diff --git a/Assets/01_Scenes/WhaleAdventure_VR/Rooms/CatsRoom.unity b/Assets/01_Scenes/WhaleAdventure_VR/Rooms/CatsRoom.unity index 703e6b1e..007d4074 100644 --- a/Assets/01_Scenes/WhaleAdventure_VR/Rooms/CatsRoom.unity +++ b/Assets/01_Scenes/WhaleAdventure_VR/Rooms/CatsRoom.unity @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:81f97d177af2e06dff1e4c59125348c6dcdc9fea4f5b2f6a57d7d1c9091b7270 -size 2112412 +oid sha256:707049e0e526e4c944606d0a4de411dace6c0d7079746cfb218ecf8ab7c24132 +size 2115193 diff --git a/Assets/01_Scenes/WhaleAdventure_VR/Rooms/CatsRoom/Global Volume Profile.asset b/Assets/01_Scenes/WhaleAdventure_VR/Rooms/CatsRoom/Global Volume Profile.asset index 70eee6a8..7e08ed51 100644 --- a/Assets/01_Scenes/WhaleAdventure_VR/Rooms/CatsRoom/Global Volume Profile.asset +++ b/Assets/01_Scenes/WhaleAdventure_VR/Rooms/CatsRoom/Global Volume Profile.asset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:26e0b488fa569da49cb06fdbe41c509e8796f71b915753d5a660136198f23911 -size 1670 +oid sha256:1fe0c9f19090cb013df9d704f549e54be135b0c8803cffeda638d98433a69a6f +size 1669 diff --git a/Assets/04_Models/Characters/Fariy.meta b/Assets/04_Models/Characters/Fariy.meta new file mode 100644 index 00000000..6bb3398b --- /dev/null +++ b/Assets/04_Models/Characters/Fariy.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: af51857a4ff2fc543966503a726fdeff +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/04_Models/Characters/Fariy/Animations.meta b/Assets/04_Models/Characters/Fariy/Animations.meta new file mode 100644 index 00000000..6401dde9 --- /dev/null +++ b/Assets/04_Models/Characters/Fariy/Animations.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: da57b9fe4d668324d9b14528ebb2becd +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/04_Models/Characters/Fariy/Animations/FairyAnimController.controller b/Assets/04_Models/Characters/Fariy/Animations/FairyAnimController.controller new file mode 100644 index 00000000..42a6203e --- /dev/null +++ b/Assets/04_Models/Characters/Fariy/Animations/FairyAnimController.controller @@ -0,0 +1,72 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1107 &-3534055997575833487 +AnimatorStateMachine: + serializedVersion: 6 + m_ObjectHideFlags: 1 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: Base Layer + m_ChildStates: + - serializedVersion: 1 + m_State: {fileID: 521846643228410262} + m_Position: {x: 410, y: 70, z: 0} + m_ChildStateMachines: [] + m_AnyStateTransitions: [] + m_EntryTransitions: [] + m_StateMachineTransitions: {} + m_StateMachineBehaviours: [] + m_AnyStatePosition: {x: 50, y: 20, z: 0} + m_EntryPosition: {x: 50, y: 120, z: 0} + m_ExitPosition: {x: 770, y: 110, z: 0} + m_ParentStateMachinePosition: {x: 800, y: 20, z: 0} + m_DefaultState: {fileID: 521846643228410262} +--- !u!91 &9100000 +AnimatorController: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: FairyAnimController + serializedVersion: 5 + m_AnimatorParameters: [] + m_AnimatorLayers: + - serializedVersion: 5 + m_Name: Base Layer + m_StateMachine: {fileID: -3534055997575833487} + m_Mask: {fileID: 0} + m_Motions: [] + m_Behaviours: [] + m_BlendingMode: 0 + m_SyncedLayerIndex: -1 + m_DefaultWeight: 0 + m_IKPass: 0 + m_SyncedLayerAffectsTiming: 0 + m_Controller: {fileID: 9100000} +--- !u!1102 &521846643228410262 +AnimatorState: + serializedVersion: 6 + m_ObjectHideFlags: 1 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: Idle + m_Speed: 1 + m_CycleOffset: 0 + m_Transitions: [] + m_StateMachineBehaviours: [] + m_Position: {x: 50, y: 50, z: 0} + m_IKOnFeet: 0 + m_WriteDefaultValues: 1 + m_Mirror: 0 + m_SpeedParameterActive: 0 + m_MirrorParameterActive: 0 + m_CycleOffsetParameterActive: 0 + m_TimeParameterActive: 0 + m_Motion: {fileID: 7400000, guid: a6f209f95d90e4e43be4124b55773e8c, type: 2} + m_Tag: + m_SpeedParameter: + m_MirrorParameter: + m_CycleOffsetParameter: + m_TimeParameter: diff --git a/Assets/04_Models/Characters/Fariy/Animations/FairyAnimController.controller.meta b/Assets/04_Models/Characters/Fariy/Animations/FairyAnimController.controller.meta new file mode 100644 index 00000000..1cb01876 --- /dev/null +++ b/Assets/04_Models/Characters/Fariy/Animations/FairyAnimController.controller.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 5236f50e9ec746e4b945415ddcf99c20 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 9100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/04_Models/Characters/Fariy/Animations/FairyFly_Idle_FlapWings.anim b/Assets/04_Models/Characters/Fariy/Animations/FairyFly_Idle_FlapWings.anim new file mode 100644 index 00000000..f90b093a --- /dev/null +++ b/Assets/04_Models/Characters/Fariy/Animations/FairyFly_Idle_FlapWings.anim @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cfbf961c3a1911f4bc52ac60076f1c0d528506653f33bd86f2b1ac245a3865de +size 8568115 diff --git a/Assets/04_Models/Characters/Fariy/Animations/FairyFly_Idle_FlapWings.anim.meta b/Assets/04_Models/Characters/Fariy/Animations/FairyFly_Idle_FlapWings.anim.meta new file mode 100644 index 00000000..9e31afe6 --- /dev/null +++ b/Assets/04_Models/Characters/Fariy/Animations/FairyFly_Idle_FlapWings.anim.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: a6f209f95d90e4e43be4124b55773e8c +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 7400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/04_Models/Characters/Fariy/FBX.meta b/Assets/04_Models/Characters/Fariy/FBX.meta new file mode 100644 index 00000000..b91a9101 --- /dev/null +++ b/Assets/04_Models/Characters/Fariy/FBX.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 3a264d424820bc24792b5f3c4c5c0d6c +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/04_Models/Characters/Fariy/FBX/Alistia.fbx b/Assets/04_Models/Characters/Fariy/FBX/Alistia.fbx new file mode 100644 index 00000000..ed4b8174 --- /dev/null +++ b/Assets/04_Models/Characters/Fariy/FBX/Alistia.fbx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f1a3be64bb9fd8bd4a50535155dbd8efe7f02f8484923fcdcf14242fbc198a36 +size 4448668 diff --git a/Assets/04_Models/Characters/Fariy/FBX/Alistia.fbx.meta b/Assets/04_Models/Characters/Fariy/FBX/Alistia.fbx.meta new file mode 100644 index 00000000..1eeda6e6 --- /dev/null +++ b/Assets/04_Models/Characters/Fariy/FBX/Alistia.fbx.meta @@ -0,0 +1,1114 @@ +fileFormatVersion: 2 +guid: c13b330bbe536e24082294714017c4c4 +ModelImporter: + serializedVersion: 19301 + internalIDToNameTable: [] + externalObjects: + - first: + type: UnityEngine:Material + assembly: UnityEngine.CoreModule + name: Alistia_Body + second: {fileID: 2100000, guid: c8b11ad3fb679554b8fe6a090fb2df31, type: 2} + - first: + type: UnityEngine:Material + assembly: UnityEngine.CoreModule + name: Alistia_Cloth + second: {fileID: 2100000, guid: bcbfd5c6863e38343b245e267d25bc9a, type: 2} + - first: + type: UnityEngine:Material + assembly: UnityEngine.CoreModule + name: Alistia_Cloth_2 + second: {fileID: 2100000, guid: e53efbb67fe6728448f434995daddef8, type: 2} + - first: + type: UnityEngine:Material + assembly: UnityEngine.CoreModule + name: Alistia_Cloth_Komono + second: {fileID: 2100000, guid: 3de8853db9fb48f479399f3e4c29bd4f, type: 2} + - first: + type: UnityEngine:Material + assembly: UnityEngine.CoreModule + name: Alistia_Cloth_Komono_Lace + second: {fileID: 2100000, guid: 0103269314fd354438519459bcba1200, type: 2} + - first: + type: UnityEngine:Material + assembly: UnityEngine.CoreModule + name: Alistia_Cloth_Lace + second: {fileID: 2100000, guid: ec6935d242801ba45a50c57594f80846, type: 2} + - first: + type: UnityEngine:Material + assembly: UnityEngine.CoreModule + name: Alistia_Hair + second: {fileID: 2100000, guid: c605ffdaefec0d3429b476e3f534840c, type: 2} + - first: + type: UnityEngine:Material + assembly: UnityEngine.CoreModule + name: Face + second: {fileID: 2100000, guid: 5964f5c0619d80048afe0d1a2fd68036, type: 2} + - first: + type: UnityEngine:Material + assembly: UnityEngine.CoreModule + name: Face_Alpha + second: {fileID: 2100000, guid: 5434df79a062a264fa80847913923f64, type: 2} + - first: + type: UnityEngine:Material + assembly: UnityEngine.CoreModule + name: Hair + second: {fileID: 2100000, guid: 603c28e1d1dba2c41a6cb2eeba1df007, type: 2} + - first: + type: UnityEngine:Material + assembly: UnityEngine.CoreModule + name: Jewel + second: {fileID: 2100000, guid: 54d340b7837b65346af0333fa5c8f9a8, type: 2} + - first: + type: UnityEngine:Material + assembly: UnityEngine.CoreModule + name: Kohane_Body + second: {fileID: 2100000, guid: c8b11ad3fb679554b8fe6a090fb2df31, type: 2} + - first: + type: UnityEngine:Material + assembly: UnityEngine.CoreModule + name: Maid_Cloth_Komono + second: {fileID: 2100000, guid: 3de8853db9fb48f479399f3e4c29bd4f, type: 2} + - first: + type: UnityEngine:Material + assembly: UnityEngine.CoreModule + name: Maid_Cloth_Race + second: {fileID: 2100000, guid: 0103269314fd354438519459bcba1200, type: 2} + - first: + type: UnityEngine:Material + assembly: UnityEngine.CoreModule + name: Metal + second: {fileID: 2100000, guid: d65d67af019c21e4090c03f494b1958c, type: 2} + - first: + type: UnityEngine:Material + assembly: UnityEngine.CoreModule + name: Rapis_Cloth_Skirt + second: {fileID: 2100000, guid: e84afd90834c51543b69db9871a01f2d, type: 2} + - first: + type: UnityEngine:Material + assembly: UnityEngine.CoreModule + name: Stoking + second: {fileID: 2100000, guid: 1d28e362395e8f141bb82817fa4e8fe3, type: 2} + materials: + materialImportMode: 1 + materialName: 0 + materialSearch: 1 + materialLocation: 1 + animations: + legacyGenerateAnimations: 4 + bakeSimulation: 0 + resampleCurves: 1 + optimizeGameObjects: 0 + motionNodeName: + rigImportErrors: + rigImportWarnings: + animationImportErrors: + animationImportWarnings: + animationRetargetingWarnings: + animationDoRetargetingWarnings: 0 + importAnimatedCustomProperties: 0 + importConstraints: 0 + animationCompression: 3 + animationRotationError: 0.5 + animationPositionError: 0.5 + animationScaleError: 0.5 + animationWrapMode: 0 + extraExposedTransformPaths: [] + extraUserProperties: [] + clipAnimations: [] + isReadable: 1 + meshes: + lODScreenPercentages: [] + globalScale: 1 + meshCompression: 0 + addColliders: 0 + useSRGBMaterialColor: 1 + sortHierarchyByName: 1 + importVisibility: 1 + importBlendShapes: 1 + importCameras: 1 + importLights: 1 + fileIdsGeneration: 2 + swapUVChannels: 0 + generateSecondaryUV: 0 + useFileUnits: 1 + keepQuads: 0 + weldVertices: 1 + preserveHierarchy: 0 + skinWeightsMode: 0 + maxBonesPerVertex: 4 + minBoneWeight: 0.001 + meshOptimizationFlags: -1 + indexFormat: 0 + secondaryUVAngleDistortion: 8 + secondaryUVAreaDistortion: 15.000001 + secondaryUVHardAngle: 88 + secondaryUVPackMargin: 4 + useFileScale: 1 + tangentSpace: + normalSmoothAngle: 60 + normalImportMode: 0 + tangentImportMode: 3 + normalCalculationMode: 4 + legacyComputeAllNormalsFromSmoothingGroupsWhenMeshHasBlendShapes: 1 + blendShapeNormalImportMode: 1 + normalSmoothingSource: 0 + referencedClips: [] + importAnimation: 1 + humanDescription: + serializedVersion: 3 + human: + - boneName: Hips + humanName: Hips + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: UpperLeg.L + humanName: LeftUpperLeg + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: UpperLeg.R + humanName: RightUpperLeg + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: LowerLeg.L + humanName: LeftLowerLeg + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: LowerLeg.R + humanName: RightLowerLeg + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: Foot.L + humanName: LeftFoot + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: Foot.R + humanName: RightFoot + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: Spine + humanName: Spine + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: Chest + humanName: Chest + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: Neck + humanName: Neck + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: Head + humanName: Head + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: Shoulder.L + humanName: LeftShoulder + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: Shoulder.R + humanName: RightShoulder + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: UpperArm.L + humanName: LeftUpperArm + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: UpperArm.R + humanName: RightUpperArm + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: LowerArm.L + humanName: LeftLowerArm + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: LowerArm.R + humanName: RightLowerArm + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: Hand.L + humanName: LeftHand + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: Hand.R + humanName: RightHand + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: Toe.L + humanName: LeftToes + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: Toe.R + humanName: RightToes + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: LeftEye + humanName: LeftEye + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: RightEye + humanName: RightEye + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: Thumb1.L + humanName: Left Thumb Proximal + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: Thumb2.L + humanName: Left Thumb Intermediate + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: Thumb3.L + humanName: Left Thumb Distal + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: Index1.L + humanName: Left Index Proximal + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: Index2.L + humanName: Left Index Intermediate + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: Index3.L + humanName: Left Index Distal + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: Middle1.L + humanName: Left Middle Proximal + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: Middle2.L + humanName: Left Middle Intermediate + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: Middle3.L + humanName: Left Middle Distal + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: Ring1.L + humanName: Left Ring Proximal + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: Ring2.L + humanName: Left Ring Intermediate + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: Ring3.L + humanName: Left Ring Distal + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: Little1.L + humanName: Left Little Proximal + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: Little2.L + humanName: Left Little Intermediate + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: Little3.L + humanName: Left Little Distal + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: Thumb1.R + humanName: Right Thumb Proximal + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: Thumb2.R + humanName: Right Thumb Intermediate + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: Thumb3.R + humanName: Right Thumb Distal + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: Index1.R + humanName: Right Index Proximal + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: Index2.R + humanName: Right Index Intermediate + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: Index3.R + humanName: Right Index Distal + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: Middle1.R + humanName: Right Middle Proximal + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: Middle2.R + humanName: Right Middle Intermediate + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: Middle3.R + humanName: Right Middle Distal + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: Ring1.R + humanName: Right Ring Proximal + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: Ring2.R + humanName: Right Ring Intermediate + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: Ring3.R + humanName: Right Ring Distal + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: Little1.R + humanName: Right Little Proximal + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: Little2.R + humanName: Right Little Intermediate + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: Little3.R + humanName: Right Little Distal + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + skeleton: + - name: Alistia(Clone) + parentName: + position: {x: 0, y: 0, z: 0} + rotation: {x: 0, y: 0, z: 0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: Hair_Base + parentName: Alistia(Clone) + position: {x: -0, y: -0.00492125, z: 0} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: Body + parentName: Alistia(Clone) + position: {x: -0, y: -0.00492125, z: 0} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: Armature + parentName: Alistia(Clone) + position: {x: -0, y: 0, z: 0} + rotation: {x: -0.7071068, y: 0, z: -0, w: 0.7071067} + scale: {x: 1, y: 1, z: 1} + - name: Hips + parentName: Armature + position: {x: -6.1696267e-18, y: -0.012475, z: 0.753024} + rotation: {x: 0.7071068, y: 3.3087225e-24, z: -6.170892e-17, w: 0.7071067} + scale: {x: 1, y: 1, z: 1} + - name: Spine + parentName: Hips + position: {x: 3.0245975e-18, y: 0.036037683, z: -0.0000004293397} + rotation: {x: -0, y: 4.3634793e-17, z: 4.3634793e-17, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: Chest + parentName: Spine + position: {x: -0, y: 0.0681147, z: 0} + rotation: {x: -0.13042058, y: 0.0000029922032, z: 0.0000029922046, w: 0.9914588} + scale: {x: 1, y: 0.9999996, z: 0.9999996} + - name: Bust1.L + parentName: Chest + position: {x: -0.036373794, y: 0.052300382, z: 0.043459147} + rotation: {x: 0.105609804, y: 0.5449849, z: 0.77077436, w: 0.31264198} + scale: {x: 1.0000036, y: 1.0000033, z: 1.0000024} + - name: Bust2.L + parentName: Bust1.L + position: {x: -0.000000020489097, y: 0.037450638, z: 0.000000038184226} + rotation: {x: 0.0037107654, y: -0.00004570186, z: -0.006652124, w: 0.99997103} + scale: {x: 1.0000026, y: 0.99999994, z: 1.0000001} + - name: Bust1.R + parentName: Chest + position: {x: 0.036374047, y: 0.05229984, z: 0.043459497} + rotation: {x: -0.105610535, y: 0.54498696, z: 0.770776, w: -0.31263408} + scale: {x: 0.9999986, y: 0.9999991, z: 1.0000001} + - name: Bust2.R + parentName: Bust1.R + position: {x: 0.000000040978193, y: 0.03745065, z: -0.000000031664968} + rotation: {x: 0.0037109037, y: 0.00004512072, z: 0.0066522853, w: 0.99997103} + scale: {x: 1.0000046, y: 1.0000024, z: 1.0000007} + - name: Neck + parentName: Chest + position: {x: 0.00000017770147, y: 0.14812247, z: 0.00617598} + rotation: {x: 0.13042058, y: -0.0000029861471, z: -0.0000029843127, w: 0.9914588} + scale: {x: 1, y: 1.0000002, z: 1.0000002} + - name: Head + parentName: Neck + position: {x: 3.1086245e-14, y: 0.05062616, z: 7.8205137e-10} + rotation: {x: -0.00024789572, y: 0.0000000662767, z: 0.00000006627272, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: LeftEye + parentName: Head + position: {x: -0.03256895, y: 0.045570184, z: 0.031821743} + rotation: {x: 0.00024789572, y: -0.00000006363798, z: -0.00000008297502, w: 1} + scale: {x: 1, y: 0.99999994, z: 1} + - name: RightEye + parentName: Head + position: {x: 0.032570522, y: 0.045570176, z: 0.031821754} + rotation: {x: 0.00024789572, y: -0.00000006363798, z: -0.00000008297502, w: 1} + scale: {x: 1, y: 0.99999994, z: 1} + - name: Shoulder.L + parentName: Chest + position: {x: -0.044254683, y: 0.13164537, z: 0.0018712665} + rotation: {x: 0.469565, y: -0.46929485, z: -0.52889204, w: -0.5287195} + scale: {x: 1.0000012, y: 1.0000018, z: 1.0000026} + - name: UpperArm.L + parentName: Shoulder.L + position: {x: -0.0000000058653313, y: 0.03066374, z: -0.000000012219971} + rotation: {x: -0.00022864343, y: 0.07132179, z: -0.000016376378, w: -0.99745333} + scale: {x: 1.0000024, y: 1.0000027, z: 1.000001} + - name: LowerArm.L + parentName: UpperArm.L + position: {x: -0.0000000023840077, y: 0.17359607, z: -5.9620864e-10} + rotation: {x: 0.000009654234, y: -0.0000054165716, z: 0.00088465307, w: 0.9999996} + scale: {x: 1.0000001, y: 0.99999946, z: 1.0000008} + - name: Hand.L + parentName: LowerArm.L + position: {x: -0.0000000018299033, y: 0.15869713, z: 0.000000052892275} + rotation: {x: 0.019572105, y: -0.037160914, z: -0.006793405, w: 0.99909455} + scale: {x: 1.0000012, y: 1.000002, z: 1.0000024} + - name: Index1.L + parentName: Hand.L + position: {x: -0.014522348, y: 0.047296092, z: 0.0045981416} + rotation: {x: -0.019978369, y: 0.036954556, z: -0.0038930534, w: 0.99910975} + scale: {x: 1.0000025, y: 1.000001, z: 1.0000018} + - name: Index2.L + parentName: Index1.L + position: {x: -1.8769697e-10, y: 0.024015969, z: -0.0000000026099771} + rotation: {x: 0.014445683, y: -0.014164986, z: 0.009858514, w: -0.99974674} + scale: {x: 1.0000014, y: 1.0000026, z: 1.000003} + - name: Index3.L + parentName: Index2.L + position: {x: 0.0000000018626451, y: 0.014786593, z: 0.000000021027518} + rotation: {x: -0.000000012107191, y: -0.000000012107191, z: -0.00000019467548, + w: 1} + scale: {x: 1.0000013, y: 1.0000019, z: 1.0000017} + - name: Little1.L + parentName: Hand.L + position: {x: 0.021028362, y: 0.04450399, z: 0.0020691496} + rotation: {x: -0.02193701, y: 0.03713258, z: 0.005996953, w: 0.9990515} + scale: {x: 1.000001, y: 0.99999946, z: 0.99999946} + - name: Little2.L + parentName: Little1.L + position: {x: 0.000000004107335, y: 0.021644933, z: -0.000000016318651} + rotation: {x: 0.0023245423, y: 0.0000025592747, z: -0.00000082282355, w: 0.9999973} + scale: {x: 0.99999875, y: 0.99999946, z: 0.9999992} + - name: Little3.L + parentName: Little2.L + position: {x: 0.0000000048106865, y: 0.012178692, z: -0.00000001093121} + rotation: {x: -2.3283064e-10, y: -0, z: -2.3092639e-14, w: 1} + scale: {x: 0.99999875, y: 0.99999946, z: 1.0000007} + - name: Middle1.L + parentName: Hand.L + position: {x: -0.0017258427, y: 0.048072364, z: 0.0036171} + rotation: {x: -0.019614687, y: 0.037148982, z: 0.0059097754, w: 0.9990998} + scale: {x: 1.0000014, y: 1.0000001, z: 1.0000002} + - name: Middle2.L + parentName: Middle1.L + position: {x: 0.0000000013537331, y: 0.026750837, z: -0.000000002144489} + rotation: {x: 0.000000029802319, y: -0.00000002235174, z: -0.000000032363456, + w: 1} + scale: {x: 0.99999994, y: 1.0000005, z: 1.0000011} + - name: Middle3.L + parentName: Middle2.L + position: {x: -2.6077274e-10, y: 0.01650331, z: -0.0000000033507597} + rotation: {x: -0, y: -0, z: 6.6613366e-16, w: 1} + scale: {x: 0.99999887, y: 1.0000001, z: 0.9999998} + - name: Ring1.L + parentName: Hand.L + position: {x: 0.009650505, y: 0.047645066, z: 0.0027892725} + rotation: {x: -0.019614726, y: 0.037149027, z: 0.0059097037, w: 0.9990998} + scale: {x: 1.0000007, y: 0.99999994, z: 0.99999994} + - name: Ring2.L + parentName: Ring1.L + position: {x: 9.057999e-11, y: 0.024814803, z: -0.000000006199496} + rotation: {x: -0, y: -0, z: -1.7462297e-10, w: 1} + scale: {x: 1.0000014, y: 1.0000017, z: 1.0000018} + - name: Ring3.L + parentName: Ring2.L + position: {x: 0.000000002025672, y: 0.014320652, z: -0.0000000060218603} + rotation: {x: -0, y: -0, z: -0, w: 1} + scale: {x: 1.0000015, y: 1.0000013, z: 1.0000014} + - name: Thumb1.L + parentName: Hand.L + position: {x: -0.017468017, y: 0.015065361, z: -0.0066261836} + rotation: {x: -0.039141063, y: 0.08133935, z: 0.34762844, w: 0.9332772} + scale: {x: 1.0000014, y: 1.0000005, z: 1.0000005} + - name: Thumb2.L + parentName: Thumb1.L + position: {x: 0.000000007450581, y: 0.021335164, z: -7.566996e-10} + rotation: {x: 0.007667834, y: -0.010849059, z: -0.036383722, w: 0.99924964} + scale: {x: 1.0000035, y: 1.0000007, z: 1.0000017} + - name: Thumb3.L + parentName: Thumb2.L + position: {x: 0.000000007450581, y: 0.018980972, z: -0.00000001268927} + rotation: {x: -0.004107844, y: -0.00076166354, z: 0.0055113547, w: 0.99997616} + scale: {x: 1.0000035, y: 1.0000026, z: 1.0000029} + - name: Shoulder.R + parentName: Chest + position: {x: 0.04425644, y: 0.13164477, z: 0.0018717226} + rotation: {x: 0.46956572, y: 0.46929416, z: 0.5288982, w: -0.5287134} + scale: {x: 1.0000001, y: 1, z: 1.0000001} + - name: UpperArm.R + parentName: Shoulder.R + position: {x: 0.000000006031769, y: 0.030663732, z: -0.000000013584213} + rotation: {x: -0.00022903082, y: -0.07132173, z: 0.000016376374, w: -0.99745333} + scale: {x: 1, y: 1.0000013, z: 1.0000015} + - name: LowerArm.R + parentName: UpperArm.R + position: {x: 7.476624e-10, y: 0.17359607, z: 0.000000058706714} + rotation: {x: -0.000009797542, y: -0.000005535781, z: 0.000884568, w: -0.9999996} + scale: {x: 1.0000019, y: 1.0000014, z: 1.0000018} + - name: Hand.R + parentName: LowerArm.R + position: {x: -4.3655746e-11, y: 0.15869711, z: 0.00000011249634} + rotation: {x: -0.019572623, y: -0.037161004, z: -0.0067932573, w: -0.9990945} + scale: {x: 0.9999997, y: 1.0000001, z: 0.9999998} + - name: Index1.R + parentName: Hand.R + position: {x: 0.014522422, y: 0.0472945, z: 0.004598211} + rotation: {x: -0.019979157, y: -0.036954816, z: 0.0038928925, w: 0.9991096} + scale: {x: 1.0000015, y: 1.0000017, z: 1.0000008} + - name: Index2.R + parentName: Index1.R + position: {x: 4.1104897e-10, y: 0.02401601, z: 0.00000005662945} + rotation: {x: 0.014446163, y: 0.014165023, z: -0.009858646, w: -0.99974674} + scale: {x: 1.000001, y: 1, z: 1.000001} + - name: Index3.R + parentName: Index2.R + position: {x: -0.0000000055879354, y: 0.014786594, z: -0.00000002561137} + rotation: {x: 0.000000025145706, y: 0.00000006798654, z: 0.000000103405895, + w: 1} + scale: {x: 1.0000012, y: 1.0000025, z: 1.0000006} + - name: Little1.R + parentName: Hand.R + position: {x: -0.021028282, y: 0.044502433, z: 0.0020692172} + rotation: {x: -0.014526544, y: -0.03717604, z: -0.0057192114, w: 0.9991868} + scale: {x: 1.0000002, y: 1.0000015, z: 0.9999997} + - name: Little2.R + parentName: Little1.R + position: {x: -6.608616e-10, y: 0.021646503, z: -0.000000006893572} + rotation: {x: -0.0050930735, y: -0.0000026598573, z: -0.0000012849341, w: 0.99998707} + scale: {x: 1.0000019, y: 1.0000002, z: 1} + - name: Little3.R + parentName: Little2.R + position: {x: -0.0000000047143334, y: 0.012178687, z: -0.0000000104769} + rotation: {x: -0, y: -0, z: -3.819167e-14, w: 1} + scale: {x: 1.0000017, y: 1.0000012, z: 1.0000024} + - name: Middle1.R + parentName: Hand.R + position: {x: 0.001725913, y: 0.048070777, z: 0.003617167} + rotation: {x: -0.019615255, y: -0.0371491, z: -0.0059097228, w: 0.99909973} + scale: {x: 1.0000002, y: 1, z: 0.9999992} + - name: Middle2.R + parentName: Middle1.R + position: {x: -0.0000000014237784, y: 0.026750863, z: -0.0000000060028147} + rotation: {x: -0, y: -0, z: -0, w: 1} + scale: {x: 1.0000006, y: 0.9999997, z: 1.0000002} + - name: Middle3.R + parentName: Middle2.R + position: {x: -5.5291594e-10, y: 0.016503299, z: -0.0000000033507639} + rotation: {x: -0, y: -0, z: -0, w: 1} + scale: {x: 1.0000007, y: 0.9999996, z: 1.0000002} + - name: Ring1.R + parentName: Hand.R + position: {x: -0.00965043, y: 0.047643475, z: 0.0027893397} + rotation: {x: -0.019615255, y: -0.0371491, z: -0.0059097228, w: 0.99909973} + scale: {x: 1.0000002, y: 1.0000001, z: 0.9999992} + - name: Ring2.R + parentName: Ring1.R + position: {x: -0.0000000025396218, y: 0.02481485, z: -0.000000006856413} + rotation: {x: -0, y: -0, z: -0, w: 1} + scale: {x: 1.0000005, y: 0.99999994, z: 1} + - name: Ring3.R + parentName: Ring2.R + position: {x: -0.0000000029314577, y: 0.014320662, z: -0.0000000054744365} + rotation: {x: -0, y: -0, z: -0, w: 1} + scale: {x: 1.0000005, y: 0.99999946, z: 0.99999994} + - name: Thumb1.R + parentName: Hand.R + position: {x: 0.017468033, y: 0.015065379, z: -0.0066261836} + rotation: {x: 0.039138585, y: 0.081340834, z: 0.34763065, w: -0.93327636} + scale: {x: 1.0000015, y: 1.0000005, z: 0.9999998} + - name: Thumb2.R + parentName: Thumb1.R + position: {x: -0.000000013038516, y: 0.021335162, z: -0.000000043946784} + rotation: {x: 0.0076674893, y: 0.010848768, z: 0.036383204, w: 0.99924964} + scale: {x: 1.0000014, y: 0.99999887, z: 0.99999803} + - name: Thumb3.R + parentName: Thumb2.R + position: {x: -0.000000016763806, y: 0.018980978, z: -0.000000021071173} + rotation: {x: -0.0041078813, y: 0.00076163746, z: -0.005511368, w: 0.9999761} + scale: {x: 1.0000019, y: 1.0000011, z: 1.0000006} + - name: UpperLeg.L + parentName: Hips + position: {x: -0.05510006, y: -0.08030146, z: -0.011969948} + rotation: {x: 0.99994344, y: 0.000000014035436, z: 0.000000014035655, w: -0.010635735} + scale: {x: 1, y: 0.99999994, z: 1.0000001} + - name: LowerLeg.L + parentName: UpperLeg.L + position: {x: -0.000000003655421, y: 0.26264185, z: 7.981139e-10} + rotation: {x: 0.01915314, y: -0.000000013611388, z: 0.000000014447262, w: 0.99981654} + scale: {x: 1, y: 0.9999979, z: 0.9999975} + - name: Foot.L + parentName: LowerLeg.L + position: {x: 1.3537782e-14, y: 0.30144525, z: -9.313206e-10} + rotation: {x: -0.4684318, y: 0.00000024730994, z: -0.000000088532694, w: 0.8834997} + scale: {x: 1, y: 0.99999917, z: 0.99999905} + - name: Toe.L + parentName: Foot.L + position: {x: -0.0000000021820092, y: 0.0990005, z: 0.0000000011536248} + rotation: {x: -0.32203057, y: 0.00000005524476, z: -0.00000016759871, w: 0.9467293} + scale: {x: 1, y: 1.0000013, z: 1.0000006} + - name: UpperLeg.R + parentName: Hips + position: {x: 0.05510006, y: -0.08030146, z: -0.011969948} + rotation: {x: 0.99994344, y: -0.000000014035436, z: -0.000000014035655, w: -0.010635735} + scale: {x: 1, y: 0.99999994, z: 1.0000001} + - name: LowerLeg.R + parentName: UpperLeg.R + position: {x: 0.000000003655421, y: 0.26264185, z: 7.981139e-10} + rotation: {x: 0.01915314, y: 0.000000013611388, z: -0.000000014447262, w: 0.99981654} + scale: {x: 1, y: 0.9999979, z: 0.9999975} + - name: Foot.R + parentName: LowerLeg.R + position: {x: -1.3537782e-14, y: 0.30144525, z: -9.313206e-10} + rotation: {x: -0.4684318, y: -0.00000024730994, z: 0.000000088532694, w: 0.8834997} + scale: {x: 1, y: 0.99999917, z: 0.99999905} + - name: Toe.R + parentName: Foot.R + position: {x: 0.0000000021820092, y: 0.0990005, z: 0.0000000011536248} + rotation: {x: -0.32203057, y: -0.00000005524476, z: 0.00000016759871, w: 0.9467293} + scale: {x: 1, y: 1.0000013, z: 1.0000006} + - name: Butt_L + parentName: Hips + position: {x: -0.049432106, y: -0.05621457, z: -0.03961581} + rotation: {x: -0.08417424, y: -0.54739594, z: 0.8217151, w: 0.13437526} + scale: {x: 1.0000019, y: 1.0000018, z: 1.0000007} + - name: Butt_L_end + parentName: Butt_L + position: {x: 0.000000009487849, y: 0.032692622, z: -0.000000027939677} + rotation: {x: 0.82941407, y: -0.05051005, z: 0.5164937, w: -0.20677382} + scale: {x: 1.0000019, y: 1.0000004, z: 1.0000017} + - name: Butt_R + parentName: Hips + position: {x: 0.049432106, y: -0.05621457, z: -0.03961581} + rotation: {x: 0.08417424, y: -0.54739594, z: 0.8217151, w: -0.13437526} + scale: {x: 1.0000019, y: 1.0000018, z: 1.0000007} + - name: Butt_R_end + parentName: Butt_R + position: {x: -0.000000009487849, y: 0.032692622, z: -0.000000027939677} + rotation: {x: 0.82941407, y: 0.05051005, z: -0.5164937, w: -0.20677382} + scale: {x: 1.0000019, y: 1.0000004, z: 1.0000017} + - name: Skirt_Root + parentName: Hips + position: {x: 3.0847643e-19, y: 0, z: 0.003534737} + rotation: {x: -0, y: -7.4497085e-18, z: -7.449713e-18, w: 1} + scale: {x: 1, y: 0.99999994, z: 1} + - name: Skirt_Front.1 + parentName: Skirt_Root + position: {x: 0.000090820686, y: 0.043659806, z: 0.05385978} + rotation: {x: -0.0022729947, y: 0.25096434, z: 0.967991, w: -0.0022730457} + scale: {x: 1.0000007, y: 1.0000014, z: 1.0000007} + - name: Skirt_Front.2 + parentName: Skirt_Front.1 + position: {x: -6.1118044e-10, y: 0.11242955, z: -0.000000008366214} + rotation: {x: 0.008286804, y: 0.0057808724, z: 0.0034313942, w: 0.9999431} + scale: {x: 1.0000024, y: 1.0000026, z: 0.9999996} + - name: Skirt_Front.3 + parentName: Skirt_Front.2 + position: {x: -1.1641532e-10, y: 0.069933556, z: 0.000000065039785} + rotation: {x: -0.0025075343, y: -0.000021738466, z: -0.0000413167, w: 0.9999969} + scale: {x: 1.0000057, y: 1.0000054, z: 1.000001} + - name: Skirt_SideF.R.1 + parentName: Skirt_Root + position: {x: 0.06909272, y: 0.04469335, z: 0.01596947} + rotation: {x: 0.4931639, y: 0.27615485, z: 0.80647975, w: -0.17354628} + scale: {x: 1.0000007, y: 1.0000013, z: 1} + - name: Skirt_SideF.R.2 + parentName: Skirt_SideF.R.1 + position: {x: -0.0000000060535967, y: 0.1107295, z: -0.00000005401671} + rotation: {x: -0.0045289397, y: -0.0052891374, z: 0.0005489439, w: 0.9999756} + scale: {x: 1.0000012, y: 1.0000013, z: 1} + - name: Skirt_SideF.R.3 + parentName: Skirt_SideF.R.2 + position: {x: 0.0000000040745363, y: 0.07303925, z: 0.000000033527613} + rotation: {x: -0.015564112, y: -0.019994458, z: -0.0018620439, w: 0.9996772} + scale: {x: 1.0000023, y: 1.0000033, z: 1} + - name: Skirt_SideF.L.1 + parentName: Skirt_Root + position: {x: -0.06909272, y: 0.04469335, z: 0.01596947} + rotation: {x: -0.4931639, y: 0.27615485, z: 0.80647975, w: 0.17354628} + scale: {x: 1.0000007, y: 1.0000013, z: 1} + - name: Skirt_SideF.L.2 + parentName: Skirt_SideF.L.1 + position: {x: 0.0000000060535967, y: 0.1107295, z: -0.00000005401671} + rotation: {x: -0.0045289397, y: 0.0052891374, z: -0.0005489439, w: 0.9999756} + scale: {x: 1.0000012, y: 1.0000013, z: 1} + - name: Skirt_SideF.L.3 + parentName: Skirt_SideF.L.2 + position: {x: -0.0000000040745363, y: 0.07303925, z: 0.000000033527613} + rotation: {x: -0.015564112, y: 0.019994458, z: 0.0018620439, w: 0.9996772} + scale: {x: 1.0000023, y: 1.0000033, z: 1} + - name: Skirt_SideB.R.1 + parentName: Skirt_Root + position: {x: 0.06992278, y: 0.04766363, z: -0.03609936} + rotation: {x: 0.79942715, y: 0.21083584, z: 0.4823379, w: -0.2895076} + scale: {x: 1.0000005, y: 1, z: 1.0000001} + - name: Skirt_SideB.R.2 + parentName: Skirt_SideB.R.1 + position: {x: -0.000000007450581, y: 0.1065388, z: 0.00000008940697} + rotation: {x: 0.0071548377, y: 0.0048371074, z: 0.0008139909, w: 0.9999624} + scale: {x: 1, y: 1.0000017, z: 1.0000023} + - name: Skirt_SideB.R.3 + parentName: Skirt_SideB.R.2 + position: {x: 0.000000026077032, y: 0.064784944, z: -0.000000022351742} + rotation: {x: 0.003669546, y: 0.003379154, z: -0.0027890278, w: 0.99998367} + scale: {x: 1.0000008, y: 1.0000032, z: 1.0000008} + - name: Skirt_SideB.L.1 + parentName: Skirt_Root + position: {x: -0.06992278, y: 0.04766363, z: -0.03609936} + rotation: {x: 0.79942715, y: -0.21083584, z: -0.4823379, w: -0.2895076} + scale: {x: 1.0000005, y: 1, z: 1.0000001} + - name: Skirt_SideB.L.2 + parentName: Skirt_SideB.L.1 + position: {x: 0.000000007450581, y: 0.1065388, z: 0.00000008940697} + rotation: {x: 0.0071548377, y: -0.0048371074, z: -0.0008139909, w: 0.9999624} + scale: {x: 1, y: 1.0000017, z: 1.0000023} + - name: Skirt_SideB.L.3 + parentName: Skirt_SideB.L.2 + position: {x: -0.000000026077032, y: 0.064784944, z: -0.000000022351742} + rotation: {x: 0.003669546, y: -0.003379154, z: 0.0027890278, w: 0.99998367} + scale: {x: 1.0000008, y: 1.0000032, z: 1.0000008} + - name: Skirt_Back.L.1 + parentName: Skirt_Root + position: {x: -0.04380273, y: 0.048995197, z: -0.05938794} + rotation: {x: 0.89772934, y: -0.12274001, z: -0.25275782, w: -0.33930883} + scale: {x: 1, y: 1.0000015, z: 1.000002} + - name: Skirt_Back.L.2 + parentName: Skirt_Back.L.1 + position: {x: 0.0000000037252903, y: 0.09740044, z: 0.000000009313226} + rotation: {x: 0.012178749, y: -0.0054054265, z: 0.0028376952, w: 0.99990726} + scale: {x: 1, y: 1.0000017, z: 1.0000014} + - name: Skirt_Back.L.3 + parentName: Skirt_Back.L.2 + position: {x: -0.000000014901161, y: 0.062575325, z: -0.000000011175871} + rotation: {x: 0.0030677347, y: -0.00019095556, z: -0.0022174448, w: 0.9999928} + scale: {x: 1.0000008, y: 1.0000023, z: 1.0000027} + - name: Skirt_Back.R.1 + parentName: Skirt_Root + position: {x: 0.04380273, y: 0.048995197, z: -0.05938794} + rotation: {x: 0.89772934, y: 0.12274001, z: 0.25275782, w: -0.33930883} + scale: {x: 1, y: 1.0000015, z: 1.000002} + - name: Skirt_Back.R.2 + parentName: Skirt_Back.R.1 + position: {x: -0.0000000037252903, y: 0.09740044, z: 0.000000009313226} + rotation: {x: 0.012178749, y: 0.0054054265, z: -0.0028376952, w: 0.99990726} + scale: {x: 1, y: 1.0000017, z: 1.0000014} + - name: Skirt_Back.R.3 + parentName: Skirt_Back.R.2 + position: {x: 0.000000014901161, y: 0.062575325, z: -0.000000011175871} + rotation: {x: 0.0030677347, y: 0.00019095556, z: 0.0022174448, w: 0.9999928} + scale: {x: 1.0000008, y: 1.0000023, z: 1.0000027} + - name: Skirt_Back.1 + parentName: Skirt_Root + position: {x: 0.000003445553, y: 0.0477556, z: -0.066995524} + rotation: {x: 0.9465774, y: -0.000025761121, z: -0.000025761103, w: -0.3224767} + scale: {x: 1, y: 1, z: 1.0000006} + - name: Skirt_Back.2 + parentName: Skirt_Back.1 + position: {x: -0, y: 0.06473696, z: 2.5313751e-11} + rotation: {x: 0.009685993, y: -0.0001802143, z: 0.00036565022, w: 0.99995303} + scale: {x: 0.99999994, y: 1.0000044, z: 1.0000038} + - name: Skirt_Back.3 + parentName: Skirt_Back.2 + position: {x: -2.1827873e-11, y: 0.05930858, z: 0.00000010795618} + rotation: {x: -0.0023036834, y: 0.0000951104, z: -0.00019585915, w: 0.9999973} + scale: {x: 0.9999996, y: 1.0000035, z: 1.000003} + - name: Skirt_Front.L.1 + parentName: Skirt_Root + position: {x: -0.041149877, y: 0.043450058, z: 0.042650267} + rotation: {x: -0.25715423, y: 0.2572139, z: 0.923851, w: 0.11921423} + scale: {x: 1.0000015, y: 1.0000007, z: 0.9999995} + - name: Skirt_Front.L.2 + parentName: Skirt_Front.L.1 + position: {x: -0.000000011175871, y: 0.10722355, z: 0.000000022351742} + rotation: {x: 0.0033605844, y: -0.00621943, z: -0.0032254755, w: 0.99996984} + scale: {x: 1.0000035, y: 1.000003, z: 1.0000014} + - name: Skirt_Front.L.3 + parentName: Skirt_Front.L.2 + position: {x: -0.000000022351742, y: 0.072623, z: -0.000000011175871} + rotation: {x: -0.010979156, y: 0.024391025, z: 0.011415142, w: 0.99957705} + scale: {x: 1.0000046, y: 1.000004, z: 1.0000008} + - name: Skirt_Front.R.1 + parentName: Skirt_Root + position: {x: 0.041149877, y: 0.043450058, z: 0.042650267} + rotation: {x: 0.25715423, y: 0.2572139, z: 0.923851, w: -0.11921423} + scale: {x: 1.0000015, y: 1.0000007, z: 0.9999995} + - name: Skirt_Front.R.2 + parentName: Skirt_Front.R.1 + position: {x: 0.000000011175871, y: 0.10722355, z: 0.000000022351742} + rotation: {x: 0.0033605844, y: 0.00621943, z: 0.0032254755, w: 0.99996984} + scale: {x: 1.0000035, y: 1.000003, z: 1.0000014} + - name: Skirt_Front.R.3 + parentName: Skirt_Front.R.2 + position: {x: 0.000000022351742, y: 0.072623, z: -0.000000011175871} + rotation: {x: -0.010979156, y: -0.024391025, z: -0.011415142, w: 0.99957705} + scale: {x: 1.0000046, y: 1.000004, z: 1.0000008} + - name: Body_Base + parentName: Alistia(Clone) + position: {x: -0, y: 0, z: 0} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: Underwear + parentName: Alistia(Clone) + position: {x: -0, y: 0, z: 0} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: Stocking + parentName: Alistia(Clone) + position: {x: -0, y: 0, z: 0} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: Bura + parentName: Alistia(Clone) + position: {x: -0, y: 0, z: 0} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: Shoes + parentName: Alistia(Clone) + position: {x: -0, y: 0, z: 0} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + armTwist: 0.5 + foreArmTwist: 0.5 + upperLegTwist: 0.5 + legTwist: 0.5 + armStretch: 0.05 + legStretch: 0.05 + feetSpacing: 0 + globalScale: 1 + rootMotionBoneName: + hasTranslationDoF: 0 + hasExtraRoot: 1 + skeletonHasParents: 1 + lastHumanDescriptionAvatarSource: {instanceID: 0} + autoGenerateAvatarMappingIfUnspecified: 1 + animationType: 3 + humanoidOversampling: 1 + avatarSetup: 1 + additionalBone: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/04_Models/Characters/Fariy/FBX/Alistia_Hair.fbx b/Assets/04_Models/Characters/Fariy/FBX/Alistia_Hair.fbx new file mode 100644 index 00000000..7f314d39 --- /dev/null +++ b/Assets/04_Models/Characters/Fariy/FBX/Alistia_Hair.fbx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:37a5bcc3532b3ae7e48d7b2ac45e82ddc7566071e9d2f93ccd7e48f41a2cc40a +size 1149532 diff --git a/Assets/04_Models/Characters/Fariy/FBX/Alistia_Hair.fbx.meta b/Assets/04_Models/Characters/Fariy/FBX/Alistia_Hair.fbx.meta new file mode 100644 index 00000000..d9b1e52b --- /dev/null +++ b/Assets/04_Models/Characters/Fariy/FBX/Alistia_Hair.fbx.meta @@ -0,0 +1,127 @@ +fileFormatVersion: 2 +guid: a6dfbc6390c7c32439b5535d97ba9adf +ModelImporter: + serializedVersion: 19301 + internalIDToNameTable: [] + externalObjects: + - first: + type: UnityEngine:Material + assembly: UnityEngine.CoreModule + name: Alistia_Cloth + second: {fileID: 2100000, guid: bcbfd5c6863e38343b245e267d25bc9a, type: 2} + - first: + type: UnityEngine:Material + assembly: UnityEngine.CoreModule + name: Alistia_Cloth_2 + second: {fileID: 2100000, guid: ec6935d242801ba45a50c57594f80846, type: 2} + - first: + type: UnityEngine:Material + assembly: UnityEngine.CoreModule + name: Alistia_Cloth_Komono + second: {fileID: 2100000, guid: 1d28e362395e8f141bb82817fa4e8fe3, type: 2} + - first: + type: UnityEngine:Material + assembly: UnityEngine.CoreModule + name: Alistia_Hair + second: {fileID: 2100000, guid: c605ffdaefec0d3429b476e3f534840c, type: 2} + - first: + type: UnityEngine:Material + assembly: UnityEngine.CoreModule + name: Maid_Cloth_Komono + second: {fileID: 2100000, guid: 3de8853db9fb48f479399f3e4c29bd4f, type: 2} + - first: + type: UnityEngine:Material + assembly: UnityEngine.CoreModule + name: Rapis_Hair + second: {fileID: 2100000, guid: 9f0241da9e2ba3d43b0fcf5d77fdd7f2, type: 2} + materials: + materialImportMode: 1 + materialName: 0 + materialSearch: 1 + materialLocation: 1 + animations: + legacyGenerateAnimations: 4 + bakeSimulation: 0 + resampleCurves: 1 + optimizeGameObjects: 0 + motionNodeName: + rigImportErrors: + rigImportWarnings: + animationImportErrors: + animationImportWarnings: + animationRetargetingWarnings: + animationDoRetargetingWarnings: 0 + importAnimatedCustomProperties: 0 + importConstraints: 0 + animationCompression: 1 + animationRotationError: 0.5 + animationPositionError: 0.5 + animationScaleError: 0.5 + animationWrapMode: 0 + extraExposedTransformPaths: [] + extraUserProperties: [] + clipAnimations: [] + isReadable: 1 + meshes: + lODScreenPercentages: [] + globalScale: 1 + meshCompression: 0 + addColliders: 0 + useSRGBMaterialColor: 1 + sortHierarchyByName: 1 + importVisibility: 1 + importBlendShapes: 1 + importCameras: 1 + importLights: 1 + fileIdsGeneration: 2 + swapUVChannels: 0 + generateSecondaryUV: 0 + useFileUnits: 1 + keepQuads: 0 + weldVertices: 1 + preserveHierarchy: 0 + skinWeightsMode: 0 + maxBonesPerVertex: 4 + minBoneWeight: 0.001 + meshOptimizationFlags: -1 + indexFormat: 0 + secondaryUVAngleDistortion: 8 + secondaryUVAreaDistortion: 15.000001 + secondaryUVHardAngle: 88 + secondaryUVPackMargin: 4 + useFileScale: 1 + tangentSpace: + normalSmoothAngle: 60 + normalImportMode: 0 + tangentImportMode: 3 + normalCalculationMode: 4 + legacyComputeAllNormalsFromSmoothingGroupsWhenMeshHasBlendShapes: 1 + blendShapeNormalImportMode: 1 + normalSmoothingSource: 0 + referencedClips: [] + importAnimation: 1 + humanDescription: + serializedVersion: 3 + human: [] + skeleton: [] + armTwist: 0.5 + foreArmTwist: 0.5 + upperLegTwist: 0.5 + legTwist: 0.5 + armStretch: 0.05 + legStretch: 0.05 + feetSpacing: 0 + globalScale: 1 + rootMotionBoneName: + hasTranslationDoF: 0 + hasExtraRoot: 0 + skeletonHasParents: 1 + lastHumanDescriptionAvatarSource: {instanceID: 0} + autoGenerateAvatarMappingIfUnspecified: 1 + animationType: 2 + humanoidOversampling: 1 + avatarSetup: 0 + additionalBone: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/04_Models/Characters/Fariy/FBX/Fairy_wing.fbx b/Assets/04_Models/Characters/Fariy/FBX/Fairy_wing.fbx new file mode 100644 index 00000000..70af8712 --- /dev/null +++ b/Assets/04_Models/Characters/Fariy/FBX/Fairy_wing.fbx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:43612c9379f8231c067100a039b19ae6dc06ba854ff96a8a16007ce3f6ba3814 +size 1218464 diff --git a/Assets/04_Models/Characters/Fariy/FBX/Fairy_wing.fbx.meta b/Assets/04_Models/Characters/Fariy/FBX/Fairy_wing.fbx.meta new file mode 100644 index 00000000..3021c57c --- /dev/null +++ b/Assets/04_Models/Characters/Fariy/FBX/Fairy_wing.fbx.meta @@ -0,0 +1,114 @@ +fileFormatVersion: 2 +guid: 99566d3cd39f8fb49acda32c3f66513d +ModelImporter: + serializedVersion: 22200 + internalIDToNameTable: [] + externalObjects: + - first: + type: UnityEngine:Material + assembly: UnityEngine.CoreModule + name: wing_mat + second: {fileID: 2100000, guid: 6705337112664b647b77d78bb08704fb, type: 2} + materials: + materialImportMode: 2 + materialName: 0 + materialSearch: 1 + materialLocation: 0 + animations: + legacyGenerateAnimations: 4 + bakeSimulation: 0 + resampleCurves: 1 + optimizeGameObjects: 0 + removeConstantScaleCurves: 0 + motionNodeName: + rigImportErrors: + rigImportWarnings: + animationImportErrors: + animationImportWarnings: + animationRetargetingWarnings: + animationDoRetargetingWarnings: 0 + importAnimatedCustomProperties: 0 + importConstraints: 0 + animationCompression: 1 + animationRotationError: 0.5 + animationPositionError: 0.5 + animationScaleError: 0.5 + animationWrapMode: 0 + extraExposedTransformPaths: [] + extraUserProperties: [] + clipAnimations: [] + isReadable: 0 + meshes: + lODScreenPercentages: [] + globalScale: 1 + meshCompression: 0 + addColliders: 0 + useSRGBMaterialColor: 1 + sortHierarchyByName: 1 + importPhysicalCameras: 1 + importVisibility: 1 + importBlendShapes: 1 + importCameras: 1 + importLights: 1 + nodeNameCollisionStrategy: 1 + fileIdsGeneration: 2 + swapUVChannels: 0 + generateSecondaryUV: 0 + useFileUnits: 1 + keepQuads: 0 + weldVertices: 1 + bakeAxisConversion: 0 + preserveHierarchy: 0 + skinWeightsMode: 0 + maxBonesPerVertex: 4 + minBoneWeight: 0.001 + optimizeBones: 1 + meshOptimizationFlags: -1 + indexFormat: 0 + secondaryUVAngleDistortion: 8 + secondaryUVAreaDistortion: 15.000001 + secondaryUVHardAngle: 88 + secondaryUVMarginMethod: 1 + secondaryUVMinLightmapResolution: 40 + secondaryUVMinObjectScale: 1 + secondaryUVPackMargin: 4 + useFileScale: 1 + strictVertexDataChecks: 0 + tangentSpace: + normalSmoothAngle: 60 + normalImportMode: 0 + tangentImportMode: 3 + normalCalculationMode: 4 + legacyComputeAllNormalsFromSmoothingGroupsWhenMeshHasBlendShapes: 0 + blendShapeNormalImportMode: 1 + normalSmoothingSource: 0 + referencedClips: [] + importAnimation: 1 + humanDescription: + serializedVersion: 3 + human: [] + skeleton: [] + armTwist: 0.5 + foreArmTwist: 0.5 + upperLegTwist: 0.5 + legTwist: 0.5 + armStretch: 0.05 + legStretch: 0.05 + feetSpacing: 0 + globalScale: 1 + rootMotionBoneName: + hasTranslationDoF: 0 + hasExtraRoot: 0 + skeletonHasParents: 1 + lastHumanDescriptionAvatarSource: {instanceID: 0} + autoGenerateAvatarMappingIfUnspecified: 1 + animationType: 2 + humanoidOversampling: 1 + avatarSetup: 0 + addHumanoidExtraRootOnlyWhenUsingAvatar: 1 + importBlendShapeDeformPercent: 1 + remapMaterialsIfMaterialImportModeIsNone: 0 + additionalBone: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/04_Models/Characters/Fariy/Fairy.prefab b/Assets/04_Models/Characters/Fariy/Fairy.prefab new file mode 100644 index 00000000..8ffbce53 --- /dev/null +++ b/Assets/04_Models/Characters/Fariy/Fairy.prefab @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:15fe95fcce389c08a3318eaaa0fff6c236a3f292825836361bf9f710d2229b3e +size 472002 diff --git a/Assets/04_Models/Characters/Fariy/Fairy.prefab.meta b/Assets/04_Models/Characters/Fariy/Fairy.prefab.meta new file mode 100644 index 00000000..1aa3f9aa --- /dev/null +++ b/Assets/04_Models/Characters/Fariy/Fairy.prefab.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 327739e1c886bed48af9bcb80c8a617c +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/04_Models/Characters/Fariy/Materials.meta b/Assets/04_Models/Characters/Fariy/Materials.meta new file mode 100644 index 00000000..59da9320 --- /dev/null +++ b/Assets/04_Models/Characters/Fariy/Materials.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 4067b7e3770e11342bd1f9a6a629f337 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/04_Models/Characters/Fariy/Materials/Body_Hair.meta b/Assets/04_Models/Characters/Fariy/Materials/Body_Hair.meta new file mode 100644 index 00000000..21e288e1 --- /dev/null +++ b/Assets/04_Models/Characters/Fariy/Materials/Body_Hair.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 719e101d11ee0274487bef5d8c811ffb +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/04_Models/Characters/Fariy/Materials/Body_Hair/Alistia_Body.mat b/Assets/04_Models/Characters/Fariy/Materials/Body_Hair/Alistia_Body.mat new file mode 100644 index 00000000..36fe4dce --- /dev/null +++ b/Assets/04_Models/Characters/Fariy/Materials/Body_Hair/Alistia_Body.mat @@ -0,0 +1,998 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 8 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: Alistia_Body + m_Shader: {fileID: 4800000, guid: 6459b2db96a08ca41b0f9b39dc7ad59e, type: 3} + m_Parent: {fileID: 0} + m_ModifiedSerializedProperties: 0 + m_ValidKeywords: + - N_F_DDMD_ON + - N_F_EAL_ON + - N_F_LLI_ON + - N_F_O_ON + - N_F_RDC_ON + - N_F_RELGI_ON + - N_F_SS_ON + - N_F_TRANSAFFSHA_ON + - _UVSET_UV0 + m_InvalidKeywords: [] + m_LightmapFlags: 0 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: -1 + stringTagMap: + VRCFallback: Unlit + disabledShaderPasses: [] + m_LockedProperties: + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _AlphaMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _AnisotropyScaleMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _AnisotropyShiftNoiseMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _AnisotropyTangentMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _AudioLinkLocalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _AudioLinkMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BacklightColorTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BaseColorMap: + m_Texture: {fileID: 2800000, guid: 38eb494fcb7511e49a5a0dafcb8aec73, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BaseMap: + m_Texture: {fileID: 2800000, guid: 38eb494fcb7511e49a5a0dafcb8aec73, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Bump2ndMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Bump2ndScaleMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DissolveMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DissolveNoiseMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DitherTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Emission2ndBlendMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Emission2ndGradTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Emission2ndMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionBlendMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionGradTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _FReflection: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _GlitterColorTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _GlitterShapeTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _GlossTexture: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MCap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MCapMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main2ndBlendMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main2ndDissolveMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main2ndDissolveNoiseMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main2ndTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main3rdBlendMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main3rdDissolveMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main3rdDissolveNoiseMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main3rdTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainColorAdjustMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainGradationTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 2800000, guid: 38eb494fcb7511e49a5a0dafcb8aec73, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MaskGloss: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MaskReflection: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MaskSelfLit: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MaskTransparency: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MatCap2ndBlendMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MatCap2ndBumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MatCap2ndTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MatCapBlendMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MatCapBumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MatCapTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _NormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OutlineTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OutlineVectorTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OutlineWidthControl: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OutlineWidthMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _PTexture: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ReflectionColorTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ReflectionCubeTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _RimColorTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _RimShadeMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _SecondaryCutout: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Shadow2ndColorTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Shadow3rdColorTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ShadowBlurMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ShadowBorderMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ShadowColorTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ShadowColorTexture: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ShadowStrengthMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ShadowT: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _SmoothnessTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Ints: [] + m_Floats: + - _AAS: 0.0001 + - _AAStrength: 1 + - _AlpToCov: 0 + - _AlphaBaseCutout: 1 + - _AlphaBoostFA: 10 + - _AlphaMaskMode: 0 + - _AlphaMaskScale: 1 + - _AlphaMaskValue: 0 + - _AlphaToMask: 0 + - _Anisotropy2MatCap: 0 + - _Anisotropy2MatCap2nd: 0 + - _Anisotropy2Reflection: 0 + - _Anisotropy2ndBitangentWidth: 1 + - _Anisotropy2ndShift: 0 + - _Anisotropy2ndShiftNoiseScale: 0 + - _Anisotropy2ndSpecularStrength: 0 + - _Anisotropy2ndTangentWidth: 1 + - _AnisotropyBitangentWidth: 1 + - _AnisotropyScale: 1 + - _AnisotropyShift: 0 + - _AnisotropyShiftNoiseScale: 0 + - _AnisotropySpecularStrength: 1 + - _AnisotropyTangentWidth: 1 + - _ApplyReflection: 0 + - _ApplySpecular: 1 + - _ApplySpecularFA: 1 + - _AsOverlay: 0 + - _AsUnlit: 0 + - _AudioLink2Emission: 0 + - _AudioLink2Emission2nd: 0 + - _AudioLink2Emission2ndGrad: 0 + - _AudioLink2EmissionGrad: 0 + - _AudioLink2Main2nd: 0 + - _AudioLink2Main3rd: 0 + - _AudioLink2Vertex: 0 + - _AudioLinkAsLocal: 0 + - _AudioLinkMask_UVMode: 0 + - _AudioLinkUVMode: 1 + - _AudioLinkVertexUVMode: 1 + - _BackfaceForceShadow: 0 + - _BacklightBackfaceMask: 1 + - _BacklightBlur: 0.05 + - _BacklightBorder: 0.35 + - _BacklightDirectivity: 5 + - _BacklightMainStrength: 0 + - _BacklightNormalStrength: 1 + - _BacklightReceiveShadow: 1 + - _BacklightViewStrength: 1 + - _BeforeExposureLimit: 10000 + - _BitKey0: 0 + - _BitKey1: 0 + - _BitKey10: 0 + - _BitKey11: 0 + - _BitKey12: 0 + - _BitKey13: 0 + - _BitKey14: 0 + - _BitKey15: 0 + - _BitKey16: 0 + - _BitKey17: 0 + - _BitKey18: 0 + - _BitKey19: 0 + - _BitKey2: 0 + - _BitKey20: 0 + - _BitKey21: 0 + - _BitKey22: 0 + - _BitKey23: 0 + - _BitKey24: 0 + - _BitKey25: 0 + - _BitKey26: 0 + - _BitKey27: 0 + - _BitKey28: 0 + - _BitKey29: 0 + - _BitKey3: 0 + - _BitKey30: 0 + - _BitKey31: 0 + - _BitKey4: 0 + - _BitKey5: 0 + - _BitKey6: 0 + - _BitKey7: 0 + - _BitKey8: 0 + - _BitKey9: 0 + - _BleModDest: 0 + - _BleModSour: 1 + - _BlendOp: 0 + - _BlendOpAlpha: 0 + - _BlendOpAlphaFA: 4 + - _BlendOpFA: 4 + - _Bump2ndMap_UVMode: 0 + - _Bump2ndScale: 1 + - _BumpScale: 1 + - _ClipAdju: 0 + - _ColorMask: 15 + - _Compa: 4 + - _ComputeMeshIndex: 0 + - _Cull: 2 + - _Culling: 2 + - _CustomLightDirectionFollowObjectRotation: 0 + - _CustomLightDirectionIntensity: 0 + - _Cutoff: 0.5 + - _Cutout: 0.5 + - _DepthThreshold: 900 + - _DirectionalLightIntensity: 0.2 + - _DissolveNoiseStrength: 0.1 + - _DistanceFadeMode: 0 + - _DistanceFadeRimFresnelPower: 5 + - _DitherMaxValue: 255 + - _DoubleSidedOutline: 1 + - _DstBlend: 0 + - _DstBlendAlpha: 10 + - _DstBlendAlphaFA: 1 + - _DstBlendFA: 1 + - _DummyProperty: 0 + - _DynamicNoisyOutline: 0 + - _Emission2ndBlend: 1 + - _Emission2ndBlendMode: 1 + - _Emission2ndFluorescence: 0 + - _Emission2ndGradSpeed: 1 + - _Emission2ndMainStrength: 0 + - _Emission2ndMap_UVMode: 0 + - _Emission2ndParallaxDepth: 0 + - _Emission2ndUseGrad: 0 + - _EmissionBlend: 1 + - _EmissionBlendMode: 1 + - _EmissionFluorescence: 1 + - _EmissionGradSpeed: 1 + - _EmissionMainStrength: 0 + - _EmissionMap_UVMode: 0 + - _EmissionParallaxDepth: 0 + - _EmissionUseGrad: 0 + - _EnvironmentalLightingIntensity: 0.5 + - _FarDistanceMaxWidth: 10 + - _FlipNormal: 0 + - _GIFlatShade: 0 + - _GIShadeThreshold: 0 + - _GSAAStrength: 0 + - _GlitterAngleRandomize: 0 + - _GlitterApplyShape: 0 + - _GlitterApplyTransparency: 1 + - _GlitterBackfaceMask: 0 + - _GlitterColorTex_UVMode: 0 + - _GlitterEnableLighting: 1 + - _GlitterMainStrength: 0 + - _GlitterNormalStrength: 1 + - _GlitterPostContrast: 1 + - _GlitterScaleRandomize: 0 + - _GlitterSensitivity: 0.25 + - _GlitterShadowMask: 0 + - _GlitterUVMode: 0 + - _GlitterVRParallaxStrength: 1 + - _GlossColorPower: 10 + - _GlossIntensity: 1 + - _GlossSoftness: 0 + - _GlossTextureFollowLight: 0 + - _GlossTextureFollowObjectRotation: 0 + - _GlossTextureRotate: 0 + - _GlossTextureSoftness: 0 + - _Glossiness: 0.6 + - _Glow_Edge_Width: 1 + - _HighlightColorPower: 1 + - _IDMask1: 0 + - _IDMask2: 0 + - _IDMask3: 0 + - _IDMask4: 0 + - _IDMask5: 0 + - _IDMask6: 0 + - _IDMask7: 0 + - _IDMask8: 0 + - _IDMaskCompile: 0 + - _IDMaskControlsDissolve: 0 + - _IDMaskFrom: 8 + - _IDMaskIndex1: 0 + - _IDMaskIndex2: 0 + - _IDMaskIndex3: 0 + - _IDMaskIndex4: 0 + - _IDMaskIndex5: 0 + - _IDMaskIndex6: 0 + - _IDMaskIndex7: 0 + - _IDMaskIndex8: 0 + - _IDMaskIsBitmap: 0 + - _IDMaskPrior1: 0 + - _IDMaskPrior2: 0 + - _IDMaskPrior3: 0 + - _IDMaskPrior4: 0 + - _IDMaskPrior5: 0 + - _IDMaskPrior6: 0 + - _IDMaskPrior7: 0 + - _IDMaskPrior8: 0 + - _IgnoreEncryption: 0 + - _Invisible: 0 + - _LLI_Max: 2 + - _LLI_Min: 1 + - _LigIgnoYNorDir: 0 + - _LightAffectOutlineColor: 0 + - _LightAffectRimLightColor: 0 + - _LightAffectShadow: 0 + - _LightFalloffAffectShadowT: 0 + - _LightFalloffSoftness: 1 + - _LightIntensity: 1 + - _LightMaxLimit: 1 + - _LightMinLimit: 0.05 + - _MCIALO: 0 + - _MCapIntensity: 1 + - _MVCOL: 0 + - _MaiColPo: 0.9 + - _Main2ndDissolveNoiseStrength: 0.1 + - _Main2ndEnableLighting: 1 + - _Main2ndTexAlphaMode: 0 + - _Main2ndTexAngle: 0 + - _Main2ndTexBlendMode: 1 + - _Main2ndTexIsDecal: 0 + - _Main2ndTexIsLeftOnly: 0 + - _Main2ndTexIsMSDF: 0 + - _Main2ndTexIsRightOnly: 0 + - _Main2ndTexShouldCopy: 0 + - _Main2ndTexShouldFlipCopy: 0 + - _Main2ndTexShouldFlipMirror: 0 + - _Main2ndTex_Cull: 0 + - _Main2ndTex_UVMode: 0 + - _Main3rdDissolveNoiseStrength: 0.1 + - _Main3rdEnableLighting: 1 + - _Main3rdTexAlphaMode: 0 + - _Main3rdTexAngle: 0 + - _Main3rdTexBlendMode: 0 + - _Main3rdTexIsDecal: 0 + - _Main3rdTexIsLeftOnly: 0 + - _Main3rdTexIsMSDF: 0 + - _Main3rdTexIsRightOnly: 0 + - _Main3rdTexShouldCopy: 0 + - _Main3rdTexShouldFlipCopy: 0 + - _Main3rdTexShouldFlipMirror: 0 + - _Main3rdTex_Cull: 0 + - _Main3rdTex_UVMode: 0 + - _MainGradationStrength: 0 + - _MatCap2ndApplyTransparency: 1 + - _MatCap2ndBackfaceMask: 0 + - _MatCap2ndBlend: 1 + - _MatCap2ndBlendMode: 1 + - _MatCap2ndBumpScale: 1 + - _MatCap2ndCustomNormal: 0 + - _MatCap2ndEnableLighting: 1 + - _MatCap2ndLod: 0 + - _MatCap2ndMainStrength: 0 + - _MatCap2ndNormalStrength: 1 + - _MatCap2ndPerspective: 1 + - _MatCap2ndShadowMask: 0 + - _MatCap2ndVRParallaxStrength: 1 + - _MatCap2ndZRotCancel: 1 + - _MatCapApplyTransparency: 1 + - _MatCapBackfaceMask: 0 + - _MatCapBlend: 1 + - _MatCapBlendMode: 1 + - _MatCapBumpScale: 1 + - _MatCapCustomNormal: 0 + - _MatCapEnableLighting: 1 + - _MatCapLod: 0 + - _MatCapMainStrength: 0 + - _MatCapNormalStrength: 1 + - _MatCapPerspective: 1 + - _MatCapShadowMask: 0 + - _MatCapVRParallaxStrength: 1 + - _MatCapZRotCancel: 1 + - _MaxFadDistance: 2 + - _Metallic: 0 + - _MinFadDistance: 0 + - _MixMainTexToOutline: 0 + - _MonochromeLighting: 0 + - _N_F_ANIS: 0 + - _N_F_CA: 0 + - _N_F_CLD: 0 + - _N_F_CO: 0 + - _N_F_COEDGL: 0 + - _N_F_DCS: 0 + - _N_F_DDMD: 1 + - _N_F_EAL: 1 + - _N_F_ESSAO: 0 + - _N_F_FR: 0 + - _N_F_GLO: 0 + - _N_F_GLOT: 0 + - _N_F_HDLS: 0 + - _N_F_HPSS: 0 + - _N_F_LLI: 1 + - _N_F_MC: 0 + - _N_F_MSSOLTFO: 0 + - _N_F_NFD: 0 + - _N_F_NLASOBF: 0 + - _N_F_NM: 0 + - _N_F_O: 1 + - _N_F_OFLMB: 0 + - _N_F_PA: 0 + - _N_F_PT: 0 + - _N_F_R: 0 + - _N_F_RDC: 1 + - _N_F_RL: 0 + - _N_F_RLIS: 0 + - _N_F_SCO: 0 + - _N_F_SCT: 0 + - _N_F_SE: 0 + - _N_F_SL: 0 + - _N_F_SLMM: 0 + - _N_F_SON: 0 + - _N_F_SS: 1 + - _N_F_ST: 0 + - _N_F_STIAL: 0 + - _N_F_STIS: 0 + - _N_F_STSDFM: 0 + - _N_F_TP: 0 + - _NoiTexAffStraWidt: 0 + - _NoisTexInten: 1 + - _NoiseSize: 100 + - _NoisyOutlineIntensity: 0 + - _NorMapAsDis: 0 + - _NormalMapIntensity: 1 + - _ObjePosiZCS: 0 + - _OffsetFactor: 0 + - _OffsetUnits: 0 + - _Opacity: 1 + - _Oper: 0 + - _OutStenPass: 0 + - _OutZTest: 4 + - _OutZWrite: 1 + - _OutlineAlphaToMask: 0 + - _OutlineBlendOp: 0 + - _OutlineBlendOpAlpha: 0 + - _OutlineBlendOpAlphaFA: 4 + - _OutlineBlendOpFA: 4 + - _OutlineColorMask: 15 + - _OutlineCull: 1 + - _OutlineDeleteMesh: 0 + - _OutlineDisableInVR: 0 + - _OutlineDstBlend: 0 + - _OutlineDstBlendAlpha: 10 + - _OutlineDstBlendAlphaFA: 1 + - _OutlineDstBlendFA: 1 + - _OutlineEnableLighting: 1 + - _OutlineExtrudeMethod: 0 + - _OutlineFixWidth: 0 + - _OutlineLitApplyTex: 0 + - _OutlineLitOffset: -8 + - _OutlineLitScale: 10 + - _OutlineLitShadowReceive: 0 + - _OutlineOffsetFactor: 0 + - _OutlineOffsetUnits: 0 + - _OutlineSrcBlend: 1 + - _OutlineSrcBlendAlpha: 1 + - _OutlineSrcBlendAlphaFA: 0 + - _OutlineSrcBlendFA: 1 + - _OutlineStencilComp: 8 + - _OutlineStencilFail: 0 + - _OutlineStencilPass: 0 + - _OutlineStencilReadMask: 255 + - _OutlineStencilRef: 0 + - _OutlineStencilWriteMask: 255 + - _OutlineStencilZFail: 0 + - _OutlineVectorScale: 1 + - _OutlineVectorUVMode: 0 + - _OutlineVertexR2Width: 0 + - _OutlineWidth: 0.03 + - _OutlineWidthAffectedByViewDistance: 0 + - _OutlineZBias: 0 + - _OutlineZClip: 1 + - _OutlineZPostionInCamera: 0 + - _OutlineZTest: 2 + - _OutlineZWrite: 1 + - _OverallShadowColorPower: 1 + - _PADist: 0 + - _PASize: 0.5 + - _PASmooTrans: 1 + - _PSGLOTEX: 0 + - _PTexturePower: 1 + - _Parallax: 0.02 + - _ParallaxOffset: 0.5 + - _PointSpotlightIntensity: 1 + - _PresAdju: 1 + - _RELG: 1 + - _RQSO: 0 + - _ReduSha: 0.5 + - _RefMetallic: 0 + - _RefVal: 0 + - _Reflectance: 0.04 + - _ReflectionApplyTransparency: 1 + - _ReflectionBlendMode: 1 + - _ReflectionCubeEnableLighting: 1 + - _ReflectionCubeOverride: 0 + - _ReflectionIntensity: 0 + - _ReflectionNormalStrength: 1 + - _RimApplyTransparency: 1 + - _RimBackfaceMask: 0 + - _RimBlendMode: 1 + - _RimBlur: 0.1 + - _RimBorder: 0.5 + - _RimDirRange: 0 + - _RimDirStrength: 0 + - _RimEnableLighting: 1 + - _RimFresnelPower: 3 + - _RimIndirBlur: 0.1 + - _RimIndirBorder: 0.5 + - _RimIndirRange: 0 + - _RimLigInt: 1 + - _RimLightColorPower: 10 + - _RimLightInLight: 1 + - _RimLightSoftness: 1 + - _RimLightUnfill: 1.5 + - _RimMainStrength: 0 + - _RimNormalStrength: 1 + - _RimShadeBlur: 1 + - _RimShadeBorder: 0.5 + - _RimShadeFresnelPower: 1 + - _RimShadeNormalStrength: 1 + - _RimShadowMask: 0 + - _RimVRParallaxStrength: 1 + - _SPECIN: 1 + - _SPECMODE: 0 + - _STIL: 0 + - _Saturation: 1 + - _SelfLitHighContrast: 1 + - _SelfLitIntensity: 0 + - _SelfLitPower: 2 + - _SelfShadowAffectedByLightShadowStrength: 0 + - _SelfShadowHardness: 1 + - _SelfShadowRealTimeShadowColorPower: 1 + - _SelfShadowRealtimeShadowIntensity: 0 + - _SelfShadowShadowTAtViewDirection: 0 + - _SelfShadowThreshold: 0.93 + - _Shadow2ndBlur: 0.08 + - _Shadow2ndBorder: 0.2 + - _Shadow2ndNormalStrength: 1 + - _Shadow2ndReceive: 0 + - _Shadow3rdBlur: 0.1 + - _Shadow3rdBorder: 0.25 + - _Shadow3rdNormalStrength: 1 + - _Shadow3rdReceive: 0 + - _ShadowBlur: 0.17 + - _ShadowBlurMaskLOD: 0 + - _ShadowBorder: 0.1 + - _ShadowBorderMaskLOD: 0 + - _ShadowBorderRange: 0 + - _ShadowColorTexturePower: 0 + - _ShadowColorType: 0 + - _ShadowEnvStrength: 0 + - _ShadowFlatBlur: 1 + - _ShadowFlatBorder: 1 + - _ShadowHardness: 0 + - _ShadowMainStrength: 0 + - _ShadowMaskType: 0 + - _ShadowNormalStrength: 1 + - _ShadowPostAO: 0 + - _ShadowReceive: 1 + - _ShadowStrength: 0.6 + - _ShadowStrengthMaskLOD: 0 + - _ShadowTColorPower: 1 + - _ShadowTHardness: 1 + - _ShadowTIntensity: 1 + - _ShadowTLightThreshold: 50 + - _ShadowTShadowThreshold: 0 + - _ShifAnis: 0 + - _ShiftBackfaceUV: 0 + - _ShowInAmbientLightShadowIntensity: 1 + - _ShowInAmbientLightShadowThreshold: 0.4 + - _ShowNormal: 0 + - _SimTrans: 0 + - _SkinMatrixIndex: 0 + - _SmoothObjectNormal: 0 + - _Smoothness: 1 + - _SpecularBlur: 0 + - _SpecularBorder: 0.5 + - _SpecularNormalStrength: 1 + - _SpecularToon: 1 + - _SrcBlend: 1 + - _SrcBlendAlpha: 1 + - _SrcBlendAlphaFA: 0 + - _SrcBlendFA: 1 + - _StencilComp: 8 + - _StencilFail: 0 + - _StencilPass: 0 + - _StencilReadMask: 255 + - _StencilRef: 0 + - _StencilWriteMask: 255 + - _StencilZFail: 0 + - _StraWidt: 10 + - _SubpassCutoff: 0.5 + - _TEXMCOLINT: 1 + - _TRANSMODE: 0 + - _TessEdge: 10 + - _TessFactorMax: 3 + - _TessShrink: 0 + - _TessStrength: 0.5 + - _TessellationFar: 1 + - _TessellationNear: 1 + - _TessellationSmoothness: 0.5 + - _TessellationTransition: 0.8 + - _TexturePatternStyle: 0 + - _TrailSize: 1.5 + - _TransAffSha: 1 + - _TransparentMode: 0 + - _TransparentThreshold: 0 + - _TriPlaBlend: 4 + - _TriPlaTile: 1 + - _UDIMDiscardCompile: 0 + - _UDIMDiscardMode: 0 + - _UDIMDiscardRow0_0: 0 + - _UDIMDiscardRow0_1: 0 + - _UDIMDiscardRow0_2: 0 + - _UDIMDiscardRow0_3: 0 + - _UDIMDiscardRow1_0: 0 + - _UDIMDiscardRow1_1: 0 + - _UDIMDiscardRow1_2: 0 + - _UDIMDiscardRow1_3: 0 + - _UDIMDiscardRow2_0: 0 + - _UDIMDiscardRow2_1: 0 + - _UDIMDiscardRow2_2: 0 + - _UDIMDiscardRow2_3: 0 + - _UDIMDiscardRow3_0: 0 + - _UDIMDiscardRow3_1: 0 + - _UDIMDiscardRow3_2: 0 + - _UDIMDiscardRow3_3: 0 + - _UDIMDiscardUV: 0 + - _UVSet: 0 + - _UseAnisotropy: 0 + - _UseAudioLink: 0 + - _UseBacklight: 0 + - _UseBump2ndMap: 0 + - _UseBumpMap: 0 + - _UseClippingCanceller: 0 + - _UseDither: 0 + - _UseEmission: 0 + - _UseEmission2nd: 0 + - _UseGlitter: 0 + - _UseMain2ndTex: 0 + - _UseMain3rdTex: 0 + - _UseMatCap: 0 + - _UseMatCap2nd: 0 + - _UseOutline: 0 + - _UsePOM: 0 + - _UseParallax: 0 + - _UseReflection: 0 + - _UseRim: 0 + - _UseRimShade: 0 + - _UseSecondaryCutout: 0 + - _UseShadow: 1 + - _UseTLB: 0 + - _VertexColorBlueAffectOutlineWitdh: 0 + - _VertexColorGreenControlSelfShadowThreshold: 0 + - _VertexColorRedControlSmoothObjectNormal: 0 + - _VertexLightStrength: 1 + - _ZClip: 1 + - _ZTest: 4 + - _ZWrite: 1 + - _e2gai: 2 + - _e2gci: 2 + - _egai: 2 + - _egci: 2 + - _lilDirectionalLightStrength: 1 + - _lilShadowCasterBias: 0 + - _lilToonVersion: 42 + m_Colors: + - _AudioLinkDefaultValue: {r: 0, g: 0, b: 2, a: 0.75} + - _AudioLinkLocalMapParams: {r: 120, g: 1, b: 0, a: 0} + - _AudioLinkMask_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _AudioLinkStart: {r: 0, g: 0, b: 0, a: 0} + - _AudioLinkUVParams: {r: 0.25, g: 0, b: 0, a: 0.125} + - _AudioLinkVertexStart: {r: 0, g: 0, b: 0, a: 0} + - _AudioLinkVertexStrength: {r: 0, g: 0, b: 0, a: 1} + - _AudioLinkVertexUVParams: {r: 0.25, g: 0, b: 0, a: 0.125} + - _BackfaceColor: {r: 0, g: 0, b: 0, a: 0} + - _BacklightColor: {r: 0.85, g: 0.8, b: 0.7, a: 1} + - _BaseColor: {r: 1, g: 1, b: 1, a: 1} + - _Color: {r: 1, g: 1, b: 1, a: 1} + - _Color2nd: {r: 1, g: 1, b: 1, a: 1} + - _Color3rd: {r: 1, g: 1, b: 1, a: 1} + - _CustomLightDirection: {r: 0, g: 0, b: 10, a: 0} + - _DissolveColor: {r: 1, g: 1, b: 1, a: 1} + - _DissolveNoiseMask_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _DissolveParams: {r: 0, g: 0, b: 0.5, a: 0.1} + - _DissolvePos: {r: 0, g: 0, b: 0, a: 0} + - _DistanceFade: {r: 0.1, g: 0.01, b: 0, a: 0} + - _DistanceFadeColor: {r: 0, g: 0, b: 0, a: 1} + - _DistanceFadeRimColor: {r: 0, g: 0, b: 0, a: 0} + - _Emission2ndBlendMask_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _Emission2ndBlink: {r: 0, g: 0, b: 3.141593, a: 0} + - _Emission2ndColor: {r: 1, g: 1, b: 1, a: 1} + - _Emission2ndMap_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _EmissionBlendMask_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _EmissionBlink: {r: 0, g: 0, b: 3.1415932, a: 0} + - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} + - _EmissionMap_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _GlitterAtras: {r: 1, g: 1, b: 0, a: 0} + - _GlitterColor: {r: 1, g: 1, b: 1, a: 1} + - _GlitterParams1: {r: 256, g: 256, b: 0.16, a: 50} + - _GlitterParams2: {r: 0.25, g: 0, b: 0, a: 0} + - _GlossColor: {r: 1, g: 1, b: 1, a: 1} + - _Glow_Color: {r: 1, g: 1, b: 1, a: 1} + - _HighlightColor: {r: 0.71733713, g: 0.73595804, b: 0.9811321, a: 1} + - _Keys: {r: 0, g: 0, b: 0, a: 0} + - _LightDirectionOverride: {r: 0, g: 0.001, b: 0, a: 0} + - _Main2ndDissolveColor: {r: 1, g: 1, b: 1, a: 1} + - _Main2ndDissolveNoiseMask_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _Main2ndDissolveParams: {r: 0, g: 0, b: 0.5, a: 0.1} + - _Main2ndDissolvePos: {r: 0, g: 0, b: 0, a: 0} + - _Main2ndDistanceFade: {r: 0.1, g: 0.01, b: 0, a: 0} + - _Main2ndTexDecalAnimation: {r: 1, g: 1, b: 1, a: 30} + - _Main2ndTexDecalSubParam: {r: 1, g: 1, b: 0, a: 1} + - _Main2ndTex_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _Main3rdDissolveColor: {r: 1, g: 1, b: 1, a: 1} + - _Main3rdDissolveNoiseMask_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _Main3rdDissolveParams: {r: 0, g: 0, b: 0.5, a: 0.1} + - _Main3rdDissolvePos: {r: 0, g: 0, b: 0, a: 0} + - _Main3rdDistanceFade: {r: 0.1, g: 0.01, b: 0, a: 0} + - _Main3rdTexDecalAnimation: {r: 1, g: 1, b: 1, a: 30} + - _Main3rdTexDecalSubParam: {r: 1, g: 1, b: 0, a: 1} + - _Main3rdTex_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _MainColor: {r: 1, g: 0.9009434, b: 0.9009434, a: 1} + - _MainTexHSVG: {r: 0, g: 1, b: 1, a: 1} + - _MainTex_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _MatCap2ndBlendUV1: {r: 0, g: 0, b: 0, a: 0} + - _MatCap2ndColor: {r: 1, g: 1, b: 1, a: 1} + - _MatCapBlendUV1: {r: 0, g: 0, b: 0, a: 0} + - _MatCapColor: {r: 1, g: 1, b: 1, a: 1} + - _ObjPosi: {r: 0, g: 0, b: 0, a: 0} + - _ObjectForward: {r: 0, g: 0, b: 0, a: 0} + - _ObjectRight: {r: 0, g: 0, b: 0, a: 0} + - _OutResi: {r: 1, g: 1, b: 1, a: 1} + - _OutlineColor: {r: 0.8392157, g: 0.5647059, b: 0.63529414, a: 1} + - _OutlineLitColor: {r: 1, g: 0.19999996, b: 0, a: 0} + - _OutlineOffset: {r: 0, g: 0, b: 0, a: 1} + - _OutlineTexHSVG: {r: 0, g: 1, b: 1, a: 1} + - _OutlineTex_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _OverallShadowColor: {r: 0, g: 0, b: 0, a: 1} + - _PTCol: {r: 0, g: 0, b: 0, a: 1} + - _PrevPosition: {r: 0, g: 0, b: 0, a: 0} + - _ReflectionColor: {r: 1, g: 1, b: 1, a: 1} + - _ReflectionCubeColor: {r: 0, g: 0, b: 0, a: 1} + - _RimColor: {r: 1, g: 1, b: 1, a: 1} + - _RimIndirColor: {r: 1, g: 1, b: 1, a: 1} + - _RimLigPosi: {r: 1, g: 1, b: 1, a: 1} + - _RimLightColor: {r: 1, g: 1, b: 1, a: 1} + - _RimShadeColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} + - _SSAOColor: {r: 0, g: 0, b: 0, a: 0} + - _SelfLitColor: {r: 1, g: 1, b: 1, a: 1} + - _SelfShadowRealTimeShadowColor: {r: 1, g: 1, b: 1, a: 1} + - _Shadow2ndColor: {r: 1, g: 0.9156185, b: 0.8915094, a: 1} + - _Shadow3rdColor: {r: 0, g: 0, b: 0, a: 0} + - _ShadowAOShift: {r: 1, g: 0, b: 1, a: 0} + - _ShadowAOShift2: {r: 1, g: 0, b: 1, a: 0} + - _ShadowBorderColor: {r: 0, g: 0, b: 0, a: 1} + - _ShadowColor: {r: 1, g: 0.92156863, b: 0.8901961, a: 1} + - _ShadowTColor: {r: 1, g: 1, b: 1, a: 1} + - _XYZPosition: {r: 0, g: 0, b: 0, a: 0} + - _e2ga0: {r: 1, g: 0, b: 0, a: 0} + - _e2ga1: {r: 1, g: 0, b: 0, a: 1} + - _e2ga2: {r: 1, g: 0, b: 0, a: 0} + - _e2ga3: {r: 1, g: 0, b: 0, a: 0} + - _e2ga4: {r: 1, g: 0, b: 0, a: 0} + - _e2ga5: {r: 1, g: 0, b: 0, a: 0} + - _e2ga6: {r: 1, g: 0, b: 0, a: 0} + - _e2ga7: {r: 1, g: 0, b: 0, a: 0} + - _e2gc0: {r: 1, g: 1, b: 1, a: 0} + - _e2gc1: {r: 1, g: 1, b: 1, a: 1} + - _e2gc2: {r: 1, g: 1, b: 1, a: 0} + - _e2gc3: {r: 1, g: 1, b: 1, a: 0} + - _e2gc4: {r: 1, g: 1, b: 1, a: 0} + - _e2gc5: {r: 1, g: 1, b: 1, a: 0} + - _e2gc6: {r: 1, g: 1, b: 1, a: 0} + - _e2gc7: {r: 1, g: 1, b: 1, a: 0} + - _ega0: {r: 1, g: 0, b: 0, a: 0} + - _ega1: {r: 1, g: 0, b: 0, a: 1} + - _ega2: {r: 1, g: 0, b: 0, a: 0} + - _ega3: {r: 1, g: 0, b: 0, a: 0} + - _ega4: {r: 1, g: 0, b: 0, a: 0} + - _ega5: {r: 1, g: 0, b: 0, a: 0} + - _ega6: {r: 1, g: 0, b: 0, a: 0} + - _ega7: {r: 1, g: 0, b: 0, a: 0} + - _egc0: {r: 1, g: 1, b: 1, a: 0} + - _egc1: {r: 1, g: 1, b: 1, a: 1} + - _egc2: {r: 1, g: 1, b: 1, a: 0} + - _egc3: {r: 1, g: 1, b: 1, a: 0} + - _egc4: {r: 1, g: 1, b: 1, a: 0} + - _egc5: {r: 1, g: 1, b: 1, a: 0} + - _egc6: {r: 1, g: 1, b: 1, a: 0} + - _egc7: {r: 1, g: 1, b: 1, a: 0} + m_BuildTextureStacks: [] + m_AllowLocking: 1 diff --git a/Assets/04_Models/Characters/Fariy/Materials/Body_Hair/Alistia_Body.mat.meta b/Assets/04_Models/Characters/Fariy/Materials/Body_Hair/Alistia_Body.mat.meta new file mode 100644 index 00000000..434e8b91 --- /dev/null +++ b/Assets/04_Models/Characters/Fariy/Materials/Body_Hair/Alistia_Body.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: c8b11ad3fb679554b8fe6a090fb2df31 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/04_Models/Characters/Fariy/Materials/Body_Hair/Alistia_Face.mat b/Assets/04_Models/Characters/Fariy/Materials/Body_Hair/Alistia_Face.mat new file mode 100644 index 00000000..9cc1829b --- /dev/null +++ b/Assets/04_Models/Characters/Fariy/Materials/Body_Hair/Alistia_Face.mat @@ -0,0 +1,999 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 8 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: Alistia_Face + m_Shader: {fileID: 4800000, guid: 6459b2db96a08ca41b0f9b39dc7ad59e, type: 3} + m_Parent: {fileID: 0} + m_ModifiedSerializedProperties: 0 + m_ValidKeywords: + - N_F_DDMD_ON + - N_F_EAL_ON + - N_F_O_ON + - N_F_RDC_ON + - N_F_RELGI_ON + - N_F_SS_ON + - N_F_TRANSAFFSHA_ON + - N_F_TRANS_ON + - _UVSET_UV0 + m_InvalidKeywords: [] + m_LightmapFlags: 0 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: 3000 + stringTagMap: + RenderType: Transparent + VRCFallback: Unlit + disabledShaderPasses: [] + m_LockedProperties: + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _AlphaMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _AnisotropyScaleMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _AnisotropyShiftNoiseMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _AnisotropyTangentMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _AudioLinkLocalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _AudioLinkMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BacklightColorTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BaseColorMap: + m_Texture: {fileID: 2800000, guid: 59cc88e58da82534b9ef6df2b16d0789, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BaseMap: + m_Texture: {fileID: 2800000, guid: 59cc88e58da82534b9ef6df2b16d0789, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Bump2ndMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Bump2ndScaleMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DissolveMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DissolveNoiseMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DitherTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Emission2ndBlendMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Emission2ndGradTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Emission2ndMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionBlendMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionGradTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _FReflection: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _GlitterColorTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _GlitterShapeTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _GlossTexture: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MCap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MCapMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main2ndBlendMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main2ndDissolveMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main2ndDissolveNoiseMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main2ndTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main3rdBlendMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main3rdDissolveMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main3rdDissolveNoiseMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main3rdTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainColorAdjustMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainGradationTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 2800000, guid: 59cc88e58da82534b9ef6df2b16d0789, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MaskGloss: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MaskReflection: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MaskSelfLit: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MaskTransparency: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MatCap2ndBlendMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MatCap2ndBumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MatCap2ndTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MatCapBlendMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MatCapBumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MatCapTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _NormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OutlineTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OutlineVectorTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OutlineWidthControl: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OutlineWidthMask: + m_Texture: {fileID: 2800000, guid: 513f256d33e4b294cb9a238d2ae516c4, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _PTexture: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ReflectionColorTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ReflectionCubeTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _RimColorTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _RimShadeMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _SecondaryCutout: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Shadow2ndColorTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Shadow3rdColorTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ShadowBlurMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ShadowBorderMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ShadowColorTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ShadowColorTexture: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ShadowStrengthMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ShadowT: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _SmoothnessTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Ints: [] + m_Floats: + - _AAS: 0.0001 + - _AAStrength: 1 + - _AlpToCov: 0 + - _AlphaBaseCutout: 1 + - _AlphaBoostFA: 10 + - _AlphaMaskMode: 0 + - _AlphaMaskScale: 1 + - _AlphaMaskValue: 0 + - _AlphaToMask: 0 + - _Anisotropy2MatCap: 0 + - _Anisotropy2MatCap2nd: 0 + - _Anisotropy2Reflection: 0 + - _Anisotropy2ndBitangentWidth: 1 + - _Anisotropy2ndShift: 0 + - _Anisotropy2ndShiftNoiseScale: 0 + - _Anisotropy2ndSpecularStrength: 0 + - _Anisotropy2ndTangentWidth: 1 + - _AnisotropyBitangentWidth: 1 + - _AnisotropyScale: 1 + - _AnisotropyShift: 0 + - _AnisotropyShiftNoiseScale: 0 + - _AnisotropySpecularStrength: 1 + - _AnisotropyTangentWidth: 1 + - _ApplyReflection: 0 + - _ApplySpecular: 1 + - _ApplySpecularFA: 1 + - _AsOverlay: 0 + - _AsUnlit: 0 + - _AudioLink2Emission: 0 + - _AudioLink2Emission2nd: 0 + - _AudioLink2Emission2ndGrad: 0 + - _AudioLink2EmissionGrad: 0 + - _AudioLink2Main2nd: 0 + - _AudioLink2Main3rd: 0 + - _AudioLink2Vertex: 0 + - _AudioLinkAsLocal: 0 + - _AudioLinkMask_UVMode: 0 + - _AudioLinkUVMode: 1 + - _AudioLinkVertexUVMode: 1 + - _BackfaceForceShadow: 0 + - _BacklightBackfaceMask: 1 + - _BacklightBlur: 0.05 + - _BacklightBorder: 0.35 + - _BacklightDirectivity: 5 + - _BacklightMainStrength: 0 + - _BacklightNormalStrength: 1 + - _BacklightReceiveShadow: 1 + - _BacklightViewStrength: 1 + - _BeforeExposureLimit: 10000 + - _BitKey0: 0 + - _BitKey1: 0 + - _BitKey10: 0 + - _BitKey11: 0 + - _BitKey12: 0 + - _BitKey13: 0 + - _BitKey14: 0 + - _BitKey15: 0 + - _BitKey16: 0 + - _BitKey17: 0 + - _BitKey18: 0 + - _BitKey19: 0 + - _BitKey2: 0 + - _BitKey20: 0 + - _BitKey21: 0 + - _BitKey22: 0 + - _BitKey23: 0 + - _BitKey24: 0 + - _BitKey25: 0 + - _BitKey26: 0 + - _BitKey27: 0 + - _BitKey28: 0 + - _BitKey29: 0 + - _BitKey3: 0 + - _BitKey30: 0 + - _BitKey31: 0 + - _BitKey4: 0 + - _BitKey5: 0 + - _BitKey6: 0 + - _BitKey7: 0 + - _BitKey8: 0 + - _BitKey9: 0 + - _BleModDest: 10 + - _BleModSour: 5 + - _BlendOp: 0 + - _BlendOpAlpha: 0 + - _BlendOpAlphaFA: 4 + - _BlendOpFA: 4 + - _Bump2ndMap_UVMode: 0 + - _Bump2ndScale: 1 + - _BumpScale: 1 + - _ClipAdju: 0 + - _ColorMask: 15 + - _Compa: 4 + - _ComputeMeshIndex: 0 + - _Cull: 2 + - _Culling: 2 + - _CustomLightDirectionFollowObjectRotation: 0 + - _CustomLightDirectionIntensity: 0 + - _Cutoff: 0.5 + - _Cutout: 0.5 + - _DepthThreshold: 900 + - _DirectionalLightIntensity: 0.2 + - _DissolveNoiseStrength: 0.1 + - _DistanceFadeMode: 0 + - _DistanceFadeRimFresnelPower: 5 + - _DitherMaxValue: 255 + - _DoubleSidedOutline: 1 + - _DstBlend: 0 + - _DstBlendAlpha: 10 + - _DstBlendAlphaFA: 1 + - _DstBlendFA: 1 + - _DummyProperty: 0 + - _DynamicNoisyOutline: 0 + - _Emission2ndBlend: 1 + - _Emission2ndBlendMode: 1 + - _Emission2ndFluorescence: 0 + - _Emission2ndGradSpeed: 1 + - _Emission2ndMainStrength: 0 + - _Emission2ndMap_UVMode: 0 + - _Emission2ndParallaxDepth: 0 + - _Emission2ndUseGrad: 0 + - _EmissionBlend: 1 + - _EmissionBlendMode: 1 + - _EmissionFluorescence: 1 + - _EmissionGradSpeed: 1 + - _EmissionMainStrength: 0 + - _EmissionMap_UVMode: 0 + - _EmissionParallaxDepth: 0 + - _EmissionUseGrad: 0 + - _EnvironmentalLightingIntensity: 0.5 + - _FarDistanceMaxWidth: 10 + - _FlipNormal: 0 + - _GIFlatShade: 0 + - _GIShadeThreshold: 0 + - _GSAAStrength: 0 + - _GlitterAngleRandomize: 0 + - _GlitterApplyShape: 0 + - _GlitterApplyTransparency: 1 + - _GlitterBackfaceMask: 0 + - _GlitterColorTex_UVMode: 0 + - _GlitterEnableLighting: 1 + - _GlitterMainStrength: 0 + - _GlitterNormalStrength: 1 + - _GlitterPostContrast: 1 + - _GlitterScaleRandomize: 0 + - _GlitterSensitivity: 0.25 + - _GlitterShadowMask: 0 + - _GlitterUVMode: 0 + - _GlitterVRParallaxStrength: 1 + - _GlossColorPower: 10 + - _GlossIntensity: 1 + - _GlossSoftness: 0 + - _GlossTextureFollowLight: 0 + - _GlossTextureFollowObjectRotation: 0 + - _GlossTextureRotate: 0 + - _GlossTextureSoftness: 0 + - _Glossiness: 0.6 + - _Glow_Edge_Width: 1 + - _HighlightColorPower: 1 + - _IDMask1: 0 + - _IDMask2: 0 + - _IDMask3: 0 + - _IDMask4: 0 + - _IDMask5: 0 + - _IDMask6: 0 + - _IDMask7: 0 + - _IDMask8: 0 + - _IDMaskCompile: 0 + - _IDMaskControlsDissolve: 0 + - _IDMaskFrom: 8 + - _IDMaskIndex1: 0 + - _IDMaskIndex2: 0 + - _IDMaskIndex3: 0 + - _IDMaskIndex4: 0 + - _IDMaskIndex5: 0 + - _IDMaskIndex6: 0 + - _IDMaskIndex7: 0 + - _IDMaskIndex8: 0 + - _IDMaskIsBitmap: 0 + - _IDMaskPrior1: 0 + - _IDMaskPrior2: 0 + - _IDMaskPrior3: 0 + - _IDMaskPrior4: 0 + - _IDMaskPrior5: 0 + - _IDMaskPrior6: 0 + - _IDMaskPrior7: 0 + - _IDMaskPrior8: 0 + - _IgnoreEncryption: 0 + - _Invisible: 0 + - _LLI_Max: 1 + - _LLI_Min: 0 + - _LigIgnoYNorDir: 0 + - _LightAffectOutlineColor: 0 + - _LightAffectRimLightColor: 0 + - _LightAffectShadow: 0 + - _LightFalloffAffectShadowT: 0 + - _LightFalloffSoftness: 1 + - _LightIntensity: 1 + - _LightMaxLimit: 1 + - _LightMinLimit: 0.05 + - _MCIALO: 0 + - _MCapIntensity: 1 + - _MVCOL: 0 + - _MaiColPo: 0.9 + - _Main2ndDissolveNoiseStrength: 0.1 + - _Main2ndEnableLighting: 1 + - _Main2ndTexAlphaMode: 0 + - _Main2ndTexAngle: 0 + - _Main2ndTexBlendMode: 1 + - _Main2ndTexIsDecal: 0 + - _Main2ndTexIsLeftOnly: 0 + - _Main2ndTexIsMSDF: 0 + - _Main2ndTexIsRightOnly: 0 + - _Main2ndTexShouldCopy: 0 + - _Main2ndTexShouldFlipCopy: 0 + - _Main2ndTexShouldFlipMirror: 0 + - _Main2ndTex_Cull: 0 + - _Main2ndTex_UVMode: 0 + - _Main3rdDissolveNoiseStrength: 0.1 + - _Main3rdEnableLighting: 1 + - _Main3rdTexAlphaMode: 0 + - _Main3rdTexAngle: 0 + - _Main3rdTexBlendMode: 0 + - _Main3rdTexIsDecal: 0 + - _Main3rdTexIsLeftOnly: 0 + - _Main3rdTexIsMSDF: 0 + - _Main3rdTexIsRightOnly: 0 + - _Main3rdTexShouldCopy: 0 + - _Main3rdTexShouldFlipCopy: 0 + - _Main3rdTexShouldFlipMirror: 0 + - _Main3rdTex_Cull: 0 + - _Main3rdTex_UVMode: 0 + - _MainGradationStrength: 0 + - _MatCap2ndApplyTransparency: 1 + - _MatCap2ndBackfaceMask: 0 + - _MatCap2ndBlend: 1 + - _MatCap2ndBlendMode: 1 + - _MatCap2ndBumpScale: 1 + - _MatCap2ndCustomNormal: 0 + - _MatCap2ndEnableLighting: 1 + - _MatCap2ndLod: 0 + - _MatCap2ndMainStrength: 0 + - _MatCap2ndNormalStrength: 1 + - _MatCap2ndPerspective: 1 + - _MatCap2ndShadowMask: 0 + - _MatCap2ndVRParallaxStrength: 1 + - _MatCap2ndZRotCancel: 1 + - _MatCapApplyTransparency: 1 + - _MatCapBackfaceMask: 0 + - _MatCapBlend: 1 + - _MatCapBlendMode: 1 + - _MatCapBumpScale: 1 + - _MatCapCustomNormal: 0 + - _MatCapEnableLighting: 1 + - _MatCapLod: 0 + - _MatCapMainStrength: 0 + - _MatCapNormalStrength: 1 + - _MatCapPerspective: 1 + - _MatCapShadowMask: 0 + - _MatCapVRParallaxStrength: 1 + - _MatCapZRotCancel: 1 + - _MaxFadDistance: 2 + - _Metallic: 0 + - _MinFadDistance: 0 + - _MixMainTexToOutline: 0 + - _MonochromeLighting: 0 + - _N_F_ANIS: 0 + - _N_F_CA: 0 + - _N_F_CLD: 0 + - _N_F_CO: 0 + - _N_F_COEDGL: 0 + - _N_F_DCS: 0 + - _N_F_DDMD: 1 + - _N_F_EAL: 1 + - _N_F_ESSAO: 0 + - _N_F_FR: 0 + - _N_F_GLO: 0 + - _N_F_GLOT: 0 + - _N_F_HDLS: 0 + - _N_F_HPSS: 0 + - _N_F_LLI: 0 + - _N_F_MC: 0 + - _N_F_MSSOLTFO: 0 + - _N_F_NFD: 0 + - _N_F_NLASOBF: 0 + - _N_F_NM: 0 + - _N_F_O: 1 + - _N_F_OFLMB: 0 + - _N_F_PA: 0 + - _N_F_PT: 0 + - _N_F_R: 0 + - _N_F_RDC: 1 + - _N_F_RL: 0 + - _N_F_RLIS: 0 + - _N_F_SCO: 0 + - _N_F_SCT: 0 + - _N_F_SE: 0 + - _N_F_SL: 0 + - _N_F_SLMM: 0 + - _N_F_SON: 0 + - _N_F_SS: 1 + - _N_F_ST: 0 + - _N_F_STIAL: 0 + - _N_F_STIS: 0 + - _N_F_STSDFM: 0 + - _N_F_TP: 0 + - _NoiTexAffStraWidt: 0 + - _NoisTexInten: 1 + - _NoiseSize: 100 + - _NoisyOutlineIntensity: 0 + - _NorMapAsDis: 0 + - _NormalMapIntensity: 1 + - _ObjePosiZCS: 0 + - _OffsetFactor: 0 + - _OffsetUnits: 0 + - _Opacity: 1 + - _Oper: 0 + - _OutStenPass: 0 + - _OutZTest: 4 + - _OutZWrite: 1 + - _OutlineAlphaToMask: 0 + - _OutlineBlendOp: 0 + - _OutlineBlendOpAlpha: 0 + - _OutlineBlendOpAlphaFA: 4 + - _OutlineBlendOpFA: 4 + - _OutlineColorMask: 15 + - _OutlineCull: 1 + - _OutlineDeleteMesh: 0 + - _OutlineDisableInVR: 0 + - _OutlineDstBlend: 0 + - _OutlineDstBlendAlpha: 10 + - _OutlineDstBlendAlphaFA: 1 + - _OutlineDstBlendFA: 1 + - _OutlineEnableLighting: 1 + - _OutlineExtrudeMethod: 0 + - _OutlineFixWidth: 0 + - _OutlineLitApplyTex: 0 + - _OutlineLitOffset: -8 + - _OutlineLitScale: 10 + - _OutlineLitShadowReceive: 0 + - _OutlineOffsetFactor: 0 + - _OutlineOffsetUnits: 0 + - _OutlineSrcBlend: 1 + - _OutlineSrcBlendAlpha: 1 + - _OutlineSrcBlendAlphaFA: 0 + - _OutlineSrcBlendFA: 1 + - _OutlineStencilComp: 8 + - _OutlineStencilFail: 0 + - _OutlineStencilPass: 0 + - _OutlineStencilReadMask: 255 + - _OutlineStencilRef: 0 + - _OutlineStencilWriteMask: 255 + - _OutlineStencilZFail: 0 + - _OutlineVectorScale: 1 + - _OutlineVectorUVMode: 0 + - _OutlineVertexR2Width: 0 + - _OutlineWidth: 0.035 + - _OutlineWidthAffectedByViewDistance: 0 + - _OutlineZBias: 0 + - _OutlineZClip: 1 + - _OutlineZPostionInCamera: 0 + - _OutlineZTest: 2 + - _OutlineZWrite: 1 + - _OverallShadowColorPower: 1 + - _PADist: 0 + - _PASize: 0.5 + - _PASmooTrans: 1 + - _PSGLOTEX: 0 + - _PTexturePower: 1 + - _Parallax: 0.02 + - _ParallaxOffset: 0.5 + - _PointSpotlightIntensity: 1 + - _PresAdju: 1 + - _RELG: 1 + - _RQSO: 0 + - _ReduSha: 0.5 + - _RefMetallic: 0 + - _RefVal: 0 + - _Reflectance: 0.04 + - _ReflectionApplyTransparency: 1 + - _ReflectionBlendMode: 1 + - _ReflectionCubeEnableLighting: 1 + - _ReflectionCubeOverride: 0 + - _ReflectionIntensity: 0 + - _ReflectionNormalStrength: 1 + - _RimApplyTransparency: 1 + - _RimBackfaceMask: 0 + - _RimBlendMode: 1 + - _RimBlur: 0.1 + - _RimBorder: 0.5 + - _RimDirRange: 0 + - _RimDirStrength: 0 + - _RimEnableLighting: 1 + - _RimFresnelPower: 3 + - _RimIndirBlur: 0.1 + - _RimIndirBorder: 0.5 + - _RimIndirRange: 0 + - _RimLigInt: 1 + - _RimLightColorPower: 10 + - _RimLightInLight: 1 + - _RimLightSoftness: 1 + - _RimLightUnfill: 1.5 + - _RimMainStrength: 0 + - _RimNormalStrength: 1 + - _RimShadeBlur: 1 + - _RimShadeBorder: 0.5 + - _RimShadeFresnelPower: 1 + - _RimShadeNormalStrength: 1 + - _RimShadowMask: 0 + - _RimVRParallaxStrength: 1 + - _SPECIN: 1 + - _SPECMODE: 0 + - _STIL: 0 + - _Saturation: 1 + - _SelfLitHighContrast: 1 + - _SelfLitIntensity: 0 + - _SelfLitPower: 2 + - _SelfShadowAffectedByLightShadowStrength: 0 + - _SelfShadowHardness: 1 + - _SelfShadowRealTimeShadowColorPower: 1 + - _SelfShadowRealtimeShadowIntensity: 0 + - _SelfShadowShadowTAtViewDirection: 0 + - _SelfShadowThreshold: 0.93 + - _Shadow2ndBlur: 0.08 + - _Shadow2ndBorder: 0.2 + - _Shadow2ndNormalStrength: 1 + - _Shadow2ndReceive: 0 + - _Shadow3rdBlur: 0.1 + - _Shadow3rdBorder: 0.25 + - _Shadow3rdNormalStrength: 1 + - _Shadow3rdReceive: 0 + - _ShadowBlur: 0.17 + - _ShadowBlurMaskLOD: 0 + - _ShadowBorder: 0.1 + - _ShadowBorderMaskLOD: 0 + - _ShadowBorderRange: 0 + - _ShadowColorTexturePower: 0 + - _ShadowColorType: 0 + - _ShadowEnvStrength: 0 + - _ShadowFlatBlur: 1 + - _ShadowFlatBorder: 1 + - _ShadowHardness: 0 + - _ShadowMainStrength: 0 + - _ShadowMaskType: 0 + - _ShadowNormalStrength: 1 + - _ShadowPostAO: 0 + - _ShadowReceive: 1 + - _ShadowStrength: 0.6 + - _ShadowStrengthMaskLOD: 0 + - _ShadowTColorPower: 1 + - _ShadowTHardness: 1 + - _ShadowTIntensity: 1 + - _ShadowTLightThreshold: 50 + - _ShadowTShadowThreshold: 0 + - _ShifAnis: 0 + - _ShiftBackfaceUV: 0 + - _ShowInAmbientLightShadowIntensity: 1 + - _ShowInAmbientLightShadowThreshold: 0.4 + - _ShowNormal: 0 + - _SimTrans: 0 + - _SkinMatrixIndex: 0 + - _SmoothObjectNormal: 0 + - _Smoothness: 1 + - _SpecularBlur: 0 + - _SpecularBorder: 0.5 + - _SpecularNormalStrength: 1 + - _SpecularToon: 1 + - _SrcBlend: 1 + - _SrcBlendAlpha: 1 + - _SrcBlendAlphaFA: 0 + - _SrcBlendFA: 1 + - _StencilComp: 8 + - _StencilFail: 0 + - _StencilPass: 2 + - _StencilReadMask: 255 + - _StencilRef: 51 + - _StencilWriteMask: 255 + - _StencilZFail: 0 + - _StraWidt: 10 + - _SubpassCutoff: 0.5 + - _TEXMCOLINT: 1 + - _TRANSMODE: 1 + - _TessEdge: 10 + - _TessFactorMax: 3 + - _TessShrink: 0 + - _TessStrength: 0.5 + - _TessellationFar: 1 + - _TessellationNear: 1 + - _TessellationSmoothness: 0.5 + - _TessellationTransition: 0.8 + - _TexturePatternStyle: 0 + - _TrailSize: 1.5 + - _TransAffSha: 1 + - _TransparentMode: 0 + - _TransparentThreshold: 0 + - _TriPlaBlend: 4 + - _TriPlaTile: 1 + - _UDIMDiscardCompile: 0 + - _UDIMDiscardMode: 0 + - _UDIMDiscardRow0_0: 0 + - _UDIMDiscardRow0_1: 0 + - _UDIMDiscardRow0_2: 0 + - _UDIMDiscardRow0_3: 0 + - _UDIMDiscardRow1_0: 0 + - _UDIMDiscardRow1_1: 0 + - _UDIMDiscardRow1_2: 0 + - _UDIMDiscardRow1_3: 0 + - _UDIMDiscardRow2_0: 0 + - _UDIMDiscardRow2_1: 0 + - _UDIMDiscardRow2_2: 0 + - _UDIMDiscardRow2_3: 0 + - _UDIMDiscardRow3_0: 0 + - _UDIMDiscardRow3_1: 0 + - _UDIMDiscardRow3_2: 0 + - _UDIMDiscardRow3_3: 0 + - _UDIMDiscardUV: 0 + - _UVSet: 0 + - _UseAnisotropy: 0 + - _UseAudioLink: 0 + - _UseBacklight: 0 + - _UseBump2ndMap: 0 + - _UseBumpMap: 0 + - _UseClippingCanceller: 0 + - _UseDither: 0 + - _UseEmission: 0 + - _UseEmission2nd: 0 + - _UseGlitter: 0 + - _UseMain2ndTex: 0 + - _UseMain3rdTex: 0 + - _UseMatCap: 0 + - _UseMatCap2nd: 0 + - _UseOutline: 0 + - _UsePOM: 0 + - _UseParallax: 0 + - _UseReflection: 0 + - _UseRim: 0 + - _UseRimShade: 0 + - _UseSecondaryCutout: 0 + - _UseShadow: 1 + - _UseTLB: 0 + - _VertexColorBlueAffectOutlineWitdh: 0 + - _VertexColorGreenControlSelfShadowThreshold: 0 + - _VertexColorRedControlSmoothObjectNormal: 0 + - _VertexLightStrength: 1 + - _ZClip: 1 + - _ZTest: 4 + - _ZWrite: 1 + - _e2gai: 2 + - _e2gci: 2 + - _egai: 2 + - _egci: 2 + - _lilDirectionalLightStrength: 1 + - _lilShadowCasterBias: 0 + - _lilToonVersion: 42 + m_Colors: + - _AudioLinkDefaultValue: {r: 0, g: 0, b: 2, a: 0.75} + - _AudioLinkLocalMapParams: {r: 120, g: 1, b: 0, a: 0} + - _AudioLinkMask_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _AudioLinkStart: {r: 0, g: 0, b: 0, a: 0} + - _AudioLinkUVParams: {r: 0.25, g: 0, b: 0, a: 0.125} + - _AudioLinkVertexStart: {r: 0, g: 0, b: 0, a: 0} + - _AudioLinkVertexStrength: {r: 0, g: 0, b: 0, a: 1} + - _AudioLinkVertexUVParams: {r: 0.25, g: 0, b: 0, a: 0.125} + - _BackfaceColor: {r: 0, g: 0, b: 0, a: 0} + - _BacklightColor: {r: 0.85, g: 0.8, b: 0.7, a: 1} + - _BaseColor: {r: 1, g: 1, b: 1, a: 1} + - _Color: {r: 1, g: 1, b: 1, a: 1} + - _Color2nd: {r: 1, g: 1, b: 1, a: 1} + - _Color3rd: {r: 1, g: 1, b: 1, a: 1} + - _CustomLightDirection: {r: 0, g: 0, b: 10, a: 0} + - _DissolveColor: {r: 1, g: 1, b: 1, a: 1} + - _DissolveNoiseMask_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _DissolveParams: {r: 0, g: 0, b: 0.5, a: 0.1} + - _DissolvePos: {r: 0, g: 0, b: 0, a: 0} + - _DistanceFade: {r: 0.1, g: 0.01, b: 0, a: 0} + - _DistanceFadeColor: {r: 0, g: 0, b: 0, a: 1} + - _DistanceFadeRimColor: {r: 0, g: 0, b: 0, a: 0} + - _Emission2ndBlendMask_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _Emission2ndBlink: {r: 0, g: 0, b: 3.141593, a: 0} + - _Emission2ndColor: {r: 1, g: 1, b: 1, a: 1} + - _Emission2ndMap_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _EmissionBlendMask_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _EmissionBlink: {r: 0, g: 0, b: 3.1415932, a: 0} + - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} + - _EmissionMap_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _GlitterAtras: {r: 1, g: 1, b: 0, a: 0} + - _GlitterColor: {r: 1, g: 1, b: 1, a: 1} + - _GlitterParams1: {r: 256, g: 256, b: 0.16, a: 50} + - _GlitterParams2: {r: 0.25, g: 0, b: 0, a: 0} + - _GlossColor: {r: 1, g: 1, b: 1, a: 1} + - _Glow_Color: {r: 1, g: 1, b: 1, a: 1} + - _HighlightColor: {r: 0.66180134, g: 0.7226262, b: 0.9811321, a: 1} + - _Keys: {r: 0, g: 0, b: 0, a: 0} + - _LightDirectionOverride: {r: 0, g: 0.001, b: 0, a: 0} + - _Main2ndDissolveColor: {r: 1, g: 1, b: 1, a: 1} + - _Main2ndDissolveNoiseMask_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _Main2ndDissolveParams: {r: 0, g: 0, b: 0.5, a: 0.1} + - _Main2ndDissolvePos: {r: 0, g: 0, b: 0, a: 0} + - _Main2ndDistanceFade: {r: 0.1, g: 0.01, b: 0, a: 0} + - _Main2ndTexDecalAnimation: {r: 1, g: 1, b: 1, a: 30} + - _Main2ndTexDecalSubParam: {r: 1, g: 1, b: 0, a: 1} + - _Main2ndTex_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _Main3rdDissolveColor: {r: 1, g: 1, b: 1, a: 1} + - _Main3rdDissolveNoiseMask_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _Main3rdDissolveParams: {r: 0, g: 0, b: 0.5, a: 0.1} + - _Main3rdDissolvePos: {r: 0, g: 0, b: 0, a: 0} + - _Main3rdDistanceFade: {r: 0.1, g: 0.01, b: 0, a: 0} + - _Main3rdTexDecalAnimation: {r: 1, g: 1, b: 1, a: 30} + - _Main3rdTexDecalSubParam: {r: 1, g: 1, b: 0, a: 1} + - _Main3rdTex_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _MainColor: {r: 1, g: 0.9481132, b: 0.9481132, a: 1} + - _MainTexHSVG: {r: 0, g: 1, b: 1, a: 1} + - _MainTex_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _MatCap2ndBlendUV1: {r: 0, g: 0, b: 0, a: 0} + - _MatCap2ndColor: {r: 1, g: 1, b: 1, a: 1} + - _MatCapBlendUV1: {r: 0, g: 0, b: 0, a: 0} + - _MatCapColor: {r: 1, g: 1, b: 1, a: 1} + - _ObjPosi: {r: 0, g: 0, b: 0, a: 0} + - _ObjectForward: {r: 0, g: 0, b: 0, a: 0} + - _ObjectRight: {r: 0, g: 0, b: 0, a: 0} + - _OutResi: {r: 1, g: 1, b: 1, a: 1} + - _OutlineColor: {r: 0.8396226, g: 0.5505073, b: 0.6236169, a: 1} + - _OutlineLitColor: {r: 1, g: 0.19999996, b: 0, a: 0} + - _OutlineOffset: {r: 0, g: 0, b: 0, a: 1} + - _OutlineTexHSVG: {r: 0, g: 1, b: 1, a: 1} + - _OutlineTex_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _OverallShadowColor: {r: 0, g: 0, b: 0, a: 1} + - _PTCol: {r: 0, g: 0, b: 0, a: 1} + - _PrevPosition: {r: 0, g: 0, b: 0, a: 0} + - _ReflectionColor: {r: 1, g: 1, b: 1, a: 1} + - _ReflectionCubeColor: {r: 0, g: 0, b: 0, a: 1} + - _RimColor: {r: 1, g: 1, b: 1, a: 1} + - _RimIndirColor: {r: 1, g: 1, b: 1, a: 1} + - _RimLigPosi: {r: 1, g: 1, b: 1, a: 1} + - _RimLightColor: {r: 1, g: 1, b: 1, a: 1} + - _RimShadeColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} + - _SSAOColor: {r: 0, g: 0, b: 0, a: 0} + - _SelfLitColor: {r: 1, g: 1, b: 1, a: 1} + - _SelfShadowRealTimeShadowColor: {r: 1, g: 1, b: 1, a: 1} + - _Shadow2ndColor: {r: 1, g: 0.91764706, b: 0.89411765, a: 1} + - _Shadow3rdColor: {r: 0, g: 0, b: 0, a: 0} + - _ShadowAOShift: {r: 1, g: 0, b: 1, a: 0} + - _ShadowAOShift2: {r: 1, g: 0, b: 1, a: 0} + - _ShadowBorderColor: {r: 0, g: 0, b: 0, a: 1} + - _ShadowColor: {r: 1, g: 0.92250675, b: 0.8915094, a: 1} + - _ShadowTColor: {r: 1, g: 1, b: 1, a: 1} + - _XYZPosition: {r: 0, g: 0, b: 0, a: 0} + - _e2ga0: {r: 1, g: 0, b: 0, a: 0} + - _e2ga1: {r: 1, g: 0, b: 0, a: 1} + - _e2ga2: {r: 1, g: 0, b: 0, a: 0} + - _e2ga3: {r: 1, g: 0, b: 0, a: 0} + - _e2ga4: {r: 1, g: 0, b: 0, a: 0} + - _e2ga5: {r: 1, g: 0, b: 0, a: 0} + - _e2ga6: {r: 1, g: 0, b: 0, a: 0} + - _e2ga7: {r: 1, g: 0, b: 0, a: 0} + - _e2gc0: {r: 1, g: 1, b: 1, a: 0} + - _e2gc1: {r: 1, g: 1, b: 1, a: 1} + - _e2gc2: {r: 1, g: 1, b: 1, a: 0} + - _e2gc3: {r: 1, g: 1, b: 1, a: 0} + - _e2gc4: {r: 1, g: 1, b: 1, a: 0} + - _e2gc5: {r: 1, g: 1, b: 1, a: 0} + - _e2gc6: {r: 1, g: 1, b: 1, a: 0} + - _e2gc7: {r: 1, g: 1, b: 1, a: 0} + - _ega0: {r: 1, g: 0, b: 0, a: 0} + - _ega1: {r: 1, g: 0, b: 0, a: 1} + - _ega2: {r: 1, g: 0, b: 0, a: 0} + - _ega3: {r: 1, g: 0, b: 0, a: 0} + - _ega4: {r: 1, g: 0, b: 0, a: 0} + - _ega5: {r: 1, g: 0, b: 0, a: 0} + - _ega6: {r: 1, g: 0, b: 0, a: 0} + - _ega7: {r: 1, g: 0, b: 0, a: 0} + - _egc0: {r: 1, g: 1, b: 1, a: 0} + - _egc1: {r: 1, g: 1, b: 1, a: 1} + - _egc2: {r: 1, g: 1, b: 1, a: 0} + - _egc3: {r: 1, g: 1, b: 1, a: 0} + - _egc4: {r: 1, g: 1, b: 1, a: 0} + - _egc5: {r: 1, g: 1, b: 1, a: 0} + - _egc6: {r: 1, g: 1, b: 1, a: 0} + - _egc7: {r: 1, g: 1, b: 1, a: 0} + m_BuildTextureStacks: [] + m_AllowLocking: 1 diff --git a/Assets/04_Models/Characters/Fariy/Materials/Body_Hair/Alistia_Face.mat.meta b/Assets/04_Models/Characters/Fariy/Materials/Body_Hair/Alistia_Face.mat.meta new file mode 100644 index 00000000..58af4b99 --- /dev/null +++ b/Assets/04_Models/Characters/Fariy/Materials/Body_Hair/Alistia_Face.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 5964f5c0619d80048afe0d1a2fd68036 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/04_Models/Characters/Fariy/Materials/Body_Hair/Alistia_Face_Alpha.mat b/Assets/04_Models/Characters/Fariy/Materials/Body_Hair/Alistia_Face_Alpha.mat new file mode 100644 index 00000000..0ae415fb --- /dev/null +++ b/Assets/04_Models/Characters/Fariy/Materials/Body_Hair/Alistia_Face_Alpha.mat @@ -0,0 +1,1030 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 8 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: Alistia_Face_Alpha + m_Shader: {fileID: 4800000, guid: 6459b2db96a08ca41b0f9b39dc7ad59e, type: 3} + m_Parent: {fileID: 0} + m_ModifiedSerializedProperties: 0 + m_ValidKeywords: + - N_F_DDMD_ON + - N_F_EAL_ON + - N_F_O_ON + - N_F_RDC_ON + - N_F_RELGI_ON + - N_F_SIMTRANS_ON + - N_F_SS_ON + - N_F_TRANSAFFSHA_ON + - N_F_TRANS_ON + - _UVSET_UV0 + m_InvalidKeywords: [] + m_LightmapFlags: 0 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: 3000 + stringTagMap: + RenderType: Transparent + VRCFallback: Unlit + disabledShaderPasses: [] + m_LockedProperties: + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _AlphaMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _AnisotropyScaleMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _AnisotropyShiftNoiseMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _AnisotropyTangentMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _AudioLinkLocalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _AudioLinkMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BacklightColorTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BaseColorMap: + m_Texture: {fileID: 2800000, guid: e9127ca5d92e63940bdc0358062db97b, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BaseMap: + m_Texture: {fileID: 2800000, guid: e9127ca5d92e63940bdc0358062db97b, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Bump2ndMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Bump2ndScaleMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DissolveMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DissolveNoiseMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DitherTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Emission2ndBlendMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Emission2ndGradTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Emission2ndMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionBlendMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionGradTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _FReflection: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _GlitterColorTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _GlitterShapeTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _GlossTexture: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MCap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MCapMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main2ndBlendMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main2ndDissolveMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main2ndDissolveNoiseMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main2ndTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main3rdBlendMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main3rdDissolveMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main3rdDissolveNoiseMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main3rdTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainColorAdjustMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainGradationTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 2800000, guid: e9127ca5d92e63940bdc0358062db97b, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MaskGloss: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MaskReflection: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MaskSelfLit: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MaskTransparency: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MatCap2ndBlendMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MatCap2ndBumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MatCap2ndTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MatCapBlendMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MatCapBumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MatCapTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _NormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OutlineTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OutlineVectorTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OutlineWidthControl: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OutlineWidthMask: + m_Texture: {fileID: 2800000, guid: 513f256d33e4b294cb9a238d2ae516c4, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _PTexture: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ReflectionColorTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ReflectionCubeTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _RimColorTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _RimShadeMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _SecondaryCutout: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Shadow2ndColorTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Shadow3rdColorTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ShadowBlurMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ShadowBorderMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ShadowColorTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ShadowColorTexture: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ShadowStrengthMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ShadowT: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _SmoothnessTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Ints: [] + m_Floats: + - _AAS: 0.0001 + - _AAStrength: 1 + - _AlpToCov: 0 + - _AlphaBaseCutout: 1 + - _AlphaBoostFA: 10 + - _AlphaMaskMode: 0 + - _AlphaMaskScale: 1 + - _AlphaMaskValue: 0 + - _AlphaToMask: 0 + - _Anisotropy2MatCap: 0 + - _Anisotropy2MatCap2nd: 0 + - _Anisotropy2Reflection: 0 + - _Anisotropy2ndBitangentWidth: 1 + - _Anisotropy2ndShift: 0 + - _Anisotropy2ndShiftNoiseScale: 0 + - _Anisotropy2ndSpecularStrength: 0 + - _Anisotropy2ndTangentWidth: 1 + - _AnisotropyBitangentWidth: 1 + - _AnisotropyScale: 1 + - _AnisotropyShift: 0 + - _AnisotropyShiftNoiseScale: 0 + - _AnisotropySpecularStrength: 1 + - _AnisotropyTangentWidth: 1 + - _ApplyReflection: 0 + - _ApplySpecular: 1 + - _ApplySpecularFA: 1 + - _AsOverlay: 0 + - _AsUnlit: 0 + - _AudioLink2Emission: 0 + - _AudioLink2Emission2nd: 0 + - _AudioLink2Emission2ndGrad: 0 + - _AudioLink2EmissionGrad: 0 + - _AudioLink2Main2nd: 0 + - _AudioLink2Main3rd: 0 + - _AudioLink2Vertex: 0 + - _AudioLinkAsLocal: 0 + - _AudioLinkMask_UVMode: 0 + - _AudioLinkUVMode: 1 + - _AudioLinkVertexUVMode: 1 + - _BackfaceForceShadow: 0 + - _BacklightBackfaceMask: 1 + - _BacklightBlur: 0.05 + - _BacklightBorder: 0.35 + - _BacklightDirectivity: 5 + - _BacklightMainStrength: 0 + - _BacklightNormalStrength: 1 + - _BacklightReceiveShadow: 1 + - _BacklightViewStrength: 1 + - _BeforeExposureLimit: 10000 + - _BitKey0: 0 + - _BitKey1: 0 + - _BitKey10: 0 + - _BitKey11: 0 + - _BitKey12: 0 + - _BitKey13: 0 + - _BitKey14: 0 + - _BitKey15: 0 + - _BitKey16: 0 + - _BitKey17: 0 + - _BitKey18: 0 + - _BitKey19: 0 + - _BitKey2: 0 + - _BitKey20: 0 + - _BitKey21: 0 + - _BitKey22: 0 + - _BitKey23: 0 + - _BitKey24: 0 + - _BitKey25: 0 + - _BitKey26: 0 + - _BitKey27: 0 + - _BitKey28: 0 + - _BitKey29: 0 + - _BitKey3: 0 + - _BitKey30: 0 + - _BitKey31: 0 + - _BitKey4: 0 + - _BitKey5: 0 + - _BitKey6: 0 + - _BitKey7: 0 + - _BitKey8: 0 + - _BitKey9: 0 + - _BleModDest: 10 + - _BleModSour: 5 + - _BlendOp: 0 + - _BlendOpAlpha: 0 + - _BlendOpAlphaFA: 4 + - _BlendOpFA: 4 + - _Bump2ndMap_UVMode: 0 + - _Bump2ndScale: 1 + - _BumpScale: 1 + - _ClipAdju: 0 + - _ColorMask: 15 + - _Compa: 4 + - _ComputeMeshIndex: 0 + - _Cull: 2 + - _Culling: 2 + - _CustomLightDirectionFollowObjectRotation: 0 + - _CustomLightDirectionIntensity: 0 + - _Cutoff: 0.001 + - _Cutout: 0.5 + - _DepthThreshold: 900 + - _DirectionalLightIntensity: 1 + - _DissolveNoiseStrength: 0.1 + - _DistanceFadeMode: 0 + - _DistanceFadeRimFresnelPower: 5 + - _DitherMaxValue: 255 + - _DoubleSidedOutline: 1 + - _DstBlend: 10 + - _DstBlendAlpha: 10 + - _DstBlendAlphaFA: 1 + - _DstBlendFA: 1 + - _DummyProperty: 0 + - _DynamicNoisyOutline: 0 + - _Emission2ndBlend: 1 + - _Emission2ndBlendMode: 1 + - _Emission2ndFluorescence: 0 + - _Emission2ndGradSpeed: 1 + - _Emission2ndMainStrength: 0 + - _Emission2ndMap_UVMode: 0 + - _Emission2ndParallaxDepth: 0 + - _Emission2ndUseGrad: 0 + - _EmissionBlend: 1 + - _EmissionBlendMode: 1 + - _EmissionFluorescence: 1 + - _EmissionGradSpeed: 1 + - _EmissionMainStrength: 0 + - _EmissionMap_UVMode: 0 + - _EmissionParallaxDepth: 0 + - _EmissionUseGrad: 0 + - _EnvironmentalLightingIntensity: 1 + - _FarDistanceMaxWidth: 10 + - _FlipNormal: 0 + - _GIFlatShade: 0 + - _GIShadeThreshold: 0 + - _GSAAStrength: 0 + - _GlitterAngleRandomize: 0 + - _GlitterApplyShape: 0 + - _GlitterApplyTransparency: 1 + - _GlitterBackfaceMask: 0 + - _GlitterColorTex_UVMode: 0 + - _GlitterEnableLighting: 1 + - _GlitterMainStrength: 0 + - _GlitterNormalStrength: 1 + - _GlitterPostContrast: 1 + - _GlitterScaleRandomize: 0 + - _GlitterSensitivity: 0.25 + - _GlitterShadowMask: 0 + - _GlitterUVMode: 0 + - _GlitterVRParallaxStrength: 1 + - _GlossColorPower: 10 + - _GlossIntensity: 1 + - _GlossSoftness: 0 + - _GlossTextureFollowLight: 0 + - _GlossTextureFollowObjectRotation: 0 + - _GlossTextureRotate: 0 + - _GlossTextureSoftness: 0 + - _Glossiness: 0.6 + - _Glow_Edge_Width: 1 + - _HighlightColorPower: 5 + - _IDMask1: 0 + - _IDMask2: 0 + - _IDMask3: 0 + - _IDMask4: 0 + - _IDMask5: 0 + - _IDMask6: 0 + - _IDMask7: 0 + - _IDMask8: 0 + - _IDMaskCompile: 0 + - _IDMaskControlsDissolve: 0 + - _IDMaskFrom: 8 + - _IDMaskIndex1: 0 + - _IDMaskIndex2: 0 + - _IDMaskIndex3: 0 + - _IDMaskIndex4: 0 + - _IDMaskIndex5: 0 + - _IDMaskIndex6: 0 + - _IDMaskIndex7: 0 + - _IDMaskIndex8: 0 + - _IDMaskIsBitmap: 0 + - _IDMaskPrior1: 0 + - _IDMaskPrior2: 0 + - _IDMaskPrior3: 0 + - _IDMaskPrior4: 0 + - _IDMaskPrior5: 0 + - _IDMaskPrior6: 0 + - _IDMaskPrior7: 0 + - _IDMaskPrior8: 0 + - _IgnoreEncryption: 0 + - _Invisible: 0 + - _LLI_Max: 1 + - _LLI_Min: 0 + - _LigIgnoYNorDir: 0 + - _LightAffectOutlineColor: 0 + - _LightAffectRimLightColor: 0 + - _LightAffectShadow: 0 + - _LightFalloffAffectShadowT: 0 + - _LightFalloffSoftness: 1 + - _LightIntensity: 1 + - _LightMaxLimit: 1 + - _LightMinLimit: 0.05 + - _MCIALO: 0 + - _MCapIntensity: 1 + - _MVCOL: 0 + - _MaiColPo: 0.8 + - _Main2ndDissolveNoiseStrength: 0.1 + - _Main2ndEnableLighting: 1 + - _Main2ndTexAlphaMode: 0 + - _Main2ndTexAngle: 0 + - _Main2ndTexBlendMode: 1 + - _Main2ndTexIsDecal: 0 + - _Main2ndTexIsLeftOnly: 0 + - _Main2ndTexIsMSDF: 0 + - _Main2ndTexIsRightOnly: 0 + - _Main2ndTexShouldCopy: 0 + - _Main2ndTexShouldFlipCopy: 0 + - _Main2ndTexShouldFlipMirror: 0 + - _Main2ndTex_Cull: 0 + - _Main2ndTex_UVMode: 0 + - _Main3rdDissolveNoiseStrength: 0.1 + - _Main3rdEnableLighting: 1 + - _Main3rdTexAlphaMode: 0 + - _Main3rdTexAngle: 0 + - _Main3rdTexBlendMode: 0 + - _Main3rdTexIsDecal: 0 + - _Main3rdTexIsLeftOnly: 0 + - _Main3rdTexIsMSDF: 0 + - _Main3rdTexIsRightOnly: 0 + - _Main3rdTexShouldCopy: 0 + - _Main3rdTexShouldFlipCopy: 0 + - _Main3rdTexShouldFlipMirror: 0 + - _Main3rdTex_Cull: 0 + - _Main3rdTex_UVMode: 0 + - _MainGradationStrength: 0 + - _MatCap2ndApplyTransparency: 1 + - _MatCap2ndBackfaceMask: 0 + - _MatCap2ndBlend: 1 + - _MatCap2ndBlendMode: 1 + - _MatCap2ndBumpScale: 1 + - _MatCap2ndCustomNormal: 0 + - _MatCap2ndEnableLighting: 1 + - _MatCap2ndLod: 0 + - _MatCap2ndMainStrength: 0 + - _MatCap2ndNormalStrength: 1 + - _MatCap2ndPerspective: 1 + - _MatCap2ndShadowMask: 0 + - _MatCap2ndVRParallaxStrength: 1 + - _MatCap2ndZRotCancel: 1 + - _MatCapApplyTransparency: 1 + - _MatCapBackfaceMask: 0 + - _MatCapBlend: 1 + - _MatCapBlendMode: 1 + - _MatCapBumpScale: 1 + - _MatCapCustomNormal: 0 + - _MatCapEnableLighting: 1 + - _MatCapLod: 0 + - _MatCapMainStrength: 0 + - _MatCapNormalStrength: 1 + - _MatCapPerspective: 1 + - _MatCapShadowMask: 0 + - _MatCapVRParallaxStrength: 1 + - _MatCapZRotCancel: 1 + - _MaxFadDistance: 2 + - _Metallic: 0 + - _MinFadDistance: 0 + - _MixMainTexToOutline: 0 + - _MonochromeLighting: 0 + - _N_F_ANIS: 0 + - _N_F_CA: 0 + - _N_F_CLD: 0 + - _N_F_CO: 0 + - _N_F_COEDGL: 0 + - _N_F_DCS: 0 + - _N_F_DDMD: 1 + - _N_F_EAL: 1 + - _N_F_ESSAO: 0 + - _N_F_FR: 0 + - _N_F_GLO: 0 + - _N_F_GLOT: 0 + - _N_F_HDLS: 0 + - _N_F_HPSS: 0 + - _N_F_LLI: 0 + - _N_F_MC: 0 + - _N_F_MSSOLTFO: 0 + - _N_F_NFD: 0 + - _N_F_NLASOBF: 0 + - _N_F_NM: 0 + - _N_F_O: 1 + - _N_F_OFLMB: 0 + - _N_F_PA: 0 + - _N_F_PT: 0 + - _N_F_R: 0 + - _N_F_RDC: 1 + - _N_F_RL: 0 + - _N_F_RLIS: 0 + - _N_F_SCO: 0 + - _N_F_SCT: 0 + - _N_F_SE: 0 + - _N_F_SL: 0 + - _N_F_SLMM: 0 + - _N_F_SON: 0 + - _N_F_SS: 1 + - _N_F_ST: 0 + - _N_F_STIAL: 0 + - _N_F_STIS: 0 + - _N_F_STSDFM: 0 + - _N_F_TP: 0 + - _NoiTexAffStraWidt: 0 + - _NoisTexInten: 1 + - _NoiseSize: 100 + - _NoisyOutlineIntensity: 0 + - _NorMapAsDis: 0 + - _NormalMapIntensity: 1 + - _ObjePosiZCS: 0 + - _OffsetFactor: 0 + - _OffsetUnits: 0 + - _Opacity: 1 + - _Oper: 0 + - _OutStenPass: 0 + - _OutZTest: 4 + - _OutZWrite: 1 + - _OutlineAlphaToMask: 0 + - _OutlineBlendOp: 0 + - _OutlineBlendOpAlpha: 0 + - _OutlineBlendOpAlphaFA: 4 + - _OutlineBlendOpFA: 4 + - _OutlineColorMask: 15 + - _OutlineCull: 1 + - _OutlineDeleteMesh: 0 + - _OutlineDisableInVR: 0 + - _OutlineDstBlend: 10 + - _OutlineDstBlendAlpha: 10 + - _OutlineDstBlendAlphaFA: 1 + - _OutlineDstBlendFA: 1 + - _OutlineEnableLighting: 1 + - _OutlineExtrudeMethod: 0 + - _OutlineFixWidth: 0 + - _OutlineLitApplyTex: 0 + - _OutlineLitOffset: -8 + - _OutlineLitScale: 10 + - _OutlineLitShadowReceive: 0 + - _OutlineOffsetFactor: 0 + - _OutlineOffsetUnits: 0 + - _OutlineSrcBlend: 5 + - _OutlineSrcBlendAlpha: 1 + - _OutlineSrcBlendAlphaFA: 0 + - _OutlineSrcBlendFA: 1 + - _OutlineStencilComp: 8 + - _OutlineStencilFail: 0 + - _OutlineStencilPass: 0 + - _OutlineStencilReadMask: 255 + - _OutlineStencilRef: 0 + - _OutlineStencilWriteMask: 255 + - _OutlineStencilZFail: 0 + - _OutlineVectorScale: 1 + - _OutlineVectorUVMode: 0 + - _OutlineVertexR2Width: 0 + - _OutlineWidth: 0.03 + - _OutlineWidthAffectedByViewDistance: 0 + - _OutlineZBias: 0 + - _OutlineZClip: 1 + - _OutlineZPostionInCamera: 0 + - _OutlineZTest: 2 + - _OutlineZWrite: 1 + - _OverallShadowColorPower: 1 + - _PADist: 0 + - _PASize: 0.5 + - _PASmooTrans: 1 + - _PSGLOTEX: 0 + - _PTexturePower: 1 + - _Parallax: 0.02 + - _ParallaxOffset: 0.5 + - _PointSpotlightIntensity: 1 + - _PreAlphaToMask: 0 + - _PreBlendOp: 0 + - _PreBlendOpAlpha: 0 + - _PreBlendOpAlphaFA: 4 + - _PreBlendOpFA: 4 + - _PreColorMask: 15 + - _PreCull: 2 + - _PreCutoff: 0.5 + - _PreDstBlend: 10 + - _PreDstBlendAlpha: 10 + - _PreDstBlendAlphaFA: 1 + - _PreDstBlendFA: 1 + - _PreOffsetFactor: 0 + - _PreOffsetUnits: 0 + - _PreOutType: 0 + - _PreSrcBlend: 1 + - _PreSrcBlendAlpha: 1 + - _PreSrcBlendAlphaFA: 0 + - _PreSrcBlendFA: 1 + - _PreStencilComp: 8 + - _PreStencilFail: 0 + - _PreStencilPass: 0 + - _PreStencilReadMask: 255 + - _PreStencilRef: 0 + - _PreStencilWriteMask: 255 + - _PreStencilZFail: 0 + - _PreZClip: 1 + - _PreZTest: 4 + - _PreZWrite: 1 + - _PresAdju: 1 + - _RELG: 1 + - _RQSO: 0 + - _ReduSha: 0.5 + - _RefMetallic: 0 + - _RefVal: 0 + - _Reflectance: 0.04 + - _ReflectionApplyTransparency: 1 + - _ReflectionBlendMode: 1 + - _ReflectionCubeEnableLighting: 1 + - _ReflectionCubeOverride: 0 + - _ReflectionIntensity: 0 + - _ReflectionNormalStrength: 1 + - _RimApplyTransparency: 1 + - _RimBackfaceMask: 0 + - _RimBlendMode: 1 + - _RimBlur: 0.1 + - _RimBorder: 0.5 + - _RimDirRange: 0 + - _RimDirStrength: 0 + - _RimEnableLighting: 1 + - _RimFresnelPower: 3 + - _RimIndirBlur: 0.1 + - _RimIndirBorder: 0.5 + - _RimIndirRange: 0 + - _RimLigInt: 1 + - _RimLightColorPower: 10 + - _RimLightInLight: 1 + - _RimLightSoftness: 1 + - _RimLightUnfill: 1.5 + - _RimMainStrength: 0 + - _RimNormalStrength: 1 + - _RimShadeBlur: 1 + - _RimShadeBorder: 0.5 + - _RimShadeFresnelPower: 1 + - _RimShadeNormalStrength: 1 + - _RimShadowMask: 0 + - _RimVRParallaxStrength: 1 + - _SPECIN: 1 + - _SPECMODE: 0 + - _STIL: 0 + - _Saturation: 1 + - _SelfLitHighContrast: 1 + - _SelfLitIntensity: 0 + - _SelfLitPower: 2 + - _SelfShadowAffectedByLightShadowStrength: 0 + - _SelfShadowHardness: 1 + - _SelfShadowRealTimeShadowColorPower: 1 + - _SelfShadowRealtimeShadowIntensity: 0 + - _SelfShadowShadowTAtViewDirection: 0 + - _SelfShadowThreshold: 0.93 + - _Shadow2ndBlur: 0.3 + - _Shadow2ndBorder: 0.5 + - _Shadow2ndNormalStrength: 1 + - _Shadow2ndReceive: 0 + - _Shadow3rdBlur: 0.1 + - _Shadow3rdBorder: 0.25 + - _Shadow3rdNormalStrength: 1 + - _Shadow3rdReceive: 0 + - _ShadowBlur: 0.1 + - _ShadowBlurMaskLOD: 0 + - _ShadowBorder: 0.5 + - _ShadowBorderMaskLOD: 0 + - _ShadowBorderRange: 0 + - _ShadowColorTexturePower: 0 + - _ShadowColorType: 0 + - _ShadowEnvStrength: 0 + - _ShadowFlatBlur: 1 + - _ShadowFlatBorder: 1 + - _ShadowHardness: 0 + - _ShadowMainStrength: 1 + - _ShadowMaskType: 0 + - _ShadowNormalStrength: 1 + - _ShadowPostAO: 0 + - _ShadowReceive: 0 + - _ShadowStrength: 1 + - _ShadowStrengthMaskLOD: 0 + - _ShadowTColorPower: 1 + - _ShadowTHardness: 1 + - _ShadowTIntensity: 1 + - _ShadowTLightThreshold: 50 + - _ShadowTShadowThreshold: 0 + - _ShifAnis: 0 + - _ShiftBackfaceUV: 0 + - _ShowInAmbientLightShadowIntensity: 1 + - _ShowInAmbientLightShadowThreshold: 0.4 + - _ShowNormal: 0 + - _SimTrans: 1 + - _SkinMatrixIndex: 0 + - _SmoothObjectNormal: 0 + - _Smoothness: 1 + - _SpecularBlur: 0 + - _SpecularBorder: 0.5 + - _SpecularNormalStrength: 1 + - _SpecularToon: 1 + - _SrcBlend: 1 + - _SrcBlendAlpha: 1 + - _SrcBlendAlphaFA: 0 + - _SrcBlendFA: 1 + - _StencilComp: 8 + - _StencilFail: 0 + - _StencilPass: 0 + - _StencilReadMask: 255 + - _StencilRef: 0 + - _StencilWriteMask: 255 + - _StencilZFail: 0 + - _StraWidt: 10 + - _SubpassCutoff: 0.5 + - _TEXMCOLINT: 1 + - _TRANSMODE: 1 + - _TessEdge: 10 + - _TessFactorMax: 3 + - _TessShrink: 0 + - _TessStrength: 0.5 + - _TessellationFar: 1 + - _TessellationNear: 1 + - _TessellationSmoothness: 0.5 + - _TessellationTransition: 0.8 + - _TexturePatternStyle: 0 + - _TrailSize: 1.5 + - _TransAffSha: 1 + - _TransparentMode: 0 + - _TransparentThreshold: 0 + - _TriPlaBlend: 4 + - _TriPlaTile: 1 + - _UDIMDiscardCompile: 0 + - _UDIMDiscardMode: 0 + - _UDIMDiscardRow0_0: 0 + - _UDIMDiscardRow0_1: 0 + - _UDIMDiscardRow0_2: 0 + - _UDIMDiscardRow0_3: 0 + - _UDIMDiscardRow1_0: 0 + - _UDIMDiscardRow1_1: 0 + - _UDIMDiscardRow1_2: 0 + - _UDIMDiscardRow1_3: 0 + - _UDIMDiscardRow2_0: 0 + - _UDIMDiscardRow2_1: 0 + - _UDIMDiscardRow2_2: 0 + - _UDIMDiscardRow2_3: 0 + - _UDIMDiscardRow3_0: 0 + - _UDIMDiscardRow3_1: 0 + - _UDIMDiscardRow3_2: 0 + - _UDIMDiscardRow3_3: 0 + - _UDIMDiscardUV: 0 + - _UVSet: 0 + - _UseAnisotropy: 0 + - _UseAudioLink: 0 + - _UseBacklight: 0 + - _UseBump2ndMap: 0 + - _UseBumpMap: 0 + - _UseClippingCanceller: 0 + - _UseDither: 0 + - _UseEmission: 0 + - _UseEmission2nd: 0 + - _UseGlitter: 0 + - _UseMain2ndTex: 0 + - _UseMain3rdTex: 0 + - _UseMatCap: 0 + - _UseMatCap2nd: 0 + - _UseOutline: 0 + - _UsePOM: 0 + - _UseParallax: 0 + - _UseReflection: 0 + - _UseRim: 0 + - _UseRimShade: 0 + - _UseSecondaryCutout: 0 + - _UseShadow: 0 + - _UseTLB: 0 + - _VertexColorBlueAffectOutlineWitdh: 0 + - _VertexColorGreenControlSelfShadowThreshold: 0 + - _VertexColorRedControlSmoothObjectNormal: 0 + - _VertexLightStrength: 1 + - _ZClip: 1 + - _ZTest: 4 + - _ZWrite: 1 + - _e2gai: 2 + - _e2gci: 2 + - _egai: 2 + - _egci: 2 + - _lilDirectionalLightStrength: 1 + - _lilShadowCasterBias: 0 + - _lilToonVersion: 42 + m_Colors: + - _AudioLinkDefaultValue: {r: 0, g: 0, b: 2, a: 0.75} + - _AudioLinkLocalMapParams: {r: 120, g: 1, b: 0, a: 0} + - _AudioLinkMask_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _AudioLinkStart: {r: 0, g: 0, b: 0, a: 0} + - _AudioLinkUVParams: {r: 0.25, g: 0, b: 0, a: 0.125} + - _AudioLinkVertexStart: {r: 0, g: 0, b: 0, a: 0} + - _AudioLinkVertexStrength: {r: 0, g: 0, b: 0, a: 1} + - _AudioLinkVertexUVParams: {r: 0.25, g: 0, b: 0, a: 0.125} + - _BackfaceColor: {r: 0, g: 0, b: 0, a: 0} + - _BacklightColor: {r: 0.85, g: 0.8, b: 0.7, a: 1} + - _BaseColor: {r: 1, g: 1, b: 1, a: 1} + - _Color: {r: 1, g: 1, b: 1, a: 1} + - _Color2nd: {r: 1, g: 1, b: 1, a: 1} + - _Color3rd: {r: 1, g: 1, b: 1, a: 1} + - _CustomLightDirection: {r: 0, g: 0, b: 10, a: 0} + - _DissolveColor: {r: 1, g: 1, b: 1, a: 1} + - _DissolveNoiseMask_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _DissolveParams: {r: 0, g: 0, b: 0.5, a: 0.1} + - _DissolvePos: {r: 0, g: 0, b: 0, a: 0} + - _DistanceFade: {r: 0.1, g: 0.01, b: 0, a: 0} + - _DistanceFadeColor: {r: 0, g: 0, b: 0, a: 1} + - _DistanceFadeRimColor: {r: 0, g: 0, b: 0, a: 0} + - _Emission2ndBlendMask_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _Emission2ndBlink: {r: 0, g: 0, b: 3.141593, a: 0} + - _Emission2ndColor: {r: 1, g: 1, b: 1, a: 1} + - _Emission2ndMap_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _EmissionBlendMask_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _EmissionBlink: {r: 0, g: 0, b: 3.1415932, a: 0} + - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} + - _EmissionMap_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _GlitterAtras: {r: 1, g: 1, b: 0, a: 0} + - _GlitterColor: {r: 1, g: 1, b: 1, a: 1} + - _GlitterParams1: {r: 256, g: 256, b: 0.16, a: 50} + - _GlitterParams2: {r: 0.25, g: 0, b: 0, a: 0} + - _GlossColor: {r: 1, g: 1, b: 1, a: 1} + - _Glow_Color: {r: 1, g: 1, b: 1, a: 1} + - _HighlightColor: {r: 0, g: 0.013357639, b: 1, a: 1} + - _Keys: {r: 0, g: 0, b: 0, a: 0} + - _LightDirectionOverride: {r: 0, g: 0.001, b: 0, a: 0} + - _Main2ndDissolveColor: {r: 1, g: 1, b: 1, a: 1} + - _Main2ndDissolveNoiseMask_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _Main2ndDissolveParams: {r: 0, g: 0, b: 0.5, a: 0.1} + - _Main2ndDissolvePos: {r: 0, g: 0, b: 0, a: 0} + - _Main2ndDistanceFade: {r: 0.1, g: 0.01, b: 0, a: 0} + - _Main2ndTexDecalAnimation: {r: 1, g: 1, b: 1, a: 30} + - _Main2ndTexDecalSubParam: {r: 1, g: 1, b: 0, a: 1} + - _Main2ndTex_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _Main3rdDissolveColor: {r: 1, g: 1, b: 1, a: 1} + - _Main3rdDissolveNoiseMask_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _Main3rdDissolveParams: {r: 0, g: 0, b: 0.5, a: 0.1} + - _Main3rdDissolvePos: {r: 0, g: 0, b: 0, a: 0} + - _Main3rdDistanceFade: {r: 0.1, g: 0.01, b: 0, a: 0} + - _Main3rdTexDecalAnimation: {r: 1, g: 1, b: 1, a: 30} + - _Main3rdTexDecalSubParam: {r: 1, g: 1, b: 0, a: 1} + - _Main3rdTex_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _MainColor: {r: 1, g: 1, b: 1, a: 1} + - _MainTexHSVG: {r: 0, g: 1, b: 1, a: 1} + - _MainTex_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _MatCap2ndBlendUV1: {r: 0, g: 0, b: 0, a: 0} + - _MatCap2ndColor: {r: 1, g: 1, b: 1, a: 1} + - _MatCapBlendUV1: {r: 0, g: 0, b: 0, a: 0} + - _MatCapColor: {r: 1, g: 1, b: 1, a: 1} + - _ObjPosi: {r: 0, g: 0, b: 0, a: 0} + - _ObjectForward: {r: 0, g: 0, b: 0, a: 0} + - _ObjectRight: {r: 0, g: 0, b: 0, a: 0} + - _OutResi: {r: 1, g: 1, b: 1, a: 1} + - _OutlineColor: {r: 0.76052475, g: 0.48514998, b: 0.5583405, a: 1} + - _OutlineLitColor: {r: 1, g: 0.19999996, b: 0, a: 0} + - _OutlineOffset: {r: 0, g: 0, b: 0, a: 1} + - _OutlineTexHSVG: {r: 0, g: 1, b: 1, a: 1} + - _OutlineTex_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _OverallShadowColor: {r: 0, g: 0, b: 0, a: 1} + - _PTCol: {r: 0, g: 0, b: 0, a: 1} + - _PreColor: {r: 1, g: 1, b: 1, a: 1} + - _PrevPosition: {r: 0, g: 0, b: 0, a: 0} + - _ReflectionColor: {r: 1, g: 1, b: 1, a: 1} + - _ReflectionCubeColor: {r: 0, g: 0, b: 0, a: 1} + - _RimColor: {r: 1, g: 1, b: 1, a: 1} + - _RimIndirColor: {r: 1, g: 1, b: 1, a: 1} + - _RimLigPosi: {r: 1, g: 1, b: 1, a: 1} + - _RimLightColor: {r: 1, g: 1, b: 1, a: 1} + - _RimShadeColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} + - _SSAOColor: {r: 0, g: 0, b: 0, a: 0} + - _SelfLitColor: {r: 1, g: 1, b: 1, a: 1} + - _SelfShadowRealTimeShadowColor: {r: 1, g: 1, b: 1, a: 1} + - _Shadow2ndColor: {r: 0, g: 0, b: 0, a: 0} + - _Shadow3rdColor: {r: 0, g: 0, b: 0, a: 0} + - _ShadowAOShift: {r: 1, g: 0, b: 1, a: 0} + - _ShadowAOShift2: {r: 1, g: 0, b: 1, a: 0} + - _ShadowBorderColor: {r: 1, g: 0, b: 0, a: 1} + - _ShadowColor: {r: 0.7, g: 0.75, b: 0.85, a: 1} + - _ShadowTColor: {r: 1, g: 1, b: 1, a: 1} + - _XYZPosition: {r: 0, g: 0, b: 0, a: 0} + - _e2ga0: {r: 1, g: 0, b: 0, a: 0} + - _e2ga1: {r: 1, g: 0, b: 0, a: 1} + - _e2ga2: {r: 1, g: 0, b: 0, a: 0} + - _e2ga3: {r: 1, g: 0, b: 0, a: 0} + - _e2ga4: {r: 1, g: 0, b: 0, a: 0} + - _e2ga5: {r: 1, g: 0, b: 0, a: 0} + - _e2ga6: {r: 1, g: 0, b: 0, a: 0} + - _e2ga7: {r: 1, g: 0, b: 0, a: 0} + - _e2gc0: {r: 1, g: 1, b: 1, a: 0} + - _e2gc1: {r: 1, g: 1, b: 1, a: 1} + - _e2gc2: {r: 1, g: 1, b: 1, a: 0} + - _e2gc3: {r: 1, g: 1, b: 1, a: 0} + - _e2gc4: {r: 1, g: 1, b: 1, a: 0} + - _e2gc5: {r: 1, g: 1, b: 1, a: 0} + - _e2gc6: {r: 1, g: 1, b: 1, a: 0} + - _e2gc7: {r: 1, g: 1, b: 1, a: 0} + - _ega0: {r: 1, g: 0, b: 0, a: 0} + - _ega1: {r: 1, g: 0, b: 0, a: 1} + - _ega2: {r: 1, g: 0, b: 0, a: 0} + - _ega3: {r: 1, g: 0, b: 0, a: 0} + - _ega4: {r: 1, g: 0, b: 0, a: 0} + - _ega5: {r: 1, g: 0, b: 0, a: 0} + - _ega6: {r: 1, g: 0, b: 0, a: 0} + - _ega7: {r: 1, g: 0, b: 0, a: 0} + - _egc0: {r: 1, g: 1, b: 1, a: 0} + - _egc1: {r: 1, g: 1, b: 1, a: 1} + - _egc2: {r: 1, g: 1, b: 1, a: 0} + - _egc3: {r: 1, g: 1, b: 1, a: 0} + - _egc4: {r: 1, g: 1, b: 1, a: 0} + - _egc5: {r: 1, g: 1, b: 1, a: 0} + - _egc6: {r: 1, g: 1, b: 1, a: 0} + - _egc7: {r: 1, g: 1, b: 1, a: 0} + m_BuildTextureStacks: [] + m_AllowLocking: 1 diff --git a/Assets/04_Models/Characters/Fariy/Materials/Body_Hair/Alistia_Face_Alpha.mat.meta b/Assets/04_Models/Characters/Fariy/Materials/Body_Hair/Alistia_Face_Alpha.mat.meta new file mode 100644 index 00000000..30a25bd7 --- /dev/null +++ b/Assets/04_Models/Characters/Fariy/Materials/Body_Hair/Alistia_Face_Alpha.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 5434df79a062a264fa80847913923f64 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/04_Models/Characters/Fariy/Materials/Body_Hair/Alistia_Hair.mat b/Assets/04_Models/Characters/Fariy/Materials/Body_Hair/Alistia_Hair.mat new file mode 100644 index 00000000..8d998a67 --- /dev/null +++ b/Assets/04_Models/Characters/Fariy/Materials/Body_Hair/Alistia_Hair.mat @@ -0,0 +1,1026 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 8 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: Alistia_Hair + m_Shader: {fileID: 4800000, guid: 6459b2db96a08ca41b0f9b39dc7ad59e, type: 3} + m_Parent: {fileID: 0} + m_ModifiedSerializedProperties: 0 + m_ValidKeywords: + - N_F_DDMD_ON + - N_F_EAL_ON + - N_F_O_ON + - N_F_RDC_ON + - N_F_RELGI_ON + - N_F_SS_ON + - N_F_TRANSAFFSHA_ON + - _UVSET_UV0 + m_InvalidKeywords: [] + m_LightmapFlags: 0 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: -1 + stringTagMap: {} + disabledShaderPasses: [] + m_LockedProperties: + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _AlphaMask: + m_Texture: {fileID: 2800000, guid: 782a9af2fc072c2419c418886e440f9d, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _AnisotropyScaleMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _AnisotropyShiftNoiseMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _AnisotropyTangentMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _AudioLinkLocalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _AudioLinkMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BacklightColorTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BaseColorMap: + m_Texture: {fileID: 2800000, guid: d048c66387fa0bc4f9913dd2d7d7fa87, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BaseMap: + m_Texture: {fileID: 2800000, guid: d048c66387fa0bc4f9913dd2d7d7fa87, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Bump2ndMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Bump2ndScaleMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DissolveMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DissolveNoiseMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DitherTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Emission2ndBlendMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Emission2ndGradTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Emission2ndMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionBlendMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionGradTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _FReflection: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _GlitterColorTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _GlitterShapeTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _GlossTexture: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MCap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MCapMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main2ndBlendMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main2ndDissolveMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main2ndDissolveNoiseMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main2ndTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main3rdBlendMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main3rdDissolveMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main3rdDissolveNoiseMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main3rdTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainColorAdjustMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainGradationTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 2800000, guid: d048c66387fa0bc4f9913dd2d7d7fa87, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MaskGloss: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MaskReflection: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MaskSelfLit: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MaskTransparency: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MatCap2ndBlendMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MatCap2ndBumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MatCap2ndTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MatCapBlendMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MatCapBumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MatCapTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _NormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OutlineTex: + m_Texture: {fileID: 2800000, guid: d048c66387fa0bc4f9913dd2d7d7fa87, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OutlineVectorTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OutlineWidthControl: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OutlineWidthMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _PTexture: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ReflectionColorTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ReflectionCubeTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _RimColorTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _RimShadeMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _SecondaryCutout: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Shadow2ndColorTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Shadow3rdColorTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ShadowBlurMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ShadowBorderMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ShadowColorTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ShadowColorTexture: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ShadowStrengthMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ShadowT: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _SmoothnessTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Ints: [] + m_Floats: + - _AAS: 0.0001 + - _AAStrength: 1 + - _AlpToCov: 0 + - _AlphaBaseCutout: 1 + - _AlphaBoostFA: 10 + - _AlphaMaskMode: 1 + - _AlphaMaskScale: 1 + - _AlphaMaskValue: 0.35 + - _AlphaToMask: 0 + - _Anisotropy2MatCap: 0 + - _Anisotropy2MatCap2nd: 0 + - _Anisotropy2Reflection: 0 + - _Anisotropy2ndBitangentWidth: 1 + - _Anisotropy2ndShift: 0 + - _Anisotropy2ndShiftNoiseScale: 0 + - _Anisotropy2ndSpecularStrength: 0 + - _Anisotropy2ndTangentWidth: 1 + - _AnisotropyBitangentWidth: 1 + - _AnisotropyScale: 1 + - _AnisotropyShift: 0 + - _AnisotropyShiftNoiseScale: 0 + - _AnisotropySpecularStrength: 1 + - _AnisotropyTangentWidth: 1 + - _ApplyReflection: 0 + - _ApplySpecular: 1 + - _ApplySpecularFA: 1 + - _AsOverlay: 0 + - _AsUnlit: 0 + - _AudioLink2Emission: 0 + - _AudioLink2Emission2nd: 0 + - _AudioLink2Emission2ndGrad: 0 + - _AudioLink2EmissionGrad: 0 + - _AudioLink2Main2nd: 0 + - _AudioLink2Main3rd: 0 + - _AudioLink2Vertex: 0 + - _AudioLinkAsLocal: 0 + - _AudioLinkMask_UVMode: 0 + - _AudioLinkUVMode: 1 + - _AudioLinkVertexUVMode: 1 + - _BackfaceForceShadow: 0 + - _BacklightBackfaceMask: 1 + - _BacklightBlur: 0.05 + - _BacklightBorder: 0.35 + - _BacklightDirectivity: 5 + - _BacklightMainStrength: 0 + - _BacklightNormalStrength: 1 + - _BacklightReceiveShadow: 1 + - _BacklightViewStrength: 1 + - _BeforeExposureLimit: 10000 + - _BitKey0: 0 + - _BitKey1: 0 + - _BitKey10: 0 + - _BitKey11: 0 + - _BitKey12: 0 + - _BitKey13: 0 + - _BitKey14: 0 + - _BitKey15: 0 + - _BitKey16: 0 + - _BitKey17: 0 + - _BitKey18: 0 + - _BitKey19: 0 + - _BitKey2: 0 + - _BitKey20: 0 + - _BitKey21: 0 + - _BitKey22: 0 + - _BitKey23: 0 + - _BitKey24: 0 + - _BitKey25: 0 + - _BitKey26: 0 + - _BitKey27: 0 + - _BitKey28: 0 + - _BitKey29: 0 + - _BitKey3: 0 + - _BitKey30: 0 + - _BitKey31: 0 + - _BitKey4: 0 + - _BitKey5: 0 + - _BitKey6: 0 + - _BitKey7: 0 + - _BitKey8: 0 + - _BitKey9: 0 + - _BleModDest: 0 + - _BleModSour: 1 + - _BlendOp: 0 + - _BlendOpAlpha: 0 + - _BlendOpAlphaFA: 4 + - _BlendOpFA: 4 + - _Bump2ndMap_UVMode: 0 + - _Bump2ndScale: 1 + - _BumpScale: 1 + - _ClipAdju: 0 + - _ColorMask: 15 + - _Compa: 4 + - _ComputeMeshIndex: 0 + - _Cull: 0 + - _Culling: 2 + - _CustomLightDirectionFollowObjectRotation: 0 + - _CustomLightDirectionIntensity: 0 + - _Cutoff: 0.001 + - _Cutout: 0.5 + - _DepthThreshold: 900 + - _DirectionalLightIntensity: 1 + - _DissolveNoiseStrength: 0.1 + - _DistanceFadeMode: 0 + - _DistanceFadeRimFresnelPower: 5 + - _DitherMaxValue: 255 + - _DoubleSidedOutline: 1 + - _DstBlend: 10 + - _DstBlendAlpha: 10 + - _DstBlendAlphaFA: 1 + - _DstBlendFA: 1 + - _DummyProperty: 0 + - _DynamicNoisyOutline: 0 + - _Emission2ndBlend: 1 + - _Emission2ndBlendMode: 1 + - _Emission2ndFluorescence: 0 + - _Emission2ndGradSpeed: 1 + - _Emission2ndMainStrength: 0 + - _Emission2ndMap_UVMode: 0 + - _Emission2ndParallaxDepth: 0 + - _Emission2ndUseGrad: 0 + - _EmissionBlend: 1 + - _EmissionBlendMode: 1 + - _EmissionFluorescence: 0 + - _EmissionGradSpeed: 1 + - _EmissionMainStrength: 0 + - _EmissionMap_UVMode: 0 + - _EmissionParallaxDepth: 0 + - _EmissionUseGrad: 0 + - _EnvironmentalLightingIntensity: 0.5 + - _FarDistanceMaxWidth: 10 + - _FlipNormal: 0 + - _GIFlatShade: 0 + - _GIShadeThreshold: 0 + - _GSAAStrength: 0 + - _GlitterAngleRandomize: 0 + - _GlitterApplyShape: 0 + - _GlitterApplyTransparency: 1 + - _GlitterBackfaceMask: 0 + - _GlitterColorTex_UVMode: 0 + - _GlitterEnableLighting: 1 + - _GlitterMainStrength: 0 + - _GlitterNormalStrength: 1 + - _GlitterPostContrast: 1 + - _GlitterScaleRandomize: 0 + - _GlitterSensitivity: 0.25 + - _GlitterShadowMask: 0 + - _GlitterUVMode: 0 + - _GlitterVRParallaxStrength: 0 + - _GlossColorPower: 10 + - _GlossIntensity: 1 + - _GlossSoftness: 0 + - _GlossTextureFollowLight: 0 + - _GlossTextureFollowObjectRotation: 0 + - _GlossTextureRotate: 0 + - _GlossTextureSoftness: 0 + - _Glossiness: 0.6 + - _Glow_Edge_Width: 1 + - _HighlightColorPower: 2 + - _IDMask1: 0 + - _IDMask2: 0 + - _IDMask3: 0 + - _IDMask4: 0 + - _IDMask5: 0 + - _IDMask6: 0 + - _IDMask7: 0 + - _IDMask8: 0 + - _IDMaskCompile: 0 + - _IDMaskControlsDissolve: 0 + - _IDMaskFrom: 8 + - _IDMaskIndex1: 0 + - _IDMaskIndex2: 0 + - _IDMaskIndex3: 0 + - _IDMaskIndex4: 0 + - _IDMaskIndex5: 0 + - _IDMaskIndex6: 0 + - _IDMaskIndex7: 0 + - _IDMaskIndex8: 0 + - _IDMaskIsBitmap: 0 + - _IDMaskPrior1: 0 + - _IDMaskPrior2: 0 + - _IDMaskPrior3: 0 + - _IDMaskPrior4: 0 + - _IDMaskPrior5: 0 + - _IDMaskPrior6: 0 + - _IDMaskPrior7: 0 + - _IDMaskPrior8: 0 + - _IgnoreEncryption: 0 + - _Invisible: 0 + - _LLI_Max: 1 + - _LLI_Min: 0 + - _LigIgnoYNorDir: 0 + - _LightAffectOutlineColor: 0 + - _LightAffectRimLightColor: 0 + - _LightAffectShadow: 0 + - _LightFalloffAffectShadowT: 0 + - _LightFalloffSoftness: 1 + - _LightIntensity: 1 + - _LightMaxLimit: 1 + - _LightMinLimit: 0.05 + - _MCIALO: 0 + - _MCapIntensity: 1 + - _MVCOL: 0 + - _MaiColPo: 0.85 + - _Main2ndDissolveNoiseStrength: 0.1 + - _Main2ndEnableLighting: 1 + - _Main2ndTexAlphaMode: 0 + - _Main2ndTexAngle: 0 + - _Main2ndTexBlendMode: 0 + - _Main2ndTexIsDecal: 0 + - _Main2ndTexIsLeftOnly: 0 + - _Main2ndTexIsMSDF: 0 + - _Main2ndTexIsRightOnly: 0 + - _Main2ndTexShouldCopy: 0 + - _Main2ndTexShouldFlipCopy: 0 + - _Main2ndTexShouldFlipMirror: 0 + - _Main2ndTex_Cull: 0 + - _Main2ndTex_UVMode: 0 + - _Main3rdDissolveNoiseStrength: 0.1 + - _Main3rdEnableLighting: 1 + - _Main3rdTexAlphaMode: 0 + - _Main3rdTexAngle: 0 + - _Main3rdTexBlendMode: 0 + - _Main3rdTexIsDecal: 0 + - _Main3rdTexIsLeftOnly: 0 + - _Main3rdTexIsMSDF: 0 + - _Main3rdTexIsRightOnly: 0 + - _Main3rdTexShouldCopy: 0 + - _Main3rdTexShouldFlipCopy: 0 + - _Main3rdTexShouldFlipMirror: 0 + - _Main3rdTex_Cull: 0 + - _Main3rdTex_UVMode: 0 + - _MainGradationStrength: 0 + - _MatCap2ndApplyTransparency: 1 + - _MatCap2ndBackfaceMask: 0 + - _MatCap2ndBlend: 1 + - _MatCap2ndBlendMode: 1 + - _MatCap2ndBumpScale: 1 + - _MatCap2ndCustomNormal: 0 + - _MatCap2ndEnableLighting: 1 + - _MatCap2ndLod: 0 + - _MatCap2ndMainStrength: 0 + - _MatCap2ndNormalStrength: 1 + - _MatCap2ndPerspective: 1 + - _MatCap2ndShadowMask: 0 + - _MatCap2ndVRParallaxStrength: 1 + - _MatCap2ndZRotCancel: 1 + - _MatCapApplyTransparency: 1 + - _MatCapBackfaceMask: 0 + - _MatCapBlend: 0.6 + - _MatCapBlendMode: 1 + - _MatCapBumpScale: 1 + - _MatCapCustomNormal: 0 + - _MatCapEnableLighting: 1 + - _MatCapLod: 0 + - _MatCapMainStrength: 0 + - _MatCapNormalStrength: 1 + - _MatCapPerspective: 1 + - _MatCapShadowMask: 0.75 + - _MatCapVRParallaxStrength: 1 + - _MatCapZRotCancel: 1 + - _MaxFadDistance: 2 + - _Metallic: 0 + - _MinFadDistance: 0 + - _MixMainTexToOutline: 0 + - _MonochromeLighting: 0 + - _N_F_ANIS: 0 + - _N_F_CA: 0 + - _N_F_CLD: 0 + - _N_F_CO: 0 + - _N_F_COEDGL: 0 + - _N_F_DCS: 0 + - _N_F_DDMD: 1 + - _N_F_EAL: 1 + - _N_F_ESSAO: 0 + - _N_F_FR: 0 + - _N_F_GLO: 0 + - _N_F_GLOT: 0 + - _N_F_HDLS: 0 + - _N_F_HPSS: 0 + - _N_F_LLI: 0 + - _N_F_MC: 0 + - _N_F_MSSOLTFO: 0 + - _N_F_NFD: 0 + - _N_F_NLASOBF: 0 + - _N_F_NM: 0 + - _N_F_O: 1 + - _N_F_OFLMB: 0 + - _N_F_PA: 0 + - _N_F_PT: 0 + - _N_F_R: 0 + - _N_F_RDC: 1 + - _N_F_RL: 0 + - _N_F_RLIS: 0 + - _N_F_SCO: 0 + - _N_F_SCT: 0 + - _N_F_SE: 0 + - _N_F_SL: 0 + - _N_F_SLMM: 0 + - _N_F_SON: 0 + - _N_F_SS: 1 + - _N_F_ST: 0 + - _N_F_STIAL: 0 + - _N_F_STIS: 0 + - _N_F_STSDFM: 0 + - _N_F_TP: 0 + - _NoiTexAffStraWidt: 0 + - _NoisTexInten: 1 + - _NoiseSize: 100 + - _NoisyOutlineIntensity: 0 + - _NorMapAsDis: 0 + - _NormalMapIntensity: 1 + - _ObjePosiZCS: 0 + - _OffsetFactor: 0 + - _OffsetUnits: 0 + - _Opacity: 1 + - _Oper: 0 + - _OutStenPass: 0 + - _OutZTest: 4 + - _OutZWrite: 1 + - _OutlineAlphaToMask: 0 + - _OutlineBlendOp: 0 + - _OutlineBlendOpAlpha: 0 + - _OutlineBlendOpAlphaFA: 4 + - _OutlineBlendOpFA: 4 + - _OutlineColorMask: 15 + - _OutlineCull: 1 + - _OutlineDeleteMesh: 0 + - _OutlineDisableInVR: 0 + - _OutlineDstBlend: 10 + - _OutlineDstBlendAlpha: 10 + - _OutlineDstBlendAlphaFA: 1 + - _OutlineDstBlendFA: 1 + - _OutlineEnableLighting: 1 + - _OutlineExtrudeMethod: 0 + - _OutlineFixWidth: 0 + - _OutlineLitApplyTex: 0 + - _OutlineLitOffset: -8 + - _OutlineLitScale: 10 + - _OutlineLitShadowReceive: 0 + - _OutlineOffsetFactor: 0 + - _OutlineOffsetUnits: 0 + - _OutlineSrcBlend: 5 + - _OutlineSrcBlendAlpha: 1 + - _OutlineSrcBlendAlphaFA: 0 + - _OutlineSrcBlendFA: 1 + - _OutlineStencilComp: 8 + - _OutlineStencilFail: 0 + - _OutlineStencilPass: 0 + - _OutlineStencilReadMask: 255 + - _OutlineStencilRef: 0 + - _OutlineStencilWriteMask: 255 + - _OutlineStencilZFail: 0 + - _OutlineVectorScale: 1 + - _OutlineVectorUVMode: 0 + - _OutlineVertexR2Width: 0 + - _OutlineWidth: 0.03 + - _OutlineWidthAffectedByViewDistance: 0 + - _OutlineZBias: 0 + - _OutlineZClip: 1 + - _OutlineZPostionInCamera: 0 + - _OutlineZTest: 2 + - _OutlineZWrite: 1 + - _OverallShadowColorPower: 1 + - _PADist: 0 + - _PASize: 0.5 + - _PASmooTrans: 1 + - _PSGLOTEX: 0 + - _PTexturePower: 1 + - _Parallax: 0.02 + - _ParallaxOffset: 0.5 + - _PointSpotlightIntensity: 1 + - _PreAlphaToMask: 0 + - _PreBlendOp: 0 + - _PreBlendOpAlpha: 0 + - _PreBlendOpAlphaFA: 4 + - _PreBlendOpFA: 4 + - _PreColorMask: 15 + - _PreCull: 2 + - _PreCutoff: 0.5 + - _PreDstBlend: 10 + - _PreDstBlendAlpha: 10 + - _PreDstBlendAlphaFA: 1 + - _PreDstBlendFA: 1 + - _PreOffsetFactor: 0 + - _PreOffsetUnits: 0 + - _PreOutType: 0 + - _PreSrcBlend: 1 + - _PreSrcBlendAlpha: 1 + - _PreSrcBlendAlphaFA: 0 + - _PreSrcBlendFA: 1 + - _PreStencilComp: 8 + - _PreStencilFail: 0 + - _PreStencilPass: 0 + - _PreStencilReadMask: 255 + - _PreStencilRef: 0 + - _PreStencilWriteMask: 255 + - _PreStencilZFail: 0 + - _PreZClip: 1 + - _PreZTest: 4 + - _PreZWrite: 1 + - _PresAdju: 1 + - _RELG: 1 + - _RQSO: 0 + - _ReduSha: 0.5 + - _RefMetallic: 0 + - _RefVal: 0 + - _Reflectance: 0.04 + - _ReflectionApplyTransparency: 1 + - _ReflectionBlendMode: 1 + - _ReflectionCubeEnableLighting: 1 + - _ReflectionCubeOverride: 0 + - _ReflectionIntensity: 0 + - _ReflectionNormalStrength: 1 + - _RimApplyTransparency: 1 + - _RimBackfaceMask: 0 + - _RimBlendMode: 1 + - _RimBlur: 0.1 + - _RimBorder: 0.873 + - _RimDirRange: 0 + - _RimDirStrength: 0 + - _RimEnableLighting: 1 + - _RimFresnelPower: 1 + - _RimIndirBlur: 0.1 + - _RimIndirBorder: 0.5 + - _RimIndirRange: 0 + - _RimLigInt: 1 + - _RimLightColorPower: 10 + - _RimLightInLight: 1 + - _RimLightSoftness: 1 + - _RimLightUnfill: 1.5 + - _RimMainStrength: 0 + - _RimNormalStrength: 1 + - _RimShadeBlur: 1 + - _RimShadeBorder: 0.5 + - _RimShadeFresnelPower: 1 + - _RimShadeNormalStrength: 1 + - _RimShadowMask: 1 + - _RimVRParallaxStrength: 1 + - _SPECIN: 1 + - _SPECMODE: 0 + - _STIL: 0 + - _Saturation: 1 + - _SelfLitHighContrast: 1 + - _SelfLitIntensity: 0 + - _SelfLitPower: 2 + - _SelfShadowAffectedByLightShadowStrength: 0 + - _SelfShadowHardness: 1 + - _SelfShadowRealTimeShadowColorPower: 1 + - _SelfShadowRealtimeShadowIntensity: 0 + - _SelfShadowShadowTAtViewDirection: 0 + - _SelfShadowThreshold: 0.93 + - _Shadow2ndBlur: 0.14 + - _Shadow2ndBorder: 0.3 + - _Shadow2ndNormalStrength: 1 + - _Shadow2ndReceive: 0 + - _Shadow3rdBlur: 0.1 + - _Shadow3rdBorder: 0.25 + - _Shadow3rdNormalStrength: 1 + - _Shadow3rdReceive: 0 + - _ShadowBlur: 0.1 + - _ShadowBlurMaskLOD: 0 + - _ShadowBorder: 0.35 + - _ShadowBorderMaskLOD: 0 + - _ShadowBorderRange: 0 + - _ShadowColorTexturePower: 0 + - _ShadowColorType: 0 + - _ShadowEnvStrength: 0 + - _ShadowFlatBlur: 1 + - _ShadowFlatBorder: 1 + - _ShadowHardness: 0 + - _ShadowMainStrength: 0 + - _ShadowMaskType: 0 + - _ShadowNormalStrength: 1 + - _ShadowPostAO: 0 + - _ShadowReceive: 1 + - _ShadowStrength: 1 + - _ShadowStrengthMaskLOD: 0 + - _ShadowTColorPower: 1 + - _ShadowTHardness: 1 + - _ShadowTIntensity: 1 + - _ShadowTLightThreshold: 50 + - _ShadowTShadowThreshold: 0 + - _ShifAnis: 0 + - _ShiftBackfaceUV: 0 + - _ShowInAmbientLightShadowIntensity: 1 + - _ShowInAmbientLightShadowThreshold: 0.4 + - _ShowNormal: 0 + - _SimTrans: 0 + - _SkinMatrixIndex: 0 + - _SmoothObjectNormal: 0 + - _Smoothness: 1 + - _SpecularBlur: 0 + - _SpecularBorder: 0.5 + - _SpecularNormalStrength: 1 + - _SpecularToon: 1 + - _SrcBlend: 1 + - _SrcBlendAlpha: 1 + - _SrcBlendAlphaFA: 0 + - _SrcBlendFA: 1 + - _StencilComp: 8 + - _StencilFail: 0 + - _StencilPass: 2 + - _StencilReadMask: 255 + - _StencilRef: 0 + - _StencilWriteMask: 255 + - _StencilZFail: 0 + - _StraWidt: 10 + - _SubpassCutoff: 0.5 + - _TEXMCOLINT: 1 + - _TRANSMODE: 0 + - _TessEdge: 10 + - _TessFactorMax: 3 + - _TessShrink: 0 + - _TessStrength: 0.5 + - _TessellationFar: 1 + - _TessellationNear: 1 + - _TessellationSmoothness: 0.5 + - _TessellationTransition: 0.8 + - _TexturePatternStyle: 0 + - _TrailSize: 1.5 + - _TransAffSha: 1 + - _TransparentMode: 0 + - _TransparentThreshold: 0 + - _TriPlaBlend: 4 + - _TriPlaTile: 1 + - _UDIMDiscardCompile: 0 + - _UDIMDiscardMode: 0 + - _UDIMDiscardRow0_0: 0 + - _UDIMDiscardRow0_1: 0 + - _UDIMDiscardRow0_2: 0 + - _UDIMDiscardRow0_3: 0 + - _UDIMDiscardRow1_0: 0 + - _UDIMDiscardRow1_1: 0 + - _UDIMDiscardRow1_2: 0 + - _UDIMDiscardRow1_3: 0 + - _UDIMDiscardRow2_0: 0 + - _UDIMDiscardRow2_1: 0 + - _UDIMDiscardRow2_2: 0 + - _UDIMDiscardRow2_3: 0 + - _UDIMDiscardRow3_0: 0 + - _UDIMDiscardRow3_1: 0 + - _UDIMDiscardRow3_2: 0 + - _UDIMDiscardRow3_3: 0 + - _UDIMDiscardUV: 0 + - _UVSet: 0 + - _UseAnisotropy: 0 + - _UseAudioLink: 0 + - _UseBacklight: 0 + - _UseBump2ndMap: 0 + - _UseBumpMap: 0 + - _UseClippingCanceller: 0 + - _UseDither: 0 + - _UseEmission: 0 + - _UseEmission2nd: 0 + - _UseGlitter: 0 + - _UseMain2ndTex: 0 + - _UseMain3rdTex: 0 + - _UseMatCap: 0 + - _UseMatCap2nd: 0 + - _UseOutline: 0 + - _UsePOM: 0 + - _UseParallax: 0 + - _UseReflection: 0 + - _UseRim: 0 + - _UseRimShade: 0 + - _UseSecondaryCutout: 0 + - _UseShadow: 1 + - _UseTLB: 0 + - _VertexColorBlueAffectOutlineWitdh: 0 + - _VertexColorGreenControlSelfShadowThreshold: 0 + - _VertexColorRedControlSmoothObjectNormal: 0 + - _VertexLightStrength: 0 + - _ZClip: 1 + - _ZTest: 4 + - _ZWrite: 1 + - _e2gai: 2 + - _e2gci: 2 + - _egai: 2 + - _egci: 2 + - _lilDirectionalLightStrength: 1 + - _lilShadowCasterBias: 0 + - _lilToonVersion: 42 + m_Colors: + - _AudioLinkDefaultValue: {r: 0, g: 0, b: 2, a: 0.75} + - _AudioLinkLocalMapParams: {r: 120, g: 1, b: 0, a: 0} + - _AudioLinkMask_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _AudioLinkStart: {r: 0, g: 0, b: 0, a: 0} + - _AudioLinkUVParams: {r: 0.25, g: 0, b: 0, a: 0.125} + - _AudioLinkVertexStart: {r: 0, g: 0, b: 0, a: 0} + - _AudioLinkVertexStrength: {r: 0, g: 0, b: 0, a: 1} + - _AudioLinkVertexUVParams: {r: 0.25, g: 0, b: 0, a: 0.125} + - _BackfaceColor: {r: 0, g: 0, b: 0, a: 0} + - _BacklightColor: {r: 0.85, g: 0.8, b: 0.7, a: 1} + - _BaseColor: {r: 1, g: 1, b: 1, a: 1} + - _Color: {r: 1, g: 1, b: 1, a: 1} + - _Color2nd: {r: 1, g: 1, b: 1, a: 1} + - _Color3rd: {r: 1, g: 1, b: 1, a: 1} + - _CustomLightDirection: {r: 0, g: 0, b: 10, a: 0} + - _DissolveColor: {r: 1, g: 1, b: 1, a: 1} + - _DissolveNoiseMask_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _DissolveParams: {r: 0, g: 0, b: 0.5, a: 0.1} + - _DissolvePos: {r: 0, g: 0, b: 0, a: 0} + - _DistanceFade: {r: 0.1, g: 0.01, b: 0, a: 0} + - _DistanceFadeColor: {r: 0, g: 0, b: 0, a: 1} + - _DistanceFadeRimColor: {r: 0, g: 0, b: 0, a: 0} + - _Emission2ndBlendMask_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _Emission2ndBlink: {r: 0, g: 0, b: 3.141593, a: 0} + - _Emission2ndColor: {r: 1, g: 1, b: 1, a: 1} + - _Emission2ndMap_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _EmissionBlendMask_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _EmissionBlink: {r: 0, g: 0, b: 3.141593, a: 0} + - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} + - _EmissionMap_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _GlitterAtras: {r: 1, g: 1, b: 0, a: 0} + - _GlitterColor: {r: 1, g: 1, b: 1, a: 1} + - _GlitterParams1: {r: 256, g: 256, b: 0.16, a: 50} + - _GlitterParams2: {r: 0.25, g: 0, b: 0, a: 0} + - _GlossColor: {r: 1, g: 1, b: 1, a: 1} + - _Glow_Color: {r: 1, g: 1, b: 1, a: 1} + - _HighlightColor: {r: 0, g: 0.056895256, b: 1, a: 1} + - _Keys: {r: 0, g: 0, b: 0, a: 0} + - _LightDirectionOverride: {r: 0.001, g: 0.002, b: 0.001, a: 0} + - _Main2ndDissolveColor: {r: 1, g: 1, b: 1, a: 1} + - _Main2ndDissolveNoiseMask_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _Main2ndDissolveParams: {r: 0, g: 0, b: 0.5, a: 0.1} + - _Main2ndDissolvePos: {r: 0, g: 0, b: 0, a: 0} + - _Main2ndDistanceFade: {r: 0.1, g: 0.01, b: 0, a: 0} + - _Main2ndTexDecalAnimation: {r: 1, g: 1, b: 1, a: 30} + - _Main2ndTexDecalSubParam: {r: 1, g: 1, b: 0, a: 1} + - _Main2ndTex_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _Main3rdDissolveColor: {r: 1, g: 1, b: 1, a: 1} + - _Main3rdDissolveNoiseMask_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _Main3rdDissolveParams: {r: 0, g: 0, b: 0.5, a: 0.1} + - _Main3rdDissolvePos: {r: 0, g: 0, b: 0, a: 0} + - _Main3rdDistanceFade: {r: 0.1, g: 0.01, b: 0, a: 0} + - _Main3rdTexDecalAnimation: {r: 1, g: 1, b: 1, a: 30} + - _Main3rdTexDecalSubParam: {r: 1, g: 1, b: 0, a: 1} + - _Main3rdTex_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _MainColor: {r: 0.7558568, g: 0.7311321, b: 1, a: 1} + - _MainTexHSVG: {r: 0, g: 1, b: 1, a: 1} + - _MainTex_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _MatCap2ndBlendUV1: {r: 0, g: 0, b: 0, a: 0} + - _MatCap2ndColor: {r: 1, g: 1, b: 1, a: 1} + - _MatCapBlendUV1: {r: 0, g: 0, b: 0, a: 0} + - _MatCapColor: {r: 1, g: 1, b: 1, a: 0.7} + - _ObjPosi: {r: 0, g: 0, b: 0, a: 0} + - _ObjectForward: {r: 0, g: 0, b: 0, a: 0} + - _ObjectRight: {r: 0, g: 0, b: 0, a: 0} + - _OutResi: {r: 1, g: 1, b: 1, a: 1} + - _OutlineColor: {r: 0.43298328, g: 0.4456163, b: 0.6603774, a: 1} + - _OutlineLitColor: {r: 1, g: 0.19999996, b: 0, a: 0} + - _OutlineOffset: {r: 0, g: 0, b: 0, a: 1} + - _OutlineTexHSVG: {r: 0, g: 1, b: 1, a: 1} + - _OutlineTex_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _OverallShadowColor: {r: 0, g: 0, b: 0, a: 1} + - _PTCol: {r: 0, g: 0, b: 0, a: 1} + - _PreColor: {r: 1, g: 1, b: 1, a: 1} + - _PrevPosition: {r: 0, g: 0, b: 0, a: 0} + - _ReflectionColor: {r: 1, g: 1, b: 1, a: 1} + - _ReflectionCubeColor: {r: 0, g: 0, b: 0, a: 1} + - _RimColor: {r: 0.5, g: 0.46249998, b: 0.42499956, a: 0.262} + - _RimIndirColor: {r: 1, g: 1, b: 1, a: 1} + - _RimLigPosi: {r: 1, g: 1, b: 1, a: 1} + - _RimLightColor: {r: 1, g: 1, b: 1, a: 1} + - _RimShadeColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} + - _SSAOColor: {r: 0, g: 0, b: 0, a: 0} + - _SelfLitColor: {r: 1, g: 1, b: 1, a: 1} + - _SelfShadowRealTimeShadowColor: {r: 1, g: 1, b: 1, a: 1} + - _Shadow2ndColor: {r: 0.85898006, g: 0.88302904, b: 0.9150943, a: 1} + - _Shadow3rdColor: {r: 0, g: 0, b: 0, a: 0} + - _ShadowAOShift: {r: 1, g: 0, b: 1, a: 0} + - _ShadowAOShift2: {r: 1, g: 0, b: 1, a: 0} + - _ShadowBorderColor: {r: 0.8666667, g: 0.8901961, b: 0.9137255, a: 1} + - _ShadowColor: {r: 0.9123354, g: 0.9326618, b: 0.9622642, a: 1} + - _ShadowTColor: {r: 1, g: 1, b: 1, a: 1} + - _XYZPosition: {r: 0, g: 0, b: 0, a: 0} + - _e2ga0: {r: 1, g: 0, b: 0, a: 0} + - _e2ga1: {r: 1, g: 0, b: 0, a: 1} + - _e2ga2: {r: 1, g: 0, b: 0, a: 0} + - _e2ga3: {r: 1, g: 0, b: 0, a: 0} + - _e2ga4: {r: 1, g: 0, b: 0, a: 0} + - _e2ga5: {r: 1, g: 0, b: 0, a: 0} + - _e2ga6: {r: 1, g: 0, b: 0, a: 0} + - _e2ga7: {r: 1, g: 0, b: 0, a: 0} + - _e2gc0: {r: 1, g: 1, b: 1, a: 0} + - _e2gc1: {r: 1, g: 1, b: 1, a: 1} + - _e2gc2: {r: 1, g: 1, b: 1, a: 0} + - _e2gc3: {r: 1, g: 1, b: 1, a: 0} + - _e2gc4: {r: 1, g: 1, b: 1, a: 0} + - _e2gc5: {r: 1, g: 1, b: 1, a: 0} + - _e2gc6: {r: 1, g: 1, b: 1, a: 0} + - _e2gc7: {r: 1, g: 1, b: 1, a: 0} + - _ega0: {r: 1, g: 0, b: 0, a: 0} + - _ega1: {r: 1, g: 0, b: 0, a: 1} + - _ega2: {r: 1, g: 0, b: 0, a: 0} + - _ega3: {r: 1, g: 0, b: 0, a: 0} + - _ega4: {r: 1, g: 0, b: 0, a: 0} + - _ega5: {r: 1, g: 0, b: 0, a: 0} + - _ega6: {r: 1, g: 0, b: 0, a: 0} + - _ega7: {r: 1, g: 0, b: 0, a: 0} + - _egc0: {r: 1, g: 1, b: 1, a: 0} + - _egc1: {r: 1, g: 1, b: 1, a: 1} + - _egc2: {r: 1, g: 1, b: 1, a: 0} + - _egc3: {r: 1, g: 1, b: 1, a: 0} + - _egc4: {r: 1, g: 1, b: 1, a: 0} + - _egc5: {r: 1, g: 1, b: 1, a: 0} + - _egc6: {r: 1, g: 1, b: 1, a: 0} + - _egc7: {r: 1, g: 1, b: 1, a: 0} + m_BuildTextureStacks: [] + m_AllowLocking: 1 diff --git a/Assets/04_Models/Characters/Fariy/Materials/Body_Hair/Alistia_Hair.mat.meta b/Assets/04_Models/Characters/Fariy/Materials/Body_Hair/Alistia_Hair.mat.meta new file mode 100644 index 00000000..12477884 --- /dev/null +++ b/Assets/04_Models/Characters/Fariy/Materials/Body_Hair/Alistia_Hair.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: c605ffdaefec0d3429b476e3f534840c +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/04_Models/Characters/Fariy/Materials/Cloth.meta b/Assets/04_Models/Characters/Fariy/Materials/Cloth.meta new file mode 100644 index 00000000..1abd81f6 --- /dev/null +++ b/Assets/04_Models/Characters/Fariy/Materials/Cloth.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: ee4551c5eae27eb4bb89edfacd9aa4b7 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/04_Models/Characters/Fariy/Materials/Cloth/Alistia_Cloth_1_Blue.mat b/Assets/04_Models/Characters/Fariy/Materials/Cloth/Alistia_Cloth_1_Blue.mat new file mode 100644 index 00000000..8aefe05d --- /dev/null +++ b/Assets/04_Models/Characters/Fariy/Materials/Cloth/Alistia_Cloth_1_Blue.mat @@ -0,0 +1,996 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 8 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: Alistia_Cloth_1_Blue + m_Shader: {fileID: 4800000, guid: 6459b2db96a08ca41b0f9b39dc7ad59e, type: 3} + m_Parent: {fileID: 0} + m_ModifiedSerializedProperties: 0 + m_ValidKeywords: + - N_F_DDMD_ON + - N_F_EAL_ON + - N_F_O_ON + - N_F_RDC_ON + - N_F_RELGI_ON + - N_F_SS_ON + - N_F_TRANSAFFSHA_ON + - _UVSET_UV0 + m_InvalidKeywords: [] + m_LightmapFlags: 0 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: -1 + stringTagMap: {} + disabledShaderPasses: [] + m_LockedProperties: _ShadowHardness + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _AlphaMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _AnisotropyScaleMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _AnisotropyShiftNoiseMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _AnisotropyTangentMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _AudioLinkLocalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _AudioLinkMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BacklightColorTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BaseColorMap: + m_Texture: {fileID: 2800000, guid: 083e7f8c110fa364c817bb3c34f9fdeb, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BaseMap: + m_Texture: {fileID: 2800000, guid: 083e7f8c110fa364c817bb3c34f9fdeb, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Bump2ndMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Bump2ndScaleMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DissolveMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DissolveNoiseMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DitherTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Emission2ndBlendMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Emission2ndGradTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Emission2ndMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionBlendMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionGradTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _FReflection: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _GlitterColorTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _GlitterShapeTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _GlossTexture: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MCap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MCapMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main2ndBlendMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main2ndDissolveMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main2ndDissolveNoiseMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main2ndTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main3rdBlendMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main3rdDissolveMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main3rdDissolveNoiseMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main3rdTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainColorAdjustMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainGradationTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 2800000, guid: 083e7f8c110fa364c817bb3c34f9fdeb, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MaskGloss: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MaskReflection: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MaskSelfLit: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MaskTransparency: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MatCap2ndBlendMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MatCap2ndBumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MatCap2ndTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MatCapBlendMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MatCapBumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MatCapTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _NormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OutlineTex: + m_Texture: {fileID: 2800000, guid: 083e7f8c110fa364c817bb3c34f9fdeb, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OutlineVectorTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OutlineWidthControl: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OutlineWidthMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _PTexture: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ReflectionColorTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ReflectionCubeTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _RimColorTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _RimShadeMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _SecondaryCutout: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Shadow2ndColorTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Shadow3rdColorTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ShadowBlurMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ShadowBorderMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ShadowColorTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ShadowColorTexture: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ShadowStrengthMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ShadowT: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _SmoothnessTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Ints: [] + m_Floats: + - _AAS: 0.0001 + - _AAStrength: 1 + - _AlpToCov: 0 + - _AlphaBaseCutout: 1 + - _AlphaBoostFA: 10 + - _AlphaMaskMode: 0 + - _AlphaMaskScale: 1 + - _AlphaMaskValue: 0 + - _AlphaToMask: 0 + - _Anisotropy2MatCap: 0 + - _Anisotropy2MatCap2nd: 0 + - _Anisotropy2Reflection: 0 + - _Anisotropy2ndBitangentWidth: 1 + - _Anisotropy2ndShift: 0 + - _Anisotropy2ndShiftNoiseScale: 0 + - _Anisotropy2ndSpecularStrength: 0 + - _Anisotropy2ndTangentWidth: 1 + - _AnisotropyBitangentWidth: 1 + - _AnisotropyScale: 1 + - _AnisotropyShift: 0 + - _AnisotropyShiftNoiseScale: 0 + - _AnisotropySpecularStrength: 1 + - _AnisotropyTangentWidth: 1 + - _ApplyReflection: 0 + - _ApplySpecular: 1 + - _ApplySpecularFA: 1 + - _AsOverlay: 0 + - _AsUnlit: 0 + - _AudioLink2Emission: 0 + - _AudioLink2Emission2nd: 0 + - _AudioLink2Emission2ndGrad: 0 + - _AudioLink2EmissionGrad: 0 + - _AudioLink2Main2nd: 0 + - _AudioLink2Main3rd: 0 + - _AudioLink2Vertex: 0 + - _AudioLinkAsLocal: 0 + - _AudioLinkMask_UVMode: 0 + - _AudioLinkUVMode: 1 + - _AudioLinkVertexUVMode: 1 + - _BackfaceForceShadow: 0 + - _BacklightBackfaceMask: 1 + - _BacklightBlur: 0.2 + - _BacklightBorder: 0.45 + - _BacklightDirectivity: 5 + - _BacklightMainStrength: 0 + - _BacklightNormalStrength: 1 + - _BacklightReceiveShadow: 1 + - _BacklightViewStrength: 1 + - _BeforeExposureLimit: 10000 + - _BitKey0: 0 + - _BitKey1: 0 + - _BitKey10: 0 + - _BitKey11: 0 + - _BitKey12: 0 + - _BitKey13: 0 + - _BitKey14: 0 + - _BitKey15: 0 + - _BitKey16: 0 + - _BitKey17: 0 + - _BitKey18: 0 + - _BitKey19: 0 + - _BitKey2: 0 + - _BitKey20: 0 + - _BitKey21: 0 + - _BitKey22: 0 + - _BitKey23: 0 + - _BitKey24: 0 + - _BitKey25: 0 + - _BitKey26: 0 + - _BitKey27: 0 + - _BitKey28: 0 + - _BitKey29: 0 + - _BitKey3: 0 + - _BitKey30: 0 + - _BitKey31: 0 + - _BitKey4: 0 + - _BitKey5: 0 + - _BitKey6: 0 + - _BitKey7: 0 + - _BitKey8: 0 + - _BitKey9: 0 + - _BleModDest: 0 + - _BleModSour: 1 + - _BlendOp: 0 + - _BlendOpAlpha: 0 + - _BlendOpAlphaFA: 4 + - _BlendOpFA: 4 + - _Bump2ndMap_UVMode: 0 + - _Bump2ndScale: 1 + - _BumpScale: 1 + - _ClipAdju: 0 + - _ColorMask: 15 + - _Compa: 4 + - _ComputeMeshIndex: 0 + - _Cull: 0 + - _Culling: 2 + - _CustomLightDirectionFollowObjectRotation: 0 + - _CustomLightDirectionIntensity: 0 + - _Cutoff: 0.5 + - _Cutout: 0.5 + - _DepthThreshold: 900 + - _DirectionalLightIntensity: 1 + - _DissolveNoiseStrength: 0.1 + - _DistanceFadeMode: 0 + - _DistanceFadeRimFresnelPower: 5 + - _DitherMaxValue: 255 + - _DoubleSidedOutline: 1 + - _DstBlend: 0 + - _DstBlendAlpha: 10 + - _DstBlendAlphaFA: 1 + - _DstBlendFA: 1 + - _DummyProperty: 0 + - _DynamicNoisyOutline: 0 + - _Emission2ndBlend: 1 + - _Emission2ndBlendMode: 1 + - _Emission2ndFluorescence: 0 + - _Emission2ndGradSpeed: 1 + - _Emission2ndMainStrength: 0 + - _Emission2ndMap_UVMode: 0 + - _Emission2ndParallaxDepth: 0 + - _Emission2ndUseGrad: 0 + - _EmissionBlend: 1 + - _EmissionBlendMode: 1 + - _EmissionFluorescence: 0 + - _EmissionGradSpeed: 1 + - _EmissionMainStrength: 0 + - _EmissionMap_UVMode: 0 + - _EmissionParallaxDepth: 0 + - _EmissionUseGrad: 0 + - _EnvironmentalLightingIntensity: 1 + - _FarDistanceMaxWidth: 10 + - _FlipNormal: 0 + - _GIFlatShade: 0 + - _GIShadeThreshold: 0 + - _GSAAStrength: 0 + - _GlitterAngleRandomize: 0 + - _GlitterApplyShape: 0 + - _GlitterApplyTransparency: 1 + - _GlitterBackfaceMask: 0 + - _GlitterColorTex_UVMode: 0 + - _GlitterEnableLighting: 1 + - _GlitterMainStrength: 0 + - _GlitterNormalStrength: 1 + - _GlitterPostContrast: 1 + - _GlitterScaleRandomize: 0 + - _GlitterSensitivity: 0.25 + - _GlitterShadowMask: 0 + - _GlitterUVMode: 0 + - _GlitterVRParallaxStrength: 0 + - _GlossColorPower: 10 + - _GlossIntensity: 1 + - _GlossSoftness: 0 + - _GlossTextureFollowLight: 0 + - _GlossTextureFollowObjectRotation: 0 + - _GlossTextureRotate: 0 + - _GlossTextureSoftness: 0 + - _Glossiness: 0.6 + - _Glow_Edge_Width: 1 + - _HighlightColorPower: 4 + - _IDMask1: 0 + - _IDMask2: 0 + - _IDMask3: 0 + - _IDMask4: 0 + - _IDMask5: 0 + - _IDMask6: 0 + - _IDMask7: 0 + - _IDMask8: 0 + - _IDMaskCompile: 0 + - _IDMaskControlsDissolve: 0 + - _IDMaskFrom: 8 + - _IDMaskIndex1: 0 + - _IDMaskIndex2: 0 + - _IDMaskIndex3: 0 + - _IDMaskIndex4: 0 + - _IDMaskIndex5: 0 + - _IDMaskIndex6: 0 + - _IDMaskIndex7: 0 + - _IDMaskIndex8: 0 + - _IDMaskIsBitmap: 0 + - _IDMaskPrior1: 0 + - _IDMaskPrior2: 0 + - _IDMaskPrior3: 0 + - _IDMaskPrior4: 0 + - _IDMaskPrior5: 0 + - _IDMaskPrior6: 0 + - _IDMaskPrior7: 0 + - _IDMaskPrior8: 0 + - _IgnoreEncryption: 0 + - _Invisible: 0 + - _LLI_Max: 1 + - _LLI_Min: 0 + - _LigIgnoYNorDir: 0 + - _LightAffectOutlineColor: 0 + - _LightAffectRimLightColor: 0 + - _LightAffectShadow: 0 + - _LightFalloffAffectShadowT: 0 + - _LightFalloffSoftness: 1 + - _LightIntensity: 1 + - _LightMaxLimit: 1 + - _LightMinLimit: 0.05 + - _MCIALO: 0 + - _MCapIntensity: 1 + - _MVCOL: 0 + - _MaiColPo: 0.8 + - _Main2ndDissolveNoiseStrength: 0.1 + - _Main2ndEnableLighting: 1 + - _Main2ndTexAlphaMode: 0 + - _Main2ndTexAngle: 0 + - _Main2ndTexBlendMode: 0 + - _Main2ndTexIsDecal: 0 + - _Main2ndTexIsLeftOnly: 0 + - _Main2ndTexIsMSDF: 0 + - _Main2ndTexIsRightOnly: 0 + - _Main2ndTexShouldCopy: 0 + - _Main2ndTexShouldFlipCopy: 0 + - _Main2ndTexShouldFlipMirror: 0 + - _Main2ndTex_Cull: 0 + - _Main2ndTex_UVMode: 0 + - _Main3rdDissolveNoiseStrength: 0.1 + - _Main3rdEnableLighting: 1 + - _Main3rdTexAlphaMode: 0 + - _Main3rdTexAngle: 0 + - _Main3rdTexBlendMode: 0 + - _Main3rdTexIsDecal: 0 + - _Main3rdTexIsLeftOnly: 0 + - _Main3rdTexIsMSDF: 0 + - _Main3rdTexIsRightOnly: 0 + - _Main3rdTexShouldCopy: 0 + - _Main3rdTexShouldFlipCopy: 0 + - _Main3rdTexShouldFlipMirror: 0 + - _Main3rdTex_Cull: 0 + - _Main3rdTex_UVMode: 0 + - _MainGradationStrength: 0 + - _MatCap2ndApplyTransparency: 1 + - _MatCap2ndBackfaceMask: 0 + - _MatCap2ndBlend: 1 + - _MatCap2ndBlendMode: 1 + - _MatCap2ndBumpScale: 1 + - _MatCap2ndCustomNormal: 0 + - _MatCap2ndEnableLighting: 1 + - _MatCap2ndLod: 0 + - _MatCap2ndMainStrength: 0 + - _MatCap2ndNormalStrength: 1 + - _MatCap2ndPerspective: 1 + - _MatCap2ndShadowMask: 0 + - _MatCap2ndVRParallaxStrength: 1 + - _MatCap2ndZRotCancel: 1 + - _MatCapApplyTransparency: 1 + - _MatCapBackfaceMask: 0 + - _MatCapBlend: 1 + - _MatCapBlendMode: 1 + - _MatCapBumpScale: 1 + - _MatCapCustomNormal: 0 + - _MatCapEnableLighting: 1 + - _MatCapLod: 0 + - _MatCapMainStrength: 0 + - _MatCapNormalStrength: 1 + - _MatCapPerspective: 1 + - _MatCapShadowMask: 0 + - _MatCapVRParallaxStrength: 1 + - _MatCapZRotCancel: 1 + - _MaxFadDistance: 2 + - _Metallic: 0 + - _MinFadDistance: 0 + - _MixMainTexToOutline: 0 + - _MonochromeLighting: 0 + - _N_F_ANIS: 0 + - _N_F_CA: 0 + - _N_F_CLD: 0 + - _N_F_CO: 0 + - _N_F_COEDGL: 0 + - _N_F_DCS: 0 + - _N_F_DDMD: 1 + - _N_F_EAL: 1 + - _N_F_ESSAO: 0 + - _N_F_FR: 0 + - _N_F_GLO: 0 + - _N_F_GLOT: 0 + - _N_F_HDLS: 0 + - _N_F_HPSS: 0 + - _N_F_LLI: 0 + - _N_F_MC: 0 + - _N_F_MSSOLTFO: 0 + - _N_F_NFD: 0 + - _N_F_NLASOBF: 0 + - _N_F_NM: 0 + - _N_F_O: 1 + - _N_F_OFLMB: 0 + - _N_F_PA: 0 + - _N_F_PT: 0 + - _N_F_R: 0 + - _N_F_RDC: 1 + - _N_F_RL: 0 + - _N_F_RLIS: 0 + - _N_F_SCO: 0 + - _N_F_SCT: 0 + - _N_F_SE: 0 + - _N_F_SL: 0 + - _N_F_SLMM: 0 + - _N_F_SON: 0 + - _N_F_SS: 1 + - _N_F_ST: 0 + - _N_F_STIAL: 0 + - _N_F_STIS: 0 + - _N_F_STSDFM: 0 + - _N_F_TP: 0 + - _NoiTexAffStraWidt: 0 + - _NoisTexInten: 1 + - _NoiseSize: 100 + - _NoisyOutlineIntensity: 0 + - _NorMapAsDis: 0 + - _NormalMapIntensity: 1 + - _ObjePosiZCS: 0 + - _OffsetFactor: 0 + - _OffsetUnits: 0 + - _Opacity: 1 + - _Oper: 0 + - _OutStenPass: 0 + - _OutZTest: 4 + - _OutZWrite: 1 + - _OutlineAlphaToMask: 0 + - _OutlineBlendOp: 0 + - _OutlineBlendOpAlpha: 0 + - _OutlineBlendOpAlphaFA: 4 + - _OutlineBlendOpFA: 4 + - _OutlineColorMask: 15 + - _OutlineCull: 1 + - _OutlineDeleteMesh: 0 + - _OutlineDisableInVR: 0 + - _OutlineDstBlend: 0 + - _OutlineDstBlendAlpha: 10 + - _OutlineDstBlendAlphaFA: 1 + - _OutlineDstBlendFA: 1 + - _OutlineEnableLighting: 1 + - _OutlineExtrudeMethod: 0 + - _OutlineFixWidth: 1 + - _OutlineLitApplyTex: 0 + - _OutlineLitOffset: -8 + - _OutlineLitScale: 10 + - _OutlineLitShadowReceive: 0 + - _OutlineOffsetFactor: 0 + - _OutlineOffsetUnits: 0 + - _OutlineSrcBlend: 1 + - _OutlineSrcBlendAlpha: 1 + - _OutlineSrcBlendAlphaFA: 0 + - _OutlineSrcBlendFA: 1 + - _OutlineStencilComp: 8 + - _OutlineStencilFail: 0 + - _OutlineStencilPass: 0 + - _OutlineStencilReadMask: 255 + - _OutlineStencilRef: 0 + - _OutlineStencilWriteMask: 255 + - _OutlineStencilZFail: 0 + - _OutlineVectorScale: 1 + - _OutlineVectorUVMode: 0 + - _OutlineVertexR2Width: 0 + - _OutlineWidth: 0.07 + - _OutlineWidthAffectedByViewDistance: 0 + - _OutlineZBias: 0 + - _OutlineZClip: 1 + - _OutlineZPostionInCamera: 0 + - _OutlineZTest: 2 + - _OutlineZWrite: 1 + - _OverallShadowColorPower: 1 + - _PADist: 0 + - _PASize: 0.5 + - _PASmooTrans: 1 + - _PSGLOTEX: 0 + - _PTexturePower: 1 + - _Parallax: 0.02 + - _ParallaxOffset: 0.5 + - _PointSpotlightIntensity: 1 + - _PresAdju: 1 + - _RELG: 1 + - _RQSO: 0 + - _ReduSha: 0.5 + - _RefMetallic: 0 + - _RefVal: 0 + - _Reflectance: 0.04 + - _ReflectionApplyTransparency: 1 + - _ReflectionBlendMode: 1 + - _ReflectionCubeEnableLighting: 1 + - _ReflectionCubeOverride: 0 + - _ReflectionIntensity: 0 + - _ReflectionNormalStrength: 1 + - _RimApplyTransparency: 1 + - _RimBackfaceMask: 1 + - _RimBlendMode: 1 + - _RimBlur: 0.6 + - _RimBorder: 0.5 + - _RimDirRange: 0 + - _RimDirStrength: 0 + - _RimEnableLighting: 1 + - _RimFresnelPower: 4 + - _RimIndirBlur: 0.029999971 + - _RimIndirBorder: 0.985 + - _RimIndirRange: 0 + - _RimLigInt: 1 + - _RimLightColorPower: 10 + - _RimLightInLight: 1 + - _RimLightSoftness: 1 + - _RimLightUnfill: 1.5 + - _RimMainStrength: 0 + - _RimNormalStrength: 1 + - _RimShadeBlur: 1 + - _RimShadeBorder: 0.5 + - _RimShadeFresnelPower: 1 + - _RimShadeNormalStrength: 1 + - _RimShadowMask: 0 + - _RimVRParallaxStrength: 0 + - _SPECIN: 1 + - _SPECMODE: 0 + - _STIL: 0 + - _Saturation: 1 + - _SelfLitHighContrast: 1 + - _SelfLitIntensity: 0 + - _SelfLitPower: 2 + - _SelfShadowAffectedByLightShadowStrength: 0 + - _SelfShadowHardness: 1 + - _SelfShadowRealTimeShadowColorPower: 1 + - _SelfShadowRealtimeShadowIntensity: 0 + - _SelfShadowShadowTAtViewDirection: 0 + - _SelfShadowThreshold: 0.93 + - _Shadow2ndBlur: 0.146 + - _Shadow2ndBorder: 0.212 + - _Shadow2ndNormalStrength: 1 + - _Shadow2ndReceive: 0 + - _Shadow3rdBlur: 0.1 + - _Shadow3rdBorder: 0.25 + - _Shadow3rdNormalStrength: 1 + - _Shadow3rdReceive: 0 + - _ShadowBlur: 0.1 + - _ShadowBlurMaskLOD: 0 + - _ShadowBorder: 0.249 + - _ShadowBorderMaskLOD: 0 + - _ShadowBorderRange: 0.01 + - _ShadowColorTexturePower: 0 + - _ShadowColorType: 0 + - _ShadowEnvStrength: 0 + - _ShadowFlatBlur: 1 + - _ShadowFlatBorder: 1 + - _ShadowHardness: 0 + - _ShadowMainStrength: 1 + - _ShadowMaskType: 0 + - _ShadowNormalStrength: 1 + - _ShadowPostAO: 0 + - _ShadowReceive: 0 + - _ShadowStrength: 0.2 + - _ShadowStrengthMaskLOD: 0 + - _ShadowTColorPower: 1 + - _ShadowTHardness: 1 + - _ShadowTIntensity: 1 + - _ShadowTLightThreshold: 50 + - _ShadowTShadowThreshold: 0 + - _ShifAnis: 0 + - _ShiftBackfaceUV: 0 + - _ShowInAmbientLightShadowIntensity: 1 + - _ShowInAmbientLightShadowThreshold: 0.4 + - _ShowNormal: 0 + - _SimTrans: 0 + - _SkinMatrixIndex: 0 + - _SmoothObjectNormal: 0 + - _Smoothness: 1 + - _SpecularBlur: 0 + - _SpecularBorder: 0.5 + - _SpecularNormalStrength: 1 + - _SpecularToon: 1 + - _SrcBlend: 1 + - _SrcBlendAlpha: 1 + - _SrcBlendAlphaFA: 0 + - _SrcBlendFA: 1 + - _StencilComp: 8 + - _StencilFail: 0 + - _StencilPass: 0 + - _StencilReadMask: 255 + - _StencilRef: 0 + - _StencilWriteMask: 255 + - _StencilZFail: 0 + - _StraWidt: 10 + - _SubpassCutoff: 0.5 + - _TEXMCOLINT: 1 + - _TRANSMODE: 0 + - _TessEdge: 10 + - _TessFactorMax: 3 + - _TessShrink: 0 + - _TessStrength: 0.5 + - _TessellationFar: 1 + - _TessellationNear: 1 + - _TessellationSmoothness: 0.5 + - _TessellationTransition: 0.8 + - _TexturePatternStyle: 0 + - _TrailSize: 1.5 + - _TransAffSha: 1 + - _TransparentMode: 0 + - _TransparentThreshold: 0 + - _TriPlaBlend: 4 + - _TriPlaTile: 1 + - _UDIMDiscardCompile: 0 + - _UDIMDiscardMode: 0 + - _UDIMDiscardRow0_0: 0 + - _UDIMDiscardRow0_1: 0 + - _UDIMDiscardRow0_2: 0 + - _UDIMDiscardRow0_3: 0 + - _UDIMDiscardRow1_0: 0 + - _UDIMDiscardRow1_1: 0 + - _UDIMDiscardRow1_2: 0 + - _UDIMDiscardRow1_3: 0 + - _UDIMDiscardRow2_0: 0 + - _UDIMDiscardRow2_1: 0 + - _UDIMDiscardRow2_2: 0 + - _UDIMDiscardRow2_3: 0 + - _UDIMDiscardRow3_0: 0 + - _UDIMDiscardRow3_1: 0 + - _UDIMDiscardRow3_2: 0 + - _UDIMDiscardRow3_3: 0 + - _UDIMDiscardUV: 0 + - _UVSet: 0 + - _UseAnisotropy: 0 + - _UseAudioLink: 0 + - _UseBacklight: 1 + - _UseBump2ndMap: 0 + - _UseBumpMap: 0 + - _UseClippingCanceller: 0 + - _UseDither: 0 + - _UseEmission: 0 + - _UseEmission2nd: 0 + - _UseGlitter: 0 + - _UseMain2ndTex: 0 + - _UseMain3rdTex: 0 + - _UseMatCap: 0 + - _UseMatCap2nd: 0 + - _UseOutline: 0 + - _UsePOM: 0 + - _UseParallax: 0 + - _UseReflection: 0 + - _UseRim: 1 + - _UseRimShade: 0 + - _UseSecondaryCutout: 0 + - _UseShadow: 1 + - _UseTLB: 0 + - _VertexColorBlueAffectOutlineWitdh: 0 + - _VertexColorGreenControlSelfShadowThreshold: 0 + - _VertexColorRedControlSmoothObjectNormal: 0 + - _VertexLightStrength: 0 + - _ZClip: 1 + - _ZTest: 4 + - _ZWrite: 1 + - _e2gai: 2 + - _e2gci: 2 + - _egai: 2 + - _egci: 2 + - _lilDirectionalLightStrength: 1 + - _lilShadowCasterBias: 0 + - _lilToonVersion: 42 + m_Colors: + - _AudioLinkDefaultValue: {r: 0, g: 0, b: 2, a: 0.75} + - _AudioLinkLocalMapParams: {r: 120, g: 1, b: 0, a: 0} + - _AudioLinkMask_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _AudioLinkStart: {r: 0, g: 0, b: 0, a: 0} + - _AudioLinkUVParams: {r: 0.25, g: 0, b: 0, a: 0.125} + - _AudioLinkVertexStart: {r: 0, g: 0, b: 0, a: 0} + - _AudioLinkVertexStrength: {r: 0, g: 0, b: 0, a: 1} + - _AudioLinkVertexUVParams: {r: 0.25, g: 0, b: 0, a: 0.125} + - _BackfaceColor: {r: 0, g: 0, b: 0, a: 0} + - _BacklightColor: {r: 0.85, g: 0.8, b: 0.7, a: 1} + - _BaseColor: {r: 1, g: 1, b: 1, a: 1} + - _Color: {r: 1, g: 1, b: 1, a: 1} + - _Color2nd: {r: 1, g: 1, b: 1, a: 1} + - _Color3rd: {r: 1, g: 1, b: 1, a: 1} + - _CustomLightDirection: {r: 0, g: 0, b: 10, a: 0} + - _DissolveColor: {r: 1, g: 1, b: 1, a: 1} + - _DissolveNoiseMask_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _DissolveParams: {r: 0, g: 0, b: 0.5, a: 0.1} + - _DissolvePos: {r: 0, g: 0, b: 0, a: 0} + - _DistanceFade: {r: 0.1, g: 0.01, b: 0, a: 0} + - _DistanceFadeColor: {r: 0, g: 0, b: 0, a: 1} + - _DistanceFadeRimColor: {r: 0, g: 0, b: 0, a: 0} + - _Emission2ndBlendMask_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _Emission2ndBlink: {r: 0, g: 0, b: 3.141593, a: 0} + - _Emission2ndColor: {r: 1, g: 1, b: 1, a: 1} + - _Emission2ndMap_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _EmissionBlendMask_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _EmissionBlink: {r: 0, g: 0, b: 3.141593, a: 0} + - _EmissionColor: {r: 1, g: 1, b: 1, a: 1} + - _EmissionMap_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _GlitterAtras: {r: 1, g: 1, b: 0, a: 0} + - _GlitterColor: {r: 1, g: 1, b: 1, a: 1} + - _GlitterParams1: {r: 256, g: 256, b: 0.16, a: 50} + - _GlitterParams2: {r: 0.25, g: 0, b: 0, a: 0} + - _GlossColor: {r: 1, g: 1, b: 1, a: 1} + - _Glow_Color: {r: 1, g: 1, b: 1, a: 1} + - _HighlightColor: {r: 0, g: 0.02643156, b: 1, a: 1} + - _Keys: {r: 0, g: 0, b: 0, a: 0} + - _LightDirectionOverride: {r: 0.001, g: 0.002, b: 0.001, a: 0} + - _Main2ndDissolveColor: {r: 1, g: 1, b: 1, a: 1} + - _Main2ndDissolveNoiseMask_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _Main2ndDissolveParams: {r: 0, g: 0, b: 0.5, a: 0.1} + - _Main2ndDissolvePos: {r: 0, g: 0, b: 0, a: 0} + - _Main2ndDistanceFade: {r: 0.1, g: 0.01, b: 0, a: 0} + - _Main2ndTexDecalAnimation: {r: 1, g: 1, b: 1, a: 30} + - _Main2ndTexDecalSubParam: {r: 1, g: 1, b: 0, a: 1} + - _Main2ndTex_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _Main3rdDissolveColor: {r: 1, g: 1, b: 1, a: 1} + - _Main3rdDissolveNoiseMask_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _Main3rdDissolveParams: {r: 0, g: 0, b: 0.5, a: 0.1} + - _Main3rdDissolvePos: {r: 0, g: 0, b: 0, a: 0} + - _Main3rdDistanceFade: {r: 0.1, g: 0.01, b: 0, a: 0} + - _Main3rdTexDecalAnimation: {r: 1, g: 1, b: 1, a: 30} + - _Main3rdTexDecalSubParam: {r: 1, g: 1, b: 0, a: 1} + - _Main3rdTex_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _MainColor: {r: 1, g: 1, b: 1, a: 1} + - _MainTexHSVG: {r: 0, g: 1, b: 1, a: 1} + - _MainTex_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _MatCap2ndBlendUV1: {r: 0, g: 0, b: 0, a: 0} + - _MatCap2ndColor: {r: 1, g: 1, b: 1, a: 1} + - _MatCapBlendUV1: {r: 0, g: 0, b: 0, a: 0} + - _MatCapColor: {r: 1, g: 1, b: 1, a: 1} + - _ObjPosi: {r: 0, g: 0, b: 0, a: 0} + - _ObjectForward: {r: 0, g: 0, b: 0, a: 0} + - _ObjectRight: {r: 0, g: 0, b: 0, a: 0} + - _OutResi: {r: 1, g: 1, b: 1, a: 1} + - _OutlineColor: {r: 0.5568628, g: 0.48235294, b: 0.5137255, a: 1} + - _OutlineLitColor: {r: 1, g: 0.28235295, b: 0, a: 0} + - _OutlineOffset: {r: 0, g: 0, b: 0, a: 1} + - _OutlineTexHSVG: {r: 0, g: 1, b: 1, a: 2} + - _OutlineTex_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _OverallShadowColor: {r: 0, g: 0, b: 0, a: 1} + - _PTCol: {r: 0, g: 0, b: 0, a: 1} + - _PrevPosition: {r: 0, g: 0, b: 0, a: 0} + - _ReflectionColor: {r: 1, g: 1, b: 1, a: 1} + - _ReflectionCubeColor: {r: 0, g: 0, b: 0, a: 1} + - _RimColor: {r: 0.34509623, g: 0.32548836, b: 0.39607662, a: 0.2} + - _RimIndirColor: {r: 0, g: 0, b: 0, a: 1} + - _RimLigPosi: {r: 1, g: 1, b: 1, a: 1} + - _RimLightColor: {r: 1, g: 1, b: 1, a: 1} + - _RimShadeColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} + - _SSAOColor: {r: 0, g: 0, b: 0, a: 0} + - _SelfLitColor: {r: 1, g: 1, b: 1, a: 1} + - _SelfShadowRealTimeShadowColor: {r: 1, g: 1, b: 1, a: 1} + - _Shadow2ndColor: {r: 0.4509804, g: 0.528278, b: 0.6509804, a: 1} + - _Shadow3rdColor: {r: 0, g: 0, b: 0, a: 0} + - _ShadowAOShift: {r: 1, g: 0, b: 1, a: 0} + - _ShadowAOShift2: {r: 1, g: 0, b: 1, a: 0} + - _ShadowBorderColor: {r: 0.18039216, g: 0.15294118, b: 0.15294118, a: 1} + - _ShadowColor: {r: 0.58708614, g: 0.6017861, b: 0.745283, a: 1} + - _ShadowTColor: {r: 1, g: 1, b: 1, a: 1} + - _XYZPosition: {r: 0, g: 0, b: 0, a: 0} + - _e2ga0: {r: 1, g: 0, b: 0, a: 0} + - _e2ga1: {r: 1, g: 0, b: 0, a: 1} + - _e2ga2: {r: 1, g: 0, b: 0, a: 0} + - _e2ga3: {r: 1, g: 0, b: 0, a: 0} + - _e2ga4: {r: 1, g: 0, b: 0, a: 0} + - _e2ga5: {r: 1, g: 0, b: 0, a: 0} + - _e2ga6: {r: 1, g: 0, b: 0, a: 0} + - _e2ga7: {r: 1, g: 0, b: 0, a: 0} + - _e2gc0: {r: 1, g: 1, b: 1, a: 0} + - _e2gc1: {r: 1, g: 1, b: 1, a: 1} + - _e2gc2: {r: 1, g: 1, b: 1, a: 0} + - _e2gc3: {r: 1, g: 1, b: 1, a: 0} + - _e2gc4: {r: 1, g: 1, b: 1, a: 0} + - _e2gc5: {r: 1, g: 1, b: 1, a: 0} + - _e2gc6: {r: 1, g: 1, b: 1, a: 0} + - _e2gc7: {r: 1, g: 1, b: 1, a: 0} + - _ega0: {r: 1, g: 0, b: 0, a: 0} + - _ega1: {r: 1, g: 0, b: 0, a: 1} + - _ega2: {r: 1, g: 0, b: 0, a: 0} + - _ega3: {r: 1, g: 0, b: 0, a: 0} + - _ega4: {r: 1, g: 0, b: 0, a: 0} + - _ega5: {r: 1, g: 0, b: 0, a: 0} + - _ega6: {r: 1, g: 0, b: 0, a: 0} + - _ega7: {r: 1, g: 0, b: 0, a: 0} + - _egc0: {r: 1, g: 1, b: 1, a: 0} + - _egc1: {r: 1, g: 1, b: 1, a: 1} + - _egc2: {r: 1, g: 1, b: 1, a: 0} + - _egc3: {r: 1, g: 1, b: 1, a: 0} + - _egc4: {r: 1, g: 1, b: 1, a: 0} + - _egc5: {r: 1, g: 1, b: 1, a: 0} + - _egc6: {r: 1, g: 1, b: 1, a: 0} + - _egc7: {r: 1, g: 1, b: 1, a: 0} + m_BuildTextureStacks: [] + m_AllowLocking: 1 diff --git a/Assets/04_Models/Characters/Fariy/Materials/Cloth/Alistia_Cloth_1_Blue.mat.meta b/Assets/04_Models/Characters/Fariy/Materials/Cloth/Alistia_Cloth_1_Blue.mat.meta new file mode 100644 index 00000000..25cef9ea --- /dev/null +++ b/Assets/04_Models/Characters/Fariy/Materials/Cloth/Alistia_Cloth_1_Blue.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: bcbfd5c6863e38343b245e267d25bc9a +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/04_Models/Characters/Fariy/Materials/Cloth/Alistia_Cloth_1_Blue_Lace.mat b/Assets/04_Models/Characters/Fariy/Materials/Cloth/Alistia_Cloth_1_Blue_Lace.mat new file mode 100644 index 00000000..b9a9a023 --- /dev/null +++ b/Assets/04_Models/Characters/Fariy/Materials/Cloth/Alistia_Cloth_1_Blue_Lace.mat @@ -0,0 +1,1028 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 8 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: Alistia_Cloth_1_Blue_Lace + m_Shader: {fileID: 4800000, guid: 6459b2db96a08ca41b0f9b39dc7ad59e, type: 3} + m_Parent: {fileID: 0} + m_ModifiedSerializedProperties: 0 + m_ValidKeywords: + - N_F_DDMD_ON + - N_F_EAL_ON + - N_F_O_ON + - N_F_RDC_ON + - N_F_RELGI_ON + - N_F_SS_ON + - N_F_TRANSAFFSHA_ON + - N_F_TRANS_ON + - _UVSET_UV0 + m_InvalidKeywords: [] + m_LightmapFlags: 0 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: 3000 + stringTagMap: + RenderType: Transparent + disabledShaderPasses: [] + m_LockedProperties: + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _AlphaMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _AnisotropyScaleMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _AnisotropyShiftNoiseMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _AnisotropyTangentMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _AudioLinkLocalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _AudioLinkMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BacklightColorTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BaseColorMap: + m_Texture: {fileID: 2800000, guid: 083e7f8c110fa364c817bb3c34f9fdeb, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BaseMap: + m_Texture: {fileID: 2800000, guid: 083e7f8c110fa364c817bb3c34f9fdeb, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Bump2ndMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Bump2ndScaleMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DissolveMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DissolveNoiseMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DitherTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Emission2ndBlendMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Emission2ndGradTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Emission2ndMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionBlendMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionGradTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _FReflection: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _GlitterColorTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _GlitterShapeTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _GlossTexture: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MCap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MCapMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main2ndBlendMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main2ndDissolveMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main2ndDissolveNoiseMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main2ndTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main3rdBlendMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main3rdDissolveMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main3rdDissolveNoiseMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main3rdTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainColorAdjustMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainGradationTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 2800000, guid: 083e7f8c110fa364c817bb3c34f9fdeb, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MaskGloss: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MaskReflection: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MaskSelfLit: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MaskTransparency: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MatCap2ndBlendMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MatCap2ndBumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MatCap2ndTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MatCapBlendMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MatCapBumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MatCapTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _NormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OutlineTex: + m_Texture: {fileID: 2800000, guid: 083e7f8c110fa364c817bb3c34f9fdeb, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OutlineVectorTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OutlineWidthControl: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OutlineWidthMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _PTexture: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ReflectionColorTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ReflectionCubeTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _RimColorTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _RimShadeMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _SecondaryCutout: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Shadow2ndColorTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Shadow3rdColorTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ShadowBlurMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ShadowBorderMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ShadowColorTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ShadowColorTexture: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ShadowStrengthMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ShadowT: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _SmoothnessTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Ints: [] + m_Floats: + - _AAS: 0.0001 + - _AAStrength: 1 + - _AlpToCov: 0 + - _AlphaBaseCutout: 1 + - _AlphaBoostFA: 10 + - _AlphaMaskMode: 0 + - _AlphaMaskScale: 1 + - _AlphaMaskValue: 0.03 + - _AlphaToMask: 0 + - _Anisotropy2MatCap: 0 + - _Anisotropy2MatCap2nd: 0 + - _Anisotropy2Reflection: 0 + - _Anisotropy2ndBitangentWidth: 1 + - _Anisotropy2ndShift: 0 + - _Anisotropy2ndShiftNoiseScale: 0 + - _Anisotropy2ndSpecularStrength: 0 + - _Anisotropy2ndTangentWidth: 1 + - _AnisotropyBitangentWidth: 1 + - _AnisotropyScale: 1 + - _AnisotropyShift: 0 + - _AnisotropyShiftNoiseScale: 0 + - _AnisotropySpecularStrength: 1 + - _AnisotropyTangentWidth: 1 + - _ApplyReflection: 0 + - _ApplySpecular: 1 + - _ApplySpecularFA: 1 + - _AsOverlay: 0 + - _AsUnlit: 0 + - _AudioLink2Emission: 0 + - _AudioLink2Emission2nd: 0 + - _AudioLink2Emission2ndGrad: 0 + - _AudioLink2EmissionGrad: 0 + - _AudioLink2Main2nd: 0 + - _AudioLink2Main3rd: 0 + - _AudioLink2Vertex: 0 + - _AudioLinkAsLocal: 0 + - _AudioLinkMask_UVMode: 0 + - _AudioLinkUVMode: 1 + - _AudioLinkVertexUVMode: 1 + - _BackfaceForceShadow: 0 + - _BacklightBackfaceMask: 1 + - _BacklightBlur: 0.05 + - _BacklightBorder: 0.35 + - _BacklightDirectivity: 5 + - _BacklightMainStrength: 0 + - _BacklightNormalStrength: 1 + - _BacklightReceiveShadow: 1 + - _BacklightViewStrength: 1 + - _BeforeExposureLimit: 10000 + - _BitKey0: 0 + - _BitKey1: 0 + - _BitKey10: 0 + - _BitKey11: 0 + - _BitKey12: 0 + - _BitKey13: 0 + - _BitKey14: 0 + - _BitKey15: 0 + - _BitKey16: 0 + - _BitKey17: 0 + - _BitKey18: 0 + - _BitKey19: 0 + - _BitKey2: 0 + - _BitKey20: 0 + - _BitKey21: 0 + - _BitKey22: 0 + - _BitKey23: 0 + - _BitKey24: 0 + - _BitKey25: 0 + - _BitKey26: 0 + - _BitKey27: 0 + - _BitKey28: 0 + - _BitKey29: 0 + - _BitKey3: 0 + - _BitKey30: 0 + - _BitKey31: 0 + - _BitKey4: 0 + - _BitKey5: 0 + - _BitKey6: 0 + - _BitKey7: 0 + - _BitKey8: 0 + - _BitKey9: 0 + - _BleModDest: 10 + - _BleModSour: 5 + - _BlendOp: 0 + - _BlendOpAlpha: 0 + - _BlendOpAlphaFA: 4 + - _BlendOpFA: 4 + - _Bump2ndMap_UVMode: 0 + - _Bump2ndScale: 1 + - _BumpScale: 1 + - _ClipAdju: 0 + - _ColorMask: 15 + - _Compa: 4 + - _ComputeMeshIndex: 0 + - _Cull: 0 + - _Culling: 2 + - _CustomLightDirectionFollowObjectRotation: 0 + - _CustomLightDirectionIntensity: 0 + - _Cutoff: 0 + - _Cutout: 0.5 + - _DepthThreshold: 900 + - _DirectionalLightIntensity: 1 + - _DissolveNoiseStrength: 0.1 + - _DistanceFadeMode: 0 + - _DistanceFadeRimFresnelPower: 5 + - _DitherMaxValue: 255 + - _DoubleSidedOutline: 1 + - _DstBlend: 10 + - _DstBlendAlpha: 10 + - _DstBlendAlphaFA: 1 + - _DstBlendFA: 1 + - _DummyProperty: 0 + - _DynamicNoisyOutline: 0 + - _Emission2ndBlend: 1 + - _Emission2ndBlendMode: 1 + - _Emission2ndFluorescence: 0 + - _Emission2ndGradSpeed: 1 + - _Emission2ndMainStrength: 0 + - _Emission2ndMap_UVMode: 0 + - _Emission2ndParallaxDepth: 0 + - _Emission2ndUseGrad: 0 + - _EmissionBlend: 1 + - _EmissionBlendMode: 1 + - _EmissionFluorescence: 0 + - _EmissionGradSpeed: 1 + - _EmissionMainStrength: 0 + - _EmissionMap_UVMode: 0 + - _EmissionParallaxDepth: 0 + - _EmissionUseGrad: 0 + - _EnvironmentalLightingIntensity: 1 + - _FarDistanceMaxWidth: 10 + - _FlipNormal: 0 + - _GIFlatShade: 0 + - _GIShadeThreshold: 0 + - _GSAAStrength: 0 + - _GlitterAngleRandomize: 0 + - _GlitterApplyShape: 0 + - _GlitterApplyTransparency: 1 + - _GlitterBackfaceMask: 0 + - _GlitterColorTex_UVMode: 0 + - _GlitterEnableLighting: 1 + - _GlitterMainStrength: 0 + - _GlitterNormalStrength: 1 + - _GlitterPostContrast: 1 + - _GlitterScaleRandomize: 0 + - _GlitterSensitivity: 0.25 + - _GlitterShadowMask: 0 + - _GlitterUVMode: 0 + - _GlitterVRParallaxStrength: 0 + - _GlossColorPower: 10 + - _GlossIntensity: 1 + - _GlossSoftness: 0 + - _GlossTextureFollowLight: 0 + - _GlossTextureFollowObjectRotation: 0 + - _GlossTextureRotate: 0 + - _GlossTextureSoftness: 0 + - _Glossiness: 0.6 + - _Glow_Edge_Width: 1 + - _HighlightColorPower: 4 + - _IDMask1: 0 + - _IDMask2: 0 + - _IDMask3: 0 + - _IDMask4: 0 + - _IDMask5: 0 + - _IDMask6: 0 + - _IDMask7: 0 + - _IDMask8: 0 + - _IDMaskCompile: 0 + - _IDMaskControlsDissolve: 0 + - _IDMaskFrom: 8 + - _IDMaskIndex1: 0 + - _IDMaskIndex2: 0 + - _IDMaskIndex3: 0 + - _IDMaskIndex4: 0 + - _IDMaskIndex5: 0 + - _IDMaskIndex6: 0 + - _IDMaskIndex7: 0 + - _IDMaskIndex8: 0 + - _IDMaskIsBitmap: 0 + - _IDMaskPrior1: 0 + - _IDMaskPrior2: 0 + - _IDMaskPrior3: 0 + - _IDMaskPrior4: 0 + - _IDMaskPrior5: 0 + - _IDMaskPrior6: 0 + - _IDMaskPrior7: 0 + - _IDMaskPrior8: 0 + - _IgnoreEncryption: 0 + - _Invisible: 0 + - _LLI_Max: 1 + - _LLI_Min: 0 + - _LigIgnoYNorDir: 0 + - _LightAffectOutlineColor: 0 + - _LightAffectRimLightColor: 0 + - _LightAffectShadow: 0 + - _LightFalloffAffectShadowT: 0 + - _LightFalloffSoftness: 1 + - _LightIntensity: 1 + - _LightMaxLimit: 1 + - _LightMinLimit: 0.05 + - _MCIALO: 0 + - _MCapIntensity: 1 + - _MVCOL: 0 + - _MaiColPo: 0.8 + - _Main2ndDissolveNoiseStrength: 0.1 + - _Main2ndEnableLighting: 1 + - _Main2ndTexAlphaMode: 0 + - _Main2ndTexAngle: 0 + - _Main2ndTexBlendMode: 0 + - _Main2ndTexIsDecal: 0 + - _Main2ndTexIsLeftOnly: 0 + - _Main2ndTexIsMSDF: 0 + - _Main2ndTexIsRightOnly: 0 + - _Main2ndTexShouldCopy: 0 + - _Main2ndTexShouldFlipCopy: 0 + - _Main2ndTexShouldFlipMirror: 0 + - _Main2ndTex_Cull: 0 + - _Main2ndTex_UVMode: 0 + - _Main3rdDissolveNoiseStrength: 0.1 + - _Main3rdEnableLighting: 1 + - _Main3rdTexAlphaMode: 0 + - _Main3rdTexAngle: 0 + - _Main3rdTexBlendMode: 0 + - _Main3rdTexIsDecal: 0 + - _Main3rdTexIsLeftOnly: 0 + - _Main3rdTexIsMSDF: 0 + - _Main3rdTexIsRightOnly: 0 + - _Main3rdTexShouldCopy: 0 + - _Main3rdTexShouldFlipCopy: 0 + - _Main3rdTexShouldFlipMirror: 0 + - _Main3rdTex_Cull: 0 + - _Main3rdTex_UVMode: 0 + - _MainGradationStrength: 0 + - _MatCap2ndApplyTransparency: 1 + - _MatCap2ndBackfaceMask: 0 + - _MatCap2ndBlend: 1 + - _MatCap2ndBlendMode: 1 + - _MatCap2ndBumpScale: 1 + - _MatCap2ndCustomNormal: 0 + - _MatCap2ndEnableLighting: 1 + - _MatCap2ndLod: 0 + - _MatCap2ndMainStrength: 0 + - _MatCap2ndNormalStrength: 1 + - _MatCap2ndPerspective: 1 + - _MatCap2ndShadowMask: 0 + - _MatCap2ndVRParallaxStrength: 1 + - _MatCap2ndZRotCancel: 1 + - _MatCapApplyTransparency: 1 + - _MatCapBackfaceMask: 0 + - _MatCapBlend: 0 + - _MatCapBlendMode: 1 + - _MatCapBumpScale: 1 + - _MatCapCustomNormal: 0 + - _MatCapEnableLighting: 1 + - _MatCapLod: 0 + - _MatCapMainStrength: 0 + - _MatCapNormalStrength: 1 + - _MatCapPerspective: 1 + - _MatCapShadowMask: 0.75 + - _MatCapVRParallaxStrength: 1 + - _MatCapZRotCancel: 1 + - _MaxFadDistance: 2 + - _Metallic: 0 + - _MinFadDistance: 0 + - _MixMainTexToOutline: 0 + - _MonochromeLighting: 0 + - _N_F_ANIS: 0 + - _N_F_CA: 0 + - _N_F_CLD: 0 + - _N_F_CO: 0 + - _N_F_COEDGL: 0 + - _N_F_DCS: 0 + - _N_F_DDMD: 1 + - _N_F_EAL: 1 + - _N_F_ESSAO: 0 + - _N_F_FR: 0 + - _N_F_GLO: 0 + - _N_F_GLOT: 0 + - _N_F_HDLS: 0 + - _N_F_HPSS: 0 + - _N_F_LLI: 0 + - _N_F_MC: 0 + - _N_F_MSSOLTFO: 0 + - _N_F_NFD: 0 + - _N_F_NLASOBF: 0 + - _N_F_NM: 0 + - _N_F_O: 1 + - _N_F_OFLMB: 0 + - _N_F_PA: 0 + - _N_F_PT: 0 + - _N_F_R: 0 + - _N_F_RDC: 1 + - _N_F_RL: 0 + - _N_F_RLIS: 0 + - _N_F_SCO: 0 + - _N_F_SCT: 0 + - _N_F_SE: 0 + - _N_F_SL: 0 + - _N_F_SLMM: 0 + - _N_F_SON: 0 + - _N_F_SS: 1 + - _N_F_ST: 0 + - _N_F_STIAL: 0 + - _N_F_STIS: 0 + - _N_F_STSDFM: 0 + - _N_F_TP: 0 + - _NoiTexAffStraWidt: 0 + - _NoisTexInten: 1 + - _NoiseSize: 100 + - _NoisyOutlineIntensity: 0 + - _NorMapAsDis: 0 + - _NormalMapIntensity: 1 + - _ObjePosiZCS: 0 + - _OffsetFactor: 0 + - _OffsetUnits: 0 + - _Opacity: 1 + - _Oper: 0 + - _OutStenPass: 0 + - _OutZTest: 4 + - _OutZWrite: 1 + - _OutlineAlphaToMask: 0 + - _OutlineBlendOp: 0 + - _OutlineBlendOpAlpha: 0 + - _OutlineBlendOpAlphaFA: 4 + - _OutlineBlendOpFA: 4 + - _OutlineColorMask: 15 + - _OutlineCull: 1 + - _OutlineDeleteMesh: 0 + - _OutlineDisableInVR: 0 + - _OutlineDstBlend: 10 + - _OutlineDstBlendAlpha: 10 + - _OutlineDstBlendAlphaFA: 1 + - _OutlineDstBlendFA: 1 + - _OutlineEnableLighting: 1 + - _OutlineExtrudeMethod: 0 + - _OutlineFixWidth: 0 + - _OutlineLitApplyTex: 0 + - _OutlineLitOffset: -8 + - _OutlineLitScale: 10 + - _OutlineLitShadowReceive: 0 + - _OutlineOffsetFactor: 0 + - _OutlineOffsetUnits: 0 + - _OutlineSrcBlend: 5 + - _OutlineSrcBlendAlpha: 1 + - _OutlineSrcBlendAlphaFA: 0 + - _OutlineSrcBlendFA: 1 + - _OutlineStencilComp: 8 + - _OutlineStencilFail: 0 + - _OutlineStencilPass: 0 + - _OutlineStencilReadMask: 255 + - _OutlineStencilRef: 0 + - _OutlineStencilWriteMask: 255 + - _OutlineStencilZFail: 0 + - _OutlineVectorScale: 1 + - _OutlineVectorUVMode: 0 + - _OutlineVertexR2Width: 0 + - _OutlineWidth: 0.02 + - _OutlineWidthAffectedByViewDistance: 0 + - _OutlineZBias: 0 + - _OutlineZClip: 1 + - _OutlineZPostionInCamera: 0 + - _OutlineZTest: 2 + - _OutlineZWrite: 1 + - _OverallShadowColorPower: 1 + - _PADist: 0 + - _PASize: 0.5 + - _PASmooTrans: 1 + - _PSGLOTEX: 0 + - _PTexturePower: 1 + - _Parallax: 0.02 + - _ParallaxOffset: 0.5 + - _PointSpotlightIntensity: 1 + - _PreAlphaToMask: 0 + - _PreBlendOp: 0 + - _PreBlendOpAlpha: 0 + - _PreBlendOpAlphaFA: 4 + - _PreBlendOpFA: 4 + - _PreColorMask: 15 + - _PreCull: 2 + - _PreCutoff: 0.5 + - _PreDstBlend: 10 + - _PreDstBlendAlpha: 10 + - _PreDstBlendAlphaFA: 1 + - _PreDstBlendFA: 1 + - _PreOffsetFactor: 0 + - _PreOffsetUnits: 0 + - _PreOutType: 0 + - _PreSrcBlend: 1 + - _PreSrcBlendAlpha: 1 + - _PreSrcBlendAlphaFA: 0 + - _PreSrcBlendFA: 1 + - _PreStencilComp: 8 + - _PreStencilFail: 0 + - _PreStencilPass: 0 + - _PreStencilReadMask: 255 + - _PreStencilRef: 0 + - _PreStencilWriteMask: 255 + - _PreStencilZFail: 0 + - _PreZClip: 1 + - _PreZTest: 4 + - _PreZWrite: 1 + - _PresAdju: 1 + - _RELG: 1 + - _RQSO: 0 + - _ReduSha: 0.5 + - _RefMetallic: 0 + - _RefVal: 0 + - _Reflectance: 0.04 + - _ReflectionApplyTransparency: 1 + - _ReflectionBlendMode: 1 + - _ReflectionCubeEnableLighting: 1 + - _ReflectionCubeOverride: 0 + - _ReflectionIntensity: 0 + - _ReflectionNormalStrength: 1 + - _RimApplyTransparency: 1 + - _RimBackfaceMask: 0 + - _RimBlendMode: 1 + - _RimBlur: 0.1 + - _RimBorder: 0.873 + - _RimDirRange: 0 + - _RimDirStrength: 0 + - _RimEnableLighting: 1 + - _RimFresnelPower: 1 + - _RimIndirBlur: 0.1 + - _RimIndirBorder: 0.5 + - _RimIndirRange: 0 + - _RimLigInt: 1 + - _RimLightColorPower: 10 + - _RimLightInLight: 1 + - _RimLightSoftness: 1 + - _RimLightUnfill: 1.5 + - _RimMainStrength: 0 + - _RimNormalStrength: 1 + - _RimShadeBlur: 1 + - _RimShadeBorder: 0.5 + - _RimShadeFresnelPower: 1 + - _RimShadeNormalStrength: 1 + - _RimShadowMask: 1 + - _RimVRParallaxStrength: 1 + - _SPECIN: 1 + - _SPECMODE: 0 + - _STIL: 0 + - _Saturation: 1 + - _SelfLitHighContrast: 1 + - _SelfLitIntensity: 0 + - _SelfLitPower: 2 + - _SelfShadowAffectedByLightShadowStrength: 0 + - _SelfShadowHardness: 1 + - _SelfShadowRealTimeShadowColorPower: 1 + - _SelfShadowRealtimeShadowIntensity: 0 + - _SelfShadowShadowTAtViewDirection: 0 + - _SelfShadowThreshold: 0.93 + - _Shadow2ndBlur: 0.175 + - _Shadow2ndBorder: 0.132 + - _Shadow2ndNormalStrength: 1 + - _Shadow2ndReceive: 0 + - _Shadow3rdBlur: 0.1 + - _Shadow3rdBorder: 0.25 + - _Shadow3rdNormalStrength: 1 + - _Shadow3rdReceive: 0 + - _ShadowBlur: 0.17 + - _ShadowBlurMaskLOD: 0 + - _ShadowBorder: 0.272 + - _ShadowBorderMaskLOD: 0 + - _ShadowBorderRange: 0.015 + - _ShadowColorTexturePower: 0 + - _ShadowColorType: 0 + - _ShadowEnvStrength: 0 + - _ShadowFlatBlur: 1 + - _ShadowFlatBorder: 1 + - _ShadowHardness: 0 + - _ShadowMainStrength: 0 + - _ShadowMaskType: 0 + - _ShadowNormalStrength: 1 + - _ShadowPostAO: 0 + - _ShadowReceive: 1 + - _ShadowStrength: 1 + - _ShadowStrengthMaskLOD: 0 + - _ShadowTColorPower: 1 + - _ShadowTHardness: 1 + - _ShadowTIntensity: 1 + - _ShadowTLightThreshold: 50 + - _ShadowTShadowThreshold: 0 + - _ShifAnis: 0 + - _ShiftBackfaceUV: 0 + - _ShowInAmbientLightShadowIntensity: 1 + - _ShowInAmbientLightShadowThreshold: 0.4 + - _ShowNormal: 0 + - _SimTrans: 0 + - _SkinMatrixIndex: 0 + - _SmoothObjectNormal: 0 + - _Smoothness: 1 + - _SpecularBlur: 0 + - _SpecularBorder: 0.5 + - _SpecularNormalStrength: 1 + - _SpecularToon: 1 + - _SrcBlend: 1 + - _SrcBlendAlpha: 1 + - _SrcBlendAlphaFA: 0 + - _SrcBlendFA: 1 + - _StencilComp: 8 + - _StencilFail: 0 + - _StencilPass: 0 + - _StencilReadMask: 255 + - _StencilRef: 0 + - _StencilWriteMask: 255 + - _StencilZFail: 0 + - _StraWidt: 10 + - _SubpassCutoff: 0.5 + - _TEXMCOLINT: 1 + - _TRANSMODE: 1 + - _TessEdge: 10 + - _TessFactorMax: 3 + - _TessShrink: 0 + - _TessStrength: 0.5 + - _TessellationFar: 1 + - _TessellationNear: 1 + - _TessellationSmoothness: 0.5 + - _TessellationTransition: 0.8 + - _TexturePatternStyle: 0 + - _TrailSize: 1.5 + - _TransAffSha: 1 + - _TransparentMode: 0 + - _TransparentThreshold: 0 + - _TriPlaBlend: 4 + - _TriPlaTile: 1 + - _UDIMDiscardCompile: 0 + - _UDIMDiscardMode: 0 + - _UDIMDiscardRow0_0: 0 + - _UDIMDiscardRow0_1: 0 + - _UDIMDiscardRow0_2: 0 + - _UDIMDiscardRow0_3: 0 + - _UDIMDiscardRow1_0: 0 + - _UDIMDiscardRow1_1: 0 + - _UDIMDiscardRow1_2: 0 + - _UDIMDiscardRow1_3: 0 + - _UDIMDiscardRow2_0: 0 + - _UDIMDiscardRow2_1: 0 + - _UDIMDiscardRow2_2: 0 + - _UDIMDiscardRow2_3: 0 + - _UDIMDiscardRow3_0: 0 + - _UDIMDiscardRow3_1: 0 + - _UDIMDiscardRow3_2: 0 + - _UDIMDiscardRow3_3: 0 + - _UDIMDiscardUV: 0 + - _UVSet: 0 + - _UseAnisotropy: 0 + - _UseAudioLink: 0 + - _UseBacklight: 0 + - _UseBump2ndMap: 0 + - _UseBumpMap: 0 + - _UseClippingCanceller: 0 + - _UseDither: 0 + - _UseEmission: 0 + - _UseEmission2nd: 0 + - _UseGlitter: 0 + - _UseMain2ndTex: 0 + - _UseMain3rdTex: 0 + - _UseMatCap: 0 + - _UseMatCap2nd: 0 + - _UseOutline: 0 + - _UsePOM: 0 + - _UseParallax: 0 + - _UseReflection: 0 + - _UseRim: 0 + - _UseRimShade: 0 + - _UseSecondaryCutout: 0 + - _UseShadow: 1 + - _UseTLB: 0 + - _VertexColorBlueAffectOutlineWitdh: 0 + - _VertexColorGreenControlSelfShadowThreshold: 0 + - _VertexColorRedControlSmoothObjectNormal: 0 + - _VertexLightStrength: 0 + - _ZClip: 1 + - _ZTest: 4 + - _ZWrite: 1 + - _e2gai: 2 + - _e2gci: 2 + - _egai: 2 + - _egci: 2 + - _lilDirectionalLightStrength: 1 + - _lilShadowCasterBias: 0 + - _lilToonVersion: 42 + m_Colors: + - _AudioLinkDefaultValue: {r: 0, g: 0, b: 2, a: 0.75} + - _AudioLinkLocalMapParams: {r: 120, g: 1, b: 0, a: 0} + - _AudioLinkMask_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _AudioLinkStart: {r: 0, g: 0, b: 0, a: 0} + - _AudioLinkUVParams: {r: 0.25, g: 0, b: 0, a: 0.125} + - _AudioLinkVertexStart: {r: 0, g: 0, b: 0, a: 0} + - _AudioLinkVertexStrength: {r: 0, g: 0, b: 0, a: 1} + - _AudioLinkVertexUVParams: {r: 0.25, g: 0, b: 0, a: 0.125} + - _BackfaceColor: {r: 0, g: 0, b: 0, a: 0} + - _BacklightColor: {r: 0.85, g: 0.8, b: 0.7, a: 1} + - _BaseColor: {r: 1, g: 1, b: 1, a: 1} + - _Color: {r: 1, g: 1, b: 1, a: 1} + - _Color2nd: {r: 1, g: 1, b: 1, a: 1} + - _Color3rd: {r: 1, g: 1, b: 1, a: 1} + - _CustomLightDirection: {r: 0, g: 0, b: 10, a: 0} + - _DissolveColor: {r: 1, g: 1, b: 1, a: 1} + - _DissolveNoiseMask_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _DissolveParams: {r: 0, g: 0, b: 0.5, a: 0.1} + - _DissolvePos: {r: 0, g: 0, b: 0, a: 0} + - _DistanceFade: {r: 0.1, g: 0.01, b: 0, a: 0} + - _DistanceFadeColor: {r: 0, g: 0, b: 0, a: 1} + - _DistanceFadeRimColor: {r: 0, g: 0, b: 0, a: 0} + - _Emission2ndBlendMask_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _Emission2ndBlink: {r: 0, g: 0, b: 3.141593, a: 0} + - _Emission2ndColor: {r: 1, g: 1, b: 1, a: 1} + - _Emission2ndMap_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _EmissionBlendMask_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _EmissionBlink: {r: 0, g: 0, b: 3.141593, a: 0} + - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} + - _EmissionMap_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _GlitterAtras: {r: 1, g: 1, b: 0, a: 0} + - _GlitterColor: {r: 1, g: 1, b: 1, a: 1} + - _GlitterParams1: {r: 256, g: 256, b: 0.16, a: 50} + - _GlitterParams2: {r: 0.25, g: 0, b: 0, a: 0} + - _GlossColor: {r: 1, g: 1, b: 1, a: 1} + - _Glow_Color: {r: 1, g: 1, b: 1, a: 1} + - _HighlightColor: {r: 0, g: 0.022338867, b: 1, a: 1} + - _Keys: {r: 0, g: 0, b: 0, a: 0} + - _LightDirectionOverride: {r: 0.001, g: 0.002, b: 0.001, a: 0} + - _Main2ndDissolveColor: {r: 1, g: 1, b: 1, a: 1} + - _Main2ndDissolveNoiseMask_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _Main2ndDissolveParams: {r: 0, g: 0, b: 0.5, a: 0.1} + - _Main2ndDissolvePos: {r: 0, g: 0, b: 0, a: 0} + - _Main2ndDistanceFade: {r: 0.1, g: 0.01, b: 0, a: 0} + - _Main2ndTexDecalAnimation: {r: 1, g: 1, b: 1, a: 30} + - _Main2ndTexDecalSubParam: {r: 1, g: 1, b: 0, a: 1} + - _Main2ndTex_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _Main3rdDissolveColor: {r: 1, g: 1, b: 1, a: 1} + - _Main3rdDissolveNoiseMask_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _Main3rdDissolveParams: {r: 0, g: 0, b: 0.5, a: 0.1} + - _Main3rdDissolvePos: {r: 0, g: 0, b: 0, a: 0} + - _Main3rdDistanceFade: {r: 0.1, g: 0.01, b: 0, a: 0} + - _Main3rdTexDecalAnimation: {r: 1, g: 1, b: 1, a: 30} + - _Main3rdTexDecalSubParam: {r: 1, g: 1, b: 0, a: 1} + - _Main3rdTex_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _MainColor: {r: 1, g: 1, b: 1, a: 1} + - _MainTexHSVG: {r: 0, g: 1, b: 1, a: 1} + - _MainTex_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _MatCap2ndBlendUV1: {r: 0, g: 0, b: 0, a: 0} + - _MatCap2ndColor: {r: 1, g: 1, b: 1, a: 1} + - _MatCapBlendUV1: {r: 0, g: 0, b: 0, a: 0} + - _MatCapColor: {r: 1, g: 1, b: 1, a: 0.7} + - _ObjPosi: {r: 0, g: 0, b: 0, a: 0} + - _ObjectForward: {r: 0, g: 0, b: 0, a: 0} + - _ObjectRight: {r: 0, g: 0, b: 0, a: 0} + - _OutResi: {r: 1, g: 1, b: 1, a: 1} + - _OutlineColor: {r: 0.7276166, g: 0.73921245, b: 0.7830189, a: 1} + - _OutlineLitColor: {r: 1, g: 0.19999996, b: 0, a: 0} + - _OutlineOffset: {r: 0, g: 0, b: 0, a: 1} + - _OutlineTexHSVG: {r: 0, g: 1, b: 1, a: 1} + - _OutlineTex_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _OverallShadowColor: {r: 0, g: 0, b: 0, a: 1} + - _PTCol: {r: 0, g: 0, b: 0, a: 1} + - _PreColor: {r: 1, g: 1, b: 1, a: 1} + - _PrevPosition: {r: 0, g: 0, b: 0, a: 0} + - _ReflectionColor: {r: 1, g: 1, b: 1, a: 1} + - _ReflectionCubeColor: {r: 0, g: 0, b: 0, a: 1} + - _RimColor: {r: 0.5, g: 0.46249998, b: 0.42499956, a: 0.262} + - _RimIndirColor: {r: 1, g: 1, b: 1, a: 1} + - _RimLigPosi: {r: 1, g: 1, b: 1, a: 1} + - _RimLightColor: {r: 1, g: 1, b: 1, a: 1} + - _RimShadeColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} + - _SSAOColor: {r: 0, g: 0, b: 0, a: 0} + - _SelfLitColor: {r: 1, g: 1, b: 1, a: 1} + - _SelfShadowRealTimeShadowColor: {r: 1, g: 1, b: 1, a: 1} + - _Shadow2ndColor: {r: 0.85882354, g: 0.87771285, b: 0.9137255, a: 1} + - _Shadow3rdColor: {r: 0, g: 0, b: 0, a: 0} + - _ShadowAOShift: {r: 1, g: 0, b: 1, a: 0} + - _ShadowAOShift2: {r: 1, g: 0, b: 1, a: 0} + - _ShadowBorderColor: {r: 0.8666667, g: 0.8901961, b: 0.9137255, a: 1} + - _ShadowColor: {r: 0.8666667, g: 0.888508, b: 0.9137255, a: 1} + - _ShadowTColor: {r: 1, g: 1, b: 1, a: 1} + - _XYZPosition: {r: 0, g: 0, b: 0, a: 0} + - _e2ga0: {r: 1, g: 0, b: 0, a: 0} + - _e2ga1: {r: 1, g: 0, b: 0, a: 1} + - _e2ga2: {r: 1, g: 0, b: 0, a: 0} + - _e2ga3: {r: 1, g: 0, b: 0, a: 0} + - _e2ga4: {r: 1, g: 0, b: 0, a: 0} + - _e2ga5: {r: 1, g: 0, b: 0, a: 0} + - _e2ga6: {r: 1, g: 0, b: 0, a: 0} + - _e2ga7: {r: 1, g: 0, b: 0, a: 0} + - _e2gc0: {r: 1, g: 1, b: 1, a: 0} + - _e2gc1: {r: 1, g: 1, b: 1, a: 1} + - _e2gc2: {r: 1, g: 1, b: 1, a: 0} + - _e2gc3: {r: 1, g: 1, b: 1, a: 0} + - _e2gc4: {r: 1, g: 1, b: 1, a: 0} + - _e2gc5: {r: 1, g: 1, b: 1, a: 0} + - _e2gc6: {r: 1, g: 1, b: 1, a: 0} + - _e2gc7: {r: 1, g: 1, b: 1, a: 0} + - _ega0: {r: 1, g: 0, b: 0, a: 0} + - _ega1: {r: 1, g: 0, b: 0, a: 1} + - _ega2: {r: 1, g: 0, b: 0, a: 0} + - _ega3: {r: 1, g: 0, b: 0, a: 0} + - _ega4: {r: 1, g: 0, b: 0, a: 0} + - _ega5: {r: 1, g: 0, b: 0, a: 0} + - _ega6: {r: 1, g: 0, b: 0, a: 0} + - _ega7: {r: 1, g: 0, b: 0, a: 0} + - _egc0: {r: 1, g: 1, b: 1, a: 0} + - _egc1: {r: 1, g: 1, b: 1, a: 1} + - _egc2: {r: 1, g: 1, b: 1, a: 0} + - _egc3: {r: 1, g: 1, b: 1, a: 0} + - _egc4: {r: 1, g: 1, b: 1, a: 0} + - _egc5: {r: 1, g: 1, b: 1, a: 0} + - _egc6: {r: 1, g: 1, b: 1, a: 0} + - _egc7: {r: 1, g: 1, b: 1, a: 0} + m_BuildTextureStacks: [] + m_AllowLocking: 1 diff --git a/Assets/04_Models/Characters/Fariy/Materials/Cloth/Alistia_Cloth_1_Blue_Lace.mat.meta b/Assets/04_Models/Characters/Fariy/Materials/Cloth/Alistia_Cloth_1_Blue_Lace.mat.meta new file mode 100644 index 00000000..b9772bf5 --- /dev/null +++ b/Assets/04_Models/Characters/Fariy/Materials/Cloth/Alistia_Cloth_1_Blue_Lace.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: ec6935d242801ba45a50c57594f80846 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/04_Models/Characters/Fariy/Materials/Cloth/Alistia_Cloth_2_Lace.mat b/Assets/04_Models/Characters/Fariy/Materials/Cloth/Alistia_Cloth_2_Lace.mat new file mode 100644 index 00000000..674ce31e --- /dev/null +++ b/Assets/04_Models/Characters/Fariy/Materials/Cloth/Alistia_Cloth_2_Lace.mat @@ -0,0 +1,1026 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 8 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: Alistia_Cloth_2_Lace + m_Shader: {fileID: 4800000, guid: 6459b2db96a08ca41b0f9b39dc7ad59e, type: 3} + m_Parent: {fileID: 0} + m_ModifiedSerializedProperties: 0 + m_ValidKeywords: + - N_F_DDMD_ON + - N_F_EAL_ON + - N_F_O_ON + - N_F_RDC_ON + - N_F_RELGI_ON + - N_F_SS_ON + - N_F_TRANSAFFSHA_ON + - _UVSET_UV0 + m_InvalidKeywords: [] + m_LightmapFlags: 0 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: -1 + stringTagMap: {} + disabledShaderPasses: [] + m_LockedProperties: + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _AlphaMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _AnisotropyScaleMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _AnisotropyShiftNoiseMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _AnisotropyTangentMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _AudioLinkLocalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _AudioLinkMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BacklightColorTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BaseColorMap: + m_Texture: {fileID: 2800000, guid: 093a9db6b1fee594380cc05560ae5e8a, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BaseMap: + m_Texture: {fileID: 2800000, guid: 093a9db6b1fee594380cc05560ae5e8a, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Bump2ndMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Bump2ndScaleMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DissolveMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DissolveNoiseMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DitherTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Emission2ndBlendMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Emission2ndGradTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Emission2ndMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionBlendMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionGradTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _FReflection: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _GlitterColorTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _GlitterShapeTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _GlossTexture: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MCap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MCapMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main2ndBlendMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main2ndDissolveMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main2ndDissolveNoiseMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main2ndTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main3rdBlendMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main3rdDissolveMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main3rdDissolveNoiseMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main3rdTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainColorAdjustMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainGradationTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 2800000, guid: 093a9db6b1fee594380cc05560ae5e8a, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MaskGloss: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MaskReflection: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MaskSelfLit: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MaskTransparency: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MatCap2ndBlendMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MatCap2ndBumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MatCap2ndTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MatCapBlendMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MatCapBumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MatCapTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _NormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OutlineTex: + m_Texture: {fileID: 2800000, guid: 093a9db6b1fee594380cc05560ae5e8a, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OutlineVectorTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OutlineWidthControl: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OutlineWidthMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _PTexture: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ReflectionColorTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ReflectionCubeTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _RimColorTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _RimShadeMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _SecondaryCutout: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Shadow2ndColorTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Shadow3rdColorTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ShadowBlurMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ShadowBorderMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ShadowColorTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ShadowColorTexture: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ShadowStrengthMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ShadowT: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _SmoothnessTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Ints: [] + m_Floats: + - _AAS: 0.0001 + - _AAStrength: 1 + - _AlpToCov: 0 + - _AlphaBaseCutout: 1 + - _AlphaBoostFA: 10 + - _AlphaMaskMode: 0 + - _AlphaMaskScale: 1 + - _AlphaMaskValue: 0 + - _AlphaToMask: 0 + - _Anisotropy2MatCap: 0 + - _Anisotropy2MatCap2nd: 0 + - _Anisotropy2Reflection: 0 + - _Anisotropy2ndBitangentWidth: 1 + - _Anisotropy2ndShift: 0 + - _Anisotropy2ndShiftNoiseScale: 0 + - _Anisotropy2ndSpecularStrength: 0 + - _Anisotropy2ndTangentWidth: 1 + - _AnisotropyBitangentWidth: 1 + - _AnisotropyScale: 1 + - _AnisotropyShift: 0 + - _AnisotropyShiftNoiseScale: 0 + - _AnisotropySpecularStrength: 1 + - _AnisotropyTangentWidth: 1 + - _ApplyReflection: 0 + - _ApplySpecular: 1 + - _ApplySpecularFA: 1 + - _AsOverlay: 0 + - _AsUnlit: 0 + - _AudioLink2Emission: 0 + - _AudioLink2Emission2nd: 0 + - _AudioLink2Emission2ndGrad: 0 + - _AudioLink2EmissionGrad: 0 + - _AudioLink2Main2nd: 0 + - _AudioLink2Main3rd: 0 + - _AudioLink2Vertex: 0 + - _AudioLinkAsLocal: 0 + - _AudioLinkMask_UVMode: 0 + - _AudioLinkUVMode: 1 + - _AudioLinkVertexUVMode: 1 + - _BackfaceForceShadow: 0 + - _BacklightBackfaceMask: 1 + - _BacklightBlur: 0.05 + - _BacklightBorder: 0.35 + - _BacklightDirectivity: 5 + - _BacklightMainStrength: 0 + - _BacklightNormalStrength: 1 + - _BacklightReceiveShadow: 1 + - _BacklightViewStrength: 1 + - _BeforeExposureLimit: 10000 + - _BitKey0: 0 + - _BitKey1: 0 + - _BitKey10: 0 + - _BitKey11: 0 + - _BitKey12: 0 + - _BitKey13: 0 + - _BitKey14: 0 + - _BitKey15: 0 + - _BitKey16: 0 + - _BitKey17: 0 + - _BitKey18: 0 + - _BitKey19: 0 + - _BitKey2: 0 + - _BitKey20: 0 + - _BitKey21: 0 + - _BitKey22: 0 + - _BitKey23: 0 + - _BitKey24: 0 + - _BitKey25: 0 + - _BitKey26: 0 + - _BitKey27: 0 + - _BitKey28: 0 + - _BitKey29: 0 + - _BitKey3: 0 + - _BitKey30: 0 + - _BitKey31: 0 + - _BitKey4: 0 + - _BitKey5: 0 + - _BitKey6: 0 + - _BitKey7: 0 + - _BitKey8: 0 + - _BitKey9: 0 + - _BleModDest: 0 + - _BleModSour: 1 + - _BlendOp: 0 + - _BlendOpAlpha: 0 + - _BlendOpAlphaFA: 4 + - _BlendOpFA: 4 + - _Bump2ndMap_UVMode: 0 + - _Bump2ndScale: 1 + - _BumpScale: 1 + - _ClipAdju: 0 + - _ColorMask: 15 + - _Compa: 4 + - _ComputeMeshIndex: 0 + - _Cull: 0 + - _Culling: 2 + - _CustomLightDirectionFollowObjectRotation: 0 + - _CustomLightDirectionIntensity: 0 + - _Cutoff: 0.001 + - _Cutout: 0.5 + - _DepthThreshold: 900 + - _DirectionalLightIntensity: 1 + - _DissolveNoiseStrength: 0.1 + - _DistanceFadeMode: 0 + - _DistanceFadeRimFresnelPower: 5 + - _DitherMaxValue: 255 + - _DoubleSidedOutline: 1 + - _DstBlend: 10 + - _DstBlendAlpha: 10 + - _DstBlendAlphaFA: 1 + - _DstBlendFA: 1 + - _DummyProperty: 0 + - _DynamicNoisyOutline: 0 + - _Emission2ndBlend: 1 + - _Emission2ndBlendMode: 1 + - _Emission2ndFluorescence: 0 + - _Emission2ndGradSpeed: 1 + - _Emission2ndMainStrength: 0 + - _Emission2ndMap_UVMode: 0 + - _Emission2ndParallaxDepth: 0 + - _Emission2ndUseGrad: 0 + - _EmissionBlend: 1 + - _EmissionBlendMode: 1 + - _EmissionFluorescence: 0 + - _EmissionGradSpeed: 1 + - _EmissionMainStrength: 0 + - _EmissionMap_UVMode: 0 + - _EmissionParallaxDepth: 0 + - _EmissionUseGrad: 0 + - _EnvironmentalLightingIntensity: 1 + - _FarDistanceMaxWidth: 10 + - _FlipNormal: 0 + - _GIFlatShade: 0 + - _GIShadeThreshold: 0 + - _GSAAStrength: 0 + - _GlitterAngleRandomize: 0 + - _GlitterApplyShape: 0 + - _GlitterApplyTransparency: 1 + - _GlitterBackfaceMask: 0 + - _GlitterColorTex_UVMode: 0 + - _GlitterEnableLighting: 1 + - _GlitterMainStrength: 0 + - _GlitterNormalStrength: 1 + - _GlitterPostContrast: 1 + - _GlitterScaleRandomize: 0 + - _GlitterSensitivity: 0.25 + - _GlitterShadowMask: 0 + - _GlitterUVMode: 0 + - _GlitterVRParallaxStrength: 0 + - _GlossColorPower: 10 + - _GlossIntensity: 1 + - _GlossSoftness: 0 + - _GlossTextureFollowLight: 0 + - _GlossTextureFollowObjectRotation: 0 + - _GlossTextureRotate: 0 + - _GlossTextureSoftness: 0 + - _Glossiness: 0.6 + - _Glow_Edge_Width: 1 + - _HighlightColorPower: 2 + - _IDMask1: 0 + - _IDMask2: 0 + - _IDMask3: 0 + - _IDMask4: 0 + - _IDMask5: 0 + - _IDMask6: 0 + - _IDMask7: 0 + - _IDMask8: 0 + - _IDMaskCompile: 0 + - _IDMaskControlsDissolve: 0 + - _IDMaskFrom: 8 + - _IDMaskIndex1: 0 + - _IDMaskIndex2: 0 + - _IDMaskIndex3: 0 + - _IDMaskIndex4: 0 + - _IDMaskIndex5: 0 + - _IDMaskIndex6: 0 + - _IDMaskIndex7: 0 + - _IDMaskIndex8: 0 + - _IDMaskIsBitmap: 0 + - _IDMaskPrior1: 0 + - _IDMaskPrior2: 0 + - _IDMaskPrior3: 0 + - _IDMaskPrior4: 0 + - _IDMaskPrior5: 0 + - _IDMaskPrior6: 0 + - _IDMaskPrior7: 0 + - _IDMaskPrior8: 0 + - _IgnoreEncryption: 0 + - _Invisible: 0 + - _LLI_Max: 1 + - _LLI_Min: 0 + - _LigIgnoYNorDir: 0 + - _LightAffectOutlineColor: 0 + - _LightAffectRimLightColor: 0 + - _LightAffectShadow: 0 + - _LightFalloffAffectShadowT: 0 + - _LightFalloffSoftness: 1 + - _LightIntensity: 1 + - _LightMaxLimit: 1 + - _LightMinLimit: 0.05 + - _MCIALO: 0 + - _MCapIntensity: 1 + - _MVCOL: 0 + - _MaiColPo: 0.8 + - _Main2ndDissolveNoiseStrength: 0.1 + - _Main2ndEnableLighting: 1 + - _Main2ndTexAlphaMode: 0 + - _Main2ndTexAngle: 0 + - _Main2ndTexBlendMode: 0 + - _Main2ndTexIsDecal: 0 + - _Main2ndTexIsLeftOnly: 0 + - _Main2ndTexIsMSDF: 0 + - _Main2ndTexIsRightOnly: 0 + - _Main2ndTexShouldCopy: 0 + - _Main2ndTexShouldFlipCopy: 0 + - _Main2ndTexShouldFlipMirror: 0 + - _Main2ndTex_Cull: 0 + - _Main2ndTex_UVMode: 0 + - _Main3rdDissolveNoiseStrength: 0.1 + - _Main3rdEnableLighting: 1 + - _Main3rdTexAlphaMode: 0 + - _Main3rdTexAngle: 0 + - _Main3rdTexBlendMode: 0 + - _Main3rdTexIsDecal: 0 + - _Main3rdTexIsLeftOnly: 0 + - _Main3rdTexIsMSDF: 0 + - _Main3rdTexIsRightOnly: 0 + - _Main3rdTexShouldCopy: 0 + - _Main3rdTexShouldFlipCopy: 0 + - _Main3rdTexShouldFlipMirror: 0 + - _Main3rdTex_Cull: 0 + - _Main3rdTex_UVMode: 0 + - _MainGradationStrength: 0 + - _MatCap2ndApplyTransparency: 1 + - _MatCap2ndBackfaceMask: 0 + - _MatCap2ndBlend: 1 + - _MatCap2ndBlendMode: 1 + - _MatCap2ndBumpScale: 1 + - _MatCap2ndCustomNormal: 0 + - _MatCap2ndEnableLighting: 1 + - _MatCap2ndLod: 0 + - _MatCap2ndMainStrength: 0 + - _MatCap2ndNormalStrength: 1 + - _MatCap2ndPerspective: 1 + - _MatCap2ndShadowMask: 0 + - _MatCap2ndVRParallaxStrength: 1 + - _MatCap2ndZRotCancel: 1 + - _MatCapApplyTransparency: 1 + - _MatCapBackfaceMask: 0 + - _MatCapBlend: 1 + - _MatCapBlendMode: 1 + - _MatCapBumpScale: 1 + - _MatCapCustomNormal: 0 + - _MatCapEnableLighting: 1 + - _MatCapLod: 0 + - _MatCapMainStrength: 0 + - _MatCapNormalStrength: 1 + - _MatCapPerspective: 1 + - _MatCapShadowMask: 0 + - _MatCapVRParallaxStrength: 1 + - _MatCapZRotCancel: 1 + - _MaxFadDistance: 2 + - _Metallic: 0 + - _MinFadDistance: 0 + - _MixMainTexToOutline: 0 + - _MonochromeLighting: 0 + - _N_F_ANIS: 0 + - _N_F_CA: 0 + - _N_F_CLD: 0 + - _N_F_CO: 0 + - _N_F_COEDGL: 0 + - _N_F_DCS: 0 + - _N_F_DDMD: 1 + - _N_F_EAL: 1 + - _N_F_ESSAO: 0 + - _N_F_FR: 0 + - _N_F_GLO: 0 + - _N_F_GLOT: 0 + - _N_F_HDLS: 0 + - _N_F_HPSS: 0 + - _N_F_LLI: 0 + - _N_F_MC: 0 + - _N_F_MSSOLTFO: 0 + - _N_F_NFD: 0 + - _N_F_NLASOBF: 0 + - _N_F_NM: 0 + - _N_F_O: 1 + - _N_F_OFLMB: 0 + - _N_F_PA: 0 + - _N_F_PT: 0 + - _N_F_R: 0 + - _N_F_RDC: 1 + - _N_F_RL: 0 + - _N_F_RLIS: 0 + - _N_F_SCO: 0 + - _N_F_SCT: 0 + - _N_F_SE: 0 + - _N_F_SL: 0 + - _N_F_SLMM: 0 + - _N_F_SON: 0 + - _N_F_SS: 1 + - _N_F_ST: 0 + - _N_F_STIAL: 0 + - _N_F_STIS: 0 + - _N_F_STSDFM: 0 + - _N_F_TP: 0 + - _NoiTexAffStraWidt: 0 + - _NoisTexInten: 1 + - _NoiseSize: 100 + - _NoisyOutlineIntensity: 0 + - _NorMapAsDis: 0 + - _NormalMapIntensity: 1 + - _ObjePosiZCS: 0 + - _OffsetFactor: 0 + - _OffsetUnits: 0 + - _Opacity: 1 + - _Oper: 0 + - _OutStenPass: 0 + - _OutZTest: 4 + - _OutZWrite: 1 + - _OutlineAlphaToMask: 0 + - _OutlineBlendOp: 0 + - _OutlineBlendOpAlpha: 0 + - _OutlineBlendOpAlphaFA: 4 + - _OutlineBlendOpFA: 4 + - _OutlineColorMask: 15 + - _OutlineCull: 1 + - _OutlineDeleteMesh: 0 + - _OutlineDisableInVR: 0 + - _OutlineDstBlend: 10 + - _OutlineDstBlendAlpha: 10 + - _OutlineDstBlendAlphaFA: 1 + - _OutlineDstBlendFA: 1 + - _OutlineEnableLighting: 1 + - _OutlineExtrudeMethod: 0 + - _OutlineFixWidth: 0.5 + - _OutlineLitApplyTex: 0 + - _OutlineLitOffset: -8 + - _OutlineLitScale: 10 + - _OutlineLitShadowReceive: 0 + - _OutlineOffsetFactor: 0 + - _OutlineOffsetUnits: 0 + - _OutlineSrcBlend: 5 + - _OutlineSrcBlendAlpha: 1 + - _OutlineSrcBlendAlphaFA: 0 + - _OutlineSrcBlendFA: 1 + - _OutlineStencilComp: 8 + - _OutlineStencilFail: 0 + - _OutlineStencilPass: 0 + - _OutlineStencilReadMask: 255 + - _OutlineStencilRef: 0 + - _OutlineStencilWriteMask: 255 + - _OutlineStencilZFail: 0 + - _OutlineVectorScale: 1 + - _OutlineVectorUVMode: 0 + - _OutlineVertexR2Width: 0 + - _OutlineWidth: 0.02 + - _OutlineWidthAffectedByViewDistance: 0 + - _OutlineZBias: 0 + - _OutlineZClip: 1 + - _OutlineZPostionInCamera: 0 + - _OutlineZTest: 2 + - _OutlineZWrite: 1 + - _OverallShadowColorPower: 1 + - _PADist: 0 + - _PASize: 0.5 + - _PASmooTrans: 1 + - _PSGLOTEX: 0 + - _PTexturePower: 1 + - _Parallax: 0.02 + - _ParallaxOffset: 0.5 + - _PointSpotlightIntensity: 1 + - _PreAlphaToMask: 0 + - _PreBlendOp: 0 + - _PreBlendOpAlpha: 0 + - _PreBlendOpAlphaFA: 4 + - _PreBlendOpFA: 4 + - _PreColorMask: 15 + - _PreCull: 2 + - _PreCutoff: 0.5 + - _PreDstBlend: 10 + - _PreDstBlendAlpha: 10 + - _PreDstBlendAlphaFA: 1 + - _PreDstBlendFA: 1 + - _PreOffsetFactor: 0 + - _PreOffsetUnits: 0 + - _PreOutType: 0 + - _PreSrcBlend: 1 + - _PreSrcBlendAlpha: 1 + - _PreSrcBlendAlphaFA: 0 + - _PreSrcBlendFA: 1 + - _PreStencilComp: 8 + - _PreStencilFail: 0 + - _PreStencilPass: 0 + - _PreStencilReadMask: 255 + - _PreStencilRef: 0 + - _PreStencilWriteMask: 255 + - _PreStencilZFail: 0 + - _PreZClip: 1 + - _PreZTest: 4 + - _PreZWrite: 1 + - _PresAdju: 1 + - _RELG: 1 + - _RQSO: 0 + - _ReduSha: 0.5 + - _RefMetallic: 0 + - _RefVal: 0 + - _Reflectance: 0.04 + - _ReflectionApplyTransparency: 1 + - _ReflectionBlendMode: 1 + - _ReflectionCubeEnableLighting: 1 + - _ReflectionCubeOverride: 0 + - _ReflectionIntensity: 0 + - _ReflectionNormalStrength: 1 + - _RimApplyTransparency: 1 + - _RimBackfaceMask: 1 + - _RimBlendMode: 1 + - _RimBlur: 0.15 + - _RimBorder: 0.9 + - _RimDirRange: 0 + - _RimDirStrength: 0 + - _RimEnableLighting: 1 + - _RimFresnelPower: 3.5 + - _RimIndirBlur: 0.1 + - _RimIndirBorder: 0.5 + - _RimIndirRange: 0 + - _RimLigInt: 1 + - _RimLightColorPower: 10 + - _RimLightInLight: 1 + - _RimLightSoftness: 1 + - _RimLightUnfill: 1.5 + - _RimMainStrength: 0 + - _RimNormalStrength: 1 + - _RimShadeBlur: 1 + - _RimShadeBorder: 0.5 + - _RimShadeFresnelPower: 1 + - _RimShadeNormalStrength: 1 + - _RimShadowMask: 0.5 + - _RimVRParallaxStrength: 1 + - _SPECIN: 1 + - _SPECMODE: 0 + - _STIL: 0 + - _Saturation: 1 + - _SelfLitHighContrast: 1 + - _SelfLitIntensity: 0 + - _SelfLitPower: 2 + - _SelfShadowAffectedByLightShadowStrength: 0 + - _SelfShadowHardness: 1 + - _SelfShadowRealTimeShadowColorPower: 1 + - _SelfShadowRealtimeShadowIntensity: 0 + - _SelfShadowShadowTAtViewDirection: 0 + - _SelfShadowThreshold: 0.93 + - _Shadow2ndBlur: 0.1 + - _Shadow2ndBorder: 0.15 + - _Shadow2ndNormalStrength: 1 + - _Shadow2ndReceive: 0 + - _Shadow3rdBlur: 0.1 + - _Shadow3rdBorder: 0.25 + - _Shadow3rdNormalStrength: 1 + - _Shadow3rdReceive: 0 + - _ShadowBlur: 0.1 + - _ShadowBlurMaskLOD: 0 + - _ShadowBorder: 0.2 + - _ShadowBorderMaskLOD: 0 + - _ShadowBorderRange: 0.08 + - _ShadowColorTexturePower: 0 + - _ShadowColorType: 0 + - _ShadowEnvStrength: 0 + - _ShadowFlatBlur: 1 + - _ShadowFlatBorder: 1 + - _ShadowHardness: 0 + - _ShadowMainStrength: 0 + - _ShadowMaskType: 0 + - _ShadowNormalStrength: 1 + - _ShadowPostAO: 0 + - _ShadowReceive: 1 + - _ShadowStrength: 0.7 + - _ShadowStrengthMaskLOD: 0 + - _ShadowTColorPower: 1 + - _ShadowTHardness: 1 + - _ShadowTIntensity: 1 + - _ShadowTLightThreshold: 50 + - _ShadowTShadowThreshold: 0 + - _ShifAnis: 0 + - _ShiftBackfaceUV: 0 + - _ShowInAmbientLightShadowIntensity: 1 + - _ShowInAmbientLightShadowThreshold: 0.4 + - _ShowNormal: 0 + - _SimTrans: 0 + - _SkinMatrixIndex: 0 + - _SmoothObjectNormal: 0 + - _Smoothness: 1 + - _SpecularBlur: 0 + - _SpecularBorder: 0.5 + - _SpecularNormalStrength: 1 + - _SpecularToon: 1 + - _SrcBlend: 1 + - _SrcBlendAlpha: 1 + - _SrcBlendAlphaFA: 0 + - _SrcBlendFA: 1 + - _StencilComp: 8 + - _StencilFail: 0 + - _StencilPass: 0 + - _StencilReadMask: 255 + - _StencilRef: 0 + - _StencilWriteMask: 255 + - _StencilZFail: 0 + - _StraWidt: 10 + - _SubpassCutoff: 0.5 + - _TEXMCOLINT: 1 + - _TRANSMODE: 0 + - _TessEdge: 10 + - _TessFactorMax: 3 + - _TessShrink: 0 + - _TessStrength: 0.5 + - _TessellationFar: 1 + - _TessellationNear: 1 + - _TessellationSmoothness: 0.5 + - _TessellationTransition: 0.8 + - _TexturePatternStyle: 0 + - _TrailSize: 1.5 + - _TransAffSha: 1 + - _TransparentMode: 0 + - _TransparentThreshold: 0 + - _TriPlaBlend: 4 + - _TriPlaTile: 1 + - _UDIMDiscardCompile: 0 + - _UDIMDiscardMode: 0 + - _UDIMDiscardRow0_0: 0 + - _UDIMDiscardRow0_1: 0 + - _UDIMDiscardRow0_2: 0 + - _UDIMDiscardRow0_3: 0 + - _UDIMDiscardRow1_0: 0 + - _UDIMDiscardRow1_1: 0 + - _UDIMDiscardRow1_2: 0 + - _UDIMDiscardRow1_3: 0 + - _UDIMDiscardRow2_0: 0 + - _UDIMDiscardRow2_1: 0 + - _UDIMDiscardRow2_2: 0 + - _UDIMDiscardRow2_3: 0 + - _UDIMDiscardRow3_0: 0 + - _UDIMDiscardRow3_1: 0 + - _UDIMDiscardRow3_2: 0 + - _UDIMDiscardRow3_3: 0 + - _UDIMDiscardUV: 0 + - _UVSet: 0 + - _UseAnisotropy: 0 + - _UseAudioLink: 0 + - _UseBacklight: 0 + - _UseBump2ndMap: 0 + - _UseBumpMap: 0 + - _UseClippingCanceller: 0 + - _UseDither: 0 + - _UseEmission: 0 + - _UseEmission2nd: 0 + - _UseGlitter: 0 + - _UseMain2ndTex: 0 + - _UseMain3rdTex: 0 + - _UseMatCap: 0 + - _UseMatCap2nd: 0 + - _UseOutline: 0 + - _UsePOM: 0 + - _UseParallax: 0 + - _UseReflection: 0 + - _UseRim: 0 + - _UseRimShade: 0 + - _UseSecondaryCutout: 0 + - _UseShadow: 1 + - _UseTLB: 0 + - _VertexColorBlueAffectOutlineWitdh: 0 + - _VertexColorGreenControlSelfShadowThreshold: 0 + - _VertexColorRedControlSmoothObjectNormal: 0 + - _VertexLightStrength: 0 + - _ZClip: 1 + - _ZTest: 4 + - _ZWrite: 1 + - _e2gai: 2 + - _e2gci: 2 + - _egai: 2 + - _egci: 2 + - _lilDirectionalLightStrength: 1 + - _lilShadowCasterBias: 0 + - _lilToonVersion: 42 + m_Colors: + - _AudioLinkDefaultValue: {r: 0, g: 0, b: 2, a: 0.75} + - _AudioLinkLocalMapParams: {r: 120, g: 1, b: 0, a: 0} + - _AudioLinkMask_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _AudioLinkStart: {r: 0, g: 0, b: 0, a: 0} + - _AudioLinkUVParams: {r: 0.25, g: 0, b: 0, a: 0.125} + - _AudioLinkVertexStart: {r: 0, g: 0, b: 0, a: 0} + - _AudioLinkVertexStrength: {r: 0, g: 0, b: 0, a: 1} + - _AudioLinkVertexUVParams: {r: 0.25, g: 0, b: 0, a: 0.125} + - _BackfaceColor: {r: 0, g: 0, b: 0, a: 0} + - _BacklightColor: {r: 0.85, g: 0.8, b: 0.7, a: 1} + - _BaseColor: {r: 1, g: 1, b: 1, a: 1} + - _Color: {r: 1, g: 1, b: 1, a: 1} + - _Color2nd: {r: 1, g: 1, b: 1, a: 1} + - _Color3rd: {r: 1, g: 1, b: 1, a: 1} + - _CustomLightDirection: {r: 0, g: 0, b: 10, a: 0} + - _DissolveColor: {r: 1, g: 1, b: 1, a: 1} + - _DissolveNoiseMask_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _DissolveParams: {r: 0, g: 0, b: 0.5, a: 0.1} + - _DissolvePos: {r: 0, g: 0, b: 0, a: 0} + - _DistanceFade: {r: 0.1, g: 0.01, b: 0, a: 0} + - _DistanceFadeColor: {r: 0, g: 0, b: 0, a: 1} + - _DistanceFadeRimColor: {r: 0, g: 0, b: 0, a: 0} + - _Emission2ndBlendMask_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _Emission2ndBlink: {r: 0, g: 0, b: 3.141593, a: 0} + - _Emission2ndColor: {r: 1, g: 1, b: 1, a: 1} + - _Emission2ndMap_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _EmissionBlendMask_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _EmissionBlink: {r: 0, g: 0, b: 3.141593, a: 0} + - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} + - _EmissionMap_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _GlitterAtras: {r: 1, g: 1, b: 0, a: 0} + - _GlitterColor: {r: 1, g: 1, b: 1, a: 1} + - _GlitterParams1: {r: 256, g: 256, b: 0.16, a: 50} + - _GlitterParams2: {r: 0.25, g: 0, b: 0, a: 0} + - _GlossColor: {r: 1, g: 1, b: 1, a: 1} + - _Glow_Color: {r: 1, g: 1, b: 1, a: 1} + - _HighlightColor: {r: 0, g: 0.022767067, b: 1, a: 1} + - _Keys: {r: 0, g: 0, b: 0, a: 0} + - _LightDirectionOverride: {r: 0.001, g: 0.002, b: 0.001, a: 0} + - _Main2ndDissolveColor: {r: 1, g: 1, b: 1, a: 1} + - _Main2ndDissolveNoiseMask_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _Main2ndDissolveParams: {r: 0, g: 0, b: 0.5, a: 0.1} + - _Main2ndDissolvePos: {r: 0, g: 0, b: 0, a: 0} + - _Main2ndDistanceFade: {r: 0.1, g: 0.01, b: 0, a: 0} + - _Main2ndTexDecalAnimation: {r: 1, g: 1, b: 1, a: 30} + - _Main2ndTexDecalSubParam: {r: 1, g: 1, b: 0, a: 1} + - _Main2ndTex_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _Main3rdDissolveColor: {r: 1, g: 1, b: 1, a: 1} + - _Main3rdDissolveNoiseMask_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _Main3rdDissolveParams: {r: 0, g: 0, b: 0.5, a: 0.1} + - _Main3rdDissolvePos: {r: 0, g: 0, b: 0, a: 0} + - _Main3rdDistanceFade: {r: 0.1, g: 0.01, b: 0, a: 0} + - _Main3rdTexDecalAnimation: {r: 1, g: 1, b: 1, a: 30} + - _Main3rdTexDecalSubParam: {r: 1, g: 1, b: 0, a: 1} + - _Main3rdTex_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _MainColor: {r: 1, g: 1, b: 1, a: 1} + - _MainTexHSVG: {r: 0, g: 1, b: 1, a: 1} + - _MainTex_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _MatCap2ndBlendUV1: {r: 0, g: 0, b: 0, a: 0} + - _MatCap2ndColor: {r: 1, g: 1, b: 1, a: 1} + - _MatCapBlendUV1: {r: 0, g: 0, b: 0, a: 0} + - _MatCapColor: {r: 1, g: 1, b: 1, a: 1} + - _ObjPosi: {r: 0, g: 0, b: 0, a: 0} + - _ObjectForward: {r: 0, g: 0, b: 0, a: 0} + - _ObjectRight: {r: 0, g: 0, b: 0, a: 0} + - _OutResi: {r: 1, g: 1, b: 1, a: 1} + - _OutlineColor: {r: 0.65837497, g: 0.5028866, b: 0.47932023, a: 1} + - _OutlineLitColor: {r: 1, g: 0.19999996, b: 0, a: 0} + - _OutlineOffset: {r: 0, g: 0, b: 0, a: 1} + - _OutlineTexHSVG: {r: 0, g: 1, b: 1, a: 1} + - _OutlineTex_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _OverallShadowColor: {r: 0, g: 0, b: 0, a: 1} + - _PTCol: {r: 0, g: 0, b: 0, a: 1} + - _PreColor: {r: 1, g: 1, b: 1, a: 1} + - _PrevPosition: {r: 0, g: 0, b: 0, a: 0} + - _ReflectionColor: {r: 1, g: 1, b: 1, a: 1} + - _ReflectionCubeColor: {r: 0, g: 0, b: 0, a: 1} + - _RimColor: {r: 0.8396226, g: 0.75352514, b: 0.74061054, a: 1} + - _RimIndirColor: {r: 1, g: 1, b: 1, a: 1} + - _RimLigPosi: {r: 1, g: 1, b: 1, a: 1} + - _RimLightColor: {r: 1, g: 1, b: 1, a: 1} + - _RimShadeColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} + - _SSAOColor: {r: 0, g: 0, b: 0, a: 0} + - _SelfLitColor: {r: 1, g: 1, b: 1, a: 1} + - _SelfShadowRealTimeShadowColor: {r: 1, g: 1, b: 1, a: 1} + - _Shadow2ndColor: {r: 0.8683324, g: 0.85898006, b: 0.9150943, a: 1} + - _Shadow3rdColor: {r: 0, g: 0, b: 0, a: 0} + - _ShadowAOShift: {r: 1, g: 0, b: 1, a: 0} + - _ShadowAOShift2: {r: 1, g: 0, b: 1, a: 0} + - _ShadowBorderColor: {r: 0.16981131, g: 0.16981131, b: 0.16981131, a: 1} + - _ShadowColor: {r: 0.94978195, g: 0.9123354, b: 0.9622642, a: 1} + - _ShadowTColor: {r: 1, g: 1, b: 1, a: 1} + - _XYZPosition: {r: 0, g: 0, b: 0, a: 0} + - _e2ga0: {r: 1, g: 0, b: 0, a: 0} + - _e2ga1: {r: 1, g: 0, b: 0, a: 1} + - _e2ga2: {r: 1, g: 0, b: 0, a: 0} + - _e2ga3: {r: 1, g: 0, b: 0, a: 0} + - _e2ga4: {r: 1, g: 0, b: 0, a: 0} + - _e2ga5: {r: 1, g: 0, b: 0, a: 0} + - _e2ga6: {r: 1, g: 0, b: 0, a: 0} + - _e2ga7: {r: 1, g: 0, b: 0, a: 0} + - _e2gc0: {r: 1, g: 1, b: 1, a: 0} + - _e2gc1: {r: 1, g: 1, b: 1, a: 1} + - _e2gc2: {r: 1, g: 1, b: 1, a: 0} + - _e2gc3: {r: 1, g: 1, b: 1, a: 0} + - _e2gc4: {r: 1, g: 1, b: 1, a: 0} + - _e2gc5: {r: 1, g: 1, b: 1, a: 0} + - _e2gc6: {r: 1, g: 1, b: 1, a: 0} + - _e2gc7: {r: 1, g: 1, b: 1, a: 0} + - _ega0: {r: 1, g: 0, b: 0, a: 0} + - _ega1: {r: 1, g: 0, b: 0, a: 1} + - _ega2: {r: 1, g: 0, b: 0, a: 0} + - _ega3: {r: 1, g: 0, b: 0, a: 0} + - _ega4: {r: 1, g: 0, b: 0, a: 0} + - _ega5: {r: 1, g: 0, b: 0, a: 0} + - _ega6: {r: 1, g: 0, b: 0, a: 0} + - _ega7: {r: 1, g: 0, b: 0, a: 0} + - _egc0: {r: 1, g: 1, b: 1, a: 0} + - _egc1: {r: 1, g: 1, b: 1, a: 1} + - _egc2: {r: 1, g: 1, b: 1, a: 0} + - _egc3: {r: 1, g: 1, b: 1, a: 0} + - _egc4: {r: 1, g: 1, b: 1, a: 0} + - _egc5: {r: 1, g: 1, b: 1, a: 0} + - _egc6: {r: 1, g: 1, b: 1, a: 0} + - _egc7: {r: 1, g: 1, b: 1, a: 0} + m_BuildTextureStacks: [] + m_AllowLocking: 1 diff --git a/Assets/04_Models/Characters/Fariy/Materials/Cloth/Alistia_Cloth_2_Lace.mat.meta b/Assets/04_Models/Characters/Fariy/Materials/Cloth/Alistia_Cloth_2_Lace.mat.meta new file mode 100644 index 00000000..bdd4036b --- /dev/null +++ b/Assets/04_Models/Characters/Fariy/Materials/Cloth/Alistia_Cloth_2_Lace.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: e53efbb67fe6728448f434995daddef8 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/04_Models/Characters/Fariy/Materials/Komono.meta b/Assets/04_Models/Characters/Fariy/Materials/Komono.meta new file mode 100644 index 00000000..3638fdae --- /dev/null +++ b/Assets/04_Models/Characters/Fariy/Materials/Komono.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: c59e650fcc5259249a93565130ccd21f +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/04_Models/Characters/Fariy/Materials/Komono/Jewel_Blue.mat b/Assets/04_Models/Characters/Fariy/Materials/Komono/Jewel_Blue.mat new file mode 100644 index 00000000..ae932c3b --- /dev/null +++ b/Assets/04_Models/Characters/Fariy/Materials/Komono/Jewel_Blue.mat @@ -0,0 +1,977 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 8 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: Jewel_Blue + m_Shader: {fileID: 4800000, guid: 6459b2db96a08ca41b0f9b39dc7ad59e, type: 3} + m_Parent: {fileID: 0} + m_ModifiedSerializedProperties: 0 + m_ValidKeywords: + - N_F_DDMD_ON + - N_F_EAL_ON + - N_F_O_ON + - N_F_RDC_ON + - N_F_RELGI_ON + - N_F_SS_ON + - N_F_TRANSAFFSHA_ON + - _UVSET_UV0 + m_InvalidKeywords: [] + m_LightmapFlags: 0 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: -1 + stringTagMap: {} + disabledShaderPasses: [] + m_LockedProperties: + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _AlphaMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _AnisotropyScaleMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _AnisotropyShiftNoiseMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _AnisotropyTangentMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _AudioLinkLocalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _AudioLinkMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BacklightColorTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BaseColorMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BaseMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Bump2ndMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Bump2ndScaleMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DissolveMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DissolveNoiseMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DitherTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Emission2ndBlendMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Emission2ndGradTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Emission2ndMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionBlendMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionGradTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _FReflection: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _GlitterColorTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _GlitterShapeTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _GlossTexture: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MCap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MCapMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main2ndBlendMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main2ndDissolveMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main2ndDissolveNoiseMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main2ndTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main3rdBlendMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main3rdDissolveMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main3rdDissolveNoiseMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main3rdTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainColorAdjustMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainGradationTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MaskGloss: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MaskReflection: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MaskSelfLit: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MaskTransparency: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MatCap2ndBlendMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MatCap2ndBumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MatCap2ndTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MatCapBlendMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MatCapBumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MatCapTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _NormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OutlineTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OutlineVectorTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OutlineWidthControl: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OutlineWidthMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _PTexture: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ReflectionColorTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ReflectionCubeTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _RimColorTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _RimShadeMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _SecondaryCutout: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Shadow2ndColorTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Shadow3rdColorTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ShadowBlurMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ShadowBorderMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ShadowColorTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ShadowColorTexture: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ShadowStrengthMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ShadowT: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _SmoothnessTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Ints: [] + m_Floats: + - _AAS: 0.0001 + - _AAStrength: 1 + - _AlpToCov: 0 + - _AlphaBaseCutout: 1 + - _AlphaBoostFA: 10 + - _AlphaMaskMode: 0 + - _AlphaMaskScale: 1 + - _AlphaMaskValue: 0 + - _AlphaToMask: 0 + - _Anisotropy2MatCap: 0 + - _Anisotropy2MatCap2nd: 0 + - _Anisotropy2Reflection: 0 + - _Anisotropy2ndBitangentWidth: 1 + - _Anisotropy2ndShift: 0 + - _Anisotropy2ndShiftNoiseScale: 0 + - _Anisotropy2ndSpecularStrength: 0 + - _Anisotropy2ndTangentWidth: 1 + - _AnisotropyBitangentWidth: 1 + - _AnisotropyScale: 1 + - _AnisotropyShift: 0 + - _AnisotropyShiftNoiseScale: 0 + - _AnisotropySpecularStrength: 1 + - _AnisotropyTangentWidth: 1 + - _ApplyReflection: 0 + - _ApplySpecular: 1 + - _ApplySpecularFA: 1 + - _AsOverlay: 0 + - _AsUnlit: 0 + - _AudioLink2Emission: 0 + - _AudioLink2Emission2nd: 0 + - _AudioLink2Emission2ndGrad: 0 + - _AudioLink2EmissionGrad: 0 + - _AudioLink2Main2nd: 0 + - _AudioLink2Main3rd: 0 + - _AudioLink2Vertex: 0 + - _AudioLinkAsLocal: 0 + - _AudioLinkMask_UVMode: 0 + - _AudioLinkUVMode: 1 + - _AudioLinkVertexUVMode: 1 + - _BackfaceForceShadow: 0 + - _BacklightBackfaceMask: 1 + - _BacklightBlur: 0.05 + - _BacklightBorder: 0.35 + - _BacklightDirectivity: 5 + - _BacklightMainStrength: 0 + - _BacklightNormalStrength: 1 + - _BacklightReceiveShadow: 1 + - _BacklightViewStrength: 1 + - _BeforeExposureLimit: 10000 + - _BitKey0: 0 + - _BitKey1: 0 + - _BitKey10: 0 + - _BitKey11: 0 + - _BitKey12: 0 + - _BitKey13: 0 + - _BitKey14: 0 + - _BitKey15: 0 + - _BitKey16: 0 + - _BitKey17: 0 + - _BitKey18: 0 + - _BitKey19: 0 + - _BitKey2: 0 + - _BitKey20: 0 + - _BitKey21: 0 + - _BitKey22: 0 + - _BitKey23: 0 + - _BitKey24: 0 + - _BitKey25: 0 + - _BitKey26: 0 + - _BitKey27: 0 + - _BitKey28: 0 + - _BitKey29: 0 + - _BitKey3: 0 + - _BitKey30: 0 + - _BitKey31: 0 + - _BitKey4: 0 + - _BitKey5: 0 + - _BitKey6: 0 + - _BitKey7: 0 + - _BitKey8: 0 + - _BitKey9: 0 + - _BleModDest: 0 + - _BleModSour: 1 + - _BlendOp: 0 + - _BlendOpAlpha: 0 + - _BlendOpAlphaFA: 4 + - _BlendOpFA: 4 + - _Bump2ndMap_UVMode: 0 + - _Bump2ndScale: 1 + - _BumpScale: 1 + - _ClipAdju: 0 + - _ColorMask: 15 + - _Compa: 4 + - _ComputeMeshIndex: 0 + - _Cull: 0 + - _Culling: 2 + - _CustomLightDirectionFollowObjectRotation: 0 + - _CustomLightDirectionIntensity: 0 + - _Cutoff: 0.5 + - _Cutout: 0.5 + - _DepthThreshold: 900 + - _DirectionalLightIntensity: 0.5 + - _DissolveNoiseStrength: 0.1 + - _DistanceFadeMode: 0 + - _DistanceFadeRimFresnelPower: 5 + - _DitherMaxValue: 255 + - _DoubleSidedOutline: 1 + - _DstBlend: 1 + - _DstBlendAlpha: 10 + - _DstBlendAlphaFA: 1 + - _DstBlendFA: 1 + - _DummyProperty: 0 + - _DynamicNoisyOutline: 0 + - _Emission2ndBlend: 1 + - _Emission2ndBlendMode: 1 + - _Emission2ndFluorescence: 0 + - _Emission2ndGradSpeed: 1 + - _Emission2ndMainStrength: 0 + - _Emission2ndMap_UVMode: 0 + - _Emission2ndParallaxDepth: 0 + - _Emission2ndUseGrad: 0 + - _EmissionBlend: 1 + - _EmissionBlendMode: 1 + - _EmissionFluorescence: 0 + - _EmissionGradSpeed: 1 + - _EmissionMainStrength: 0 + - _EmissionMap_UVMode: 0 + - _EmissionParallaxDepth: 0 + - _EmissionUseGrad: 0 + - _EnvironmentalLightingIntensity: 0.5 + - _FarDistanceMaxWidth: 10 + - _FlipNormal: 0 + - _GIFlatShade: 0 + - _GIShadeThreshold: 0 + - _GSAAStrength: 0 + - _GemChromaticAberration: 0.02 + - _GemEnvContrast: 2 + - _GemParticleLoop: 8 + - _GemVRParallaxStrength: 1 + - _GlitterAngleRandomize: 0 + - _GlitterApplyShape: 0 + - _GlitterApplyTransparency: 1 + - _GlitterBackfaceMask: 0 + - _GlitterColorTex_UVMode: 0 + - _GlitterEnableLighting: 1 + - _GlitterMainStrength: 0 + - _GlitterNormalStrength: 1 + - _GlitterPostContrast: 1 + - _GlitterScaleRandomize: 0 + - _GlitterSensitivity: 0.25 + - _GlitterShadowMask: 0 + - _GlitterUVMode: 0 + - _GlitterVRParallaxStrength: 1 + - _GlossColorPower: 10 + - _GlossIntensity: 1 + - _GlossSoftness: 0 + - _GlossTextureFollowLight: 0 + - _GlossTextureFollowObjectRotation: 0 + - _GlossTextureRotate: 0 + - _GlossTextureSoftness: 0 + - _Glossiness: 0.6 + - _Glow_Edge_Width: 1 + - _HighlightColorPower: 1 + - _IDMask1: 0 + - _IDMask2: 0 + - _IDMask3: 0 + - _IDMask4: 0 + - _IDMask5: 0 + - _IDMask6: 0 + - _IDMask7: 0 + - _IDMask8: 0 + - _IDMaskCompile: 0 + - _IDMaskControlsDissolve: 0 + - _IDMaskFrom: 8 + - _IDMaskIndex1: 0 + - _IDMaskIndex2: 0 + - _IDMaskIndex3: 0 + - _IDMaskIndex4: 0 + - _IDMaskIndex5: 0 + - _IDMaskIndex6: 0 + - _IDMaskIndex7: 0 + - _IDMaskIndex8: 0 + - _IDMaskIsBitmap: 0 + - _IDMaskPrior1: 0 + - _IDMaskPrior2: 0 + - _IDMaskPrior3: 0 + - _IDMaskPrior4: 0 + - _IDMaskPrior5: 0 + - _IDMaskPrior6: 0 + - _IDMaskPrior7: 0 + - _IDMaskPrior8: 0 + - _IgnoreEncryption: 0 + - _Invisible: 0 + - _LLI_Max: 1 + - _LLI_Min: 0 + - _LigIgnoYNorDir: 0 + - _LightAffectOutlineColor: 0 + - _LightAffectRimLightColor: 0 + - _LightAffectShadow: 0 + - _LightFalloffAffectShadowT: 0 + - _LightFalloffSoftness: 1 + - _LightIntensity: 1 + - _LightMaxLimit: 1 + - _LightMinLimit: 0.05 + - _MCIALO: 0 + - _MCapIntensity: 1 + - _MVCOL: 0 + - _MaiColPo: 0.8 + - _Main2ndDissolveNoiseStrength: 0.1 + - _Main2ndEnableLighting: 1 + - _Main2ndTexAlphaMode: 0 + - _Main2ndTexAngle: 0 + - _Main2ndTexBlendMode: 0 + - _Main2ndTexIsDecal: 0 + - _Main2ndTexIsLeftOnly: 0 + - _Main2ndTexIsMSDF: 0 + - _Main2ndTexIsRightOnly: 0 + - _Main2ndTexShouldCopy: 0 + - _Main2ndTexShouldFlipCopy: 0 + - _Main2ndTexShouldFlipMirror: 0 + - _Main2ndTex_Cull: 0 + - _Main2ndTex_UVMode: 0 + - _Main3rdDissolveNoiseStrength: 0.1 + - _Main3rdEnableLighting: 1 + - _Main3rdTexAlphaMode: 0 + - _Main3rdTexAngle: 0 + - _Main3rdTexBlendMode: 0 + - _Main3rdTexIsDecal: 0 + - _Main3rdTexIsLeftOnly: 0 + - _Main3rdTexIsMSDF: 0 + - _Main3rdTexIsRightOnly: 0 + - _Main3rdTexShouldCopy: 0 + - _Main3rdTexShouldFlipCopy: 0 + - _Main3rdTexShouldFlipMirror: 0 + - _Main3rdTex_Cull: 0 + - _Main3rdTex_UVMode: 0 + - _MainGradationStrength: 0 + - _MatCap2ndApplyTransparency: 1 + - _MatCap2ndBackfaceMask: 0 + - _MatCap2ndBlend: 1 + - _MatCap2ndBlendMode: 1 + - _MatCap2ndBumpScale: 1 + - _MatCap2ndCustomNormal: 0 + - _MatCap2ndEnableLighting: 1 + - _MatCap2ndLod: 0 + - _MatCap2ndMainStrength: 0 + - _MatCap2ndNormalStrength: 1 + - _MatCap2ndPerspective: 1 + - _MatCap2ndShadowMask: 0 + - _MatCap2ndVRParallaxStrength: 1 + - _MatCap2ndZRotCancel: 1 + - _MatCapApplyTransparency: 1 + - _MatCapBackfaceMask: 0 + - _MatCapBlend: 1 + - _MatCapBlendMode: 1 + - _MatCapBumpScale: 1 + - _MatCapCustomNormal: 0 + - _MatCapEnableLighting: 1 + - _MatCapLod: 0 + - _MatCapMainStrength: 0 + - _MatCapNormalStrength: 1 + - _MatCapPerspective: 1 + - _MatCapShadowMask: 0 + - _MatCapVRParallaxStrength: 1 + - _MatCapZRotCancel: 1 + - _MaxFadDistance: 2 + - _Metallic: 0 + - _MinFadDistance: 0 + - _MixMainTexToOutline: 0 + - _MonochromeLighting: 0 + - _N_F_ANIS: 0 + - _N_F_CA: 0 + - _N_F_CLD: 0 + - _N_F_CO: 0 + - _N_F_COEDGL: 0 + - _N_F_DCS: 0 + - _N_F_DDMD: 1 + - _N_F_EAL: 1 + - _N_F_ESSAO: 0 + - _N_F_FR: 0 + - _N_F_GLO: 0 + - _N_F_GLOT: 0 + - _N_F_HDLS: 0 + - _N_F_HPSS: 0 + - _N_F_LLI: 0 + - _N_F_MC: 0 + - _N_F_MSSOLTFO: 0 + - _N_F_NFD: 0 + - _N_F_NLASOBF: 0 + - _N_F_NM: 0 + - _N_F_O: 1 + - _N_F_OFLMB: 0 + - _N_F_PA: 0 + - _N_F_PT: 0 + - _N_F_R: 0 + - _N_F_RDC: 1 + - _N_F_RL: 0 + - _N_F_RLIS: 0 + - _N_F_SCO: 0 + - _N_F_SCT: 0 + - _N_F_SE: 0 + - _N_F_SL: 0 + - _N_F_SLMM: 0 + - _N_F_SON: 0 + - _N_F_SS: 1 + - _N_F_ST: 0 + - _N_F_STIAL: 0 + - _N_F_STIS: 0 + - _N_F_STSDFM: 0 + - _N_F_TP: 0 + - _NoiTexAffStraWidt: 0 + - _NoisTexInten: 1 + - _NoiseSize: 100 + - _NoisyOutlineIntensity: 0 + - _NorMapAsDis: 0 + - _NormalMapIntensity: 1 + - _ObjePosiZCS: 0 + - _OffsetFactor: 0 + - _OffsetUnits: 0 + - _Opacity: 1 + - _Oper: 0 + - _OutStenPass: 0 + - _OutZTest: 4 + - _OutZWrite: 1 + - _OutlineDeleteMesh: 0 + - _OutlineDisableInVR: 0 + - _OutlineEnableLighting: 1 + - _OutlineExtrudeMethod: 0 + - _OutlineFixWidth: 0.5 + - _OutlineLitApplyTex: 0 + - _OutlineLitOffset: -8 + - _OutlineLitScale: 10 + - _OutlineLitShadowReceive: 0 + - _OutlineVectorScale: 1 + - _OutlineVectorUVMode: 0 + - _OutlineVertexR2Width: 0 + - _OutlineWidth: 0.08 + - _OutlineWidthAffectedByViewDistance: 0 + - _OutlineZBias: 0 + - _OutlineZPostionInCamera: 0 + - _OverallShadowColorPower: 1 + - _PADist: 0 + - _PASize: 0.5 + - _PASmooTrans: 1 + - _PSGLOTEX: 0 + - _PTexturePower: 1 + - _Parallax: 0.02 + - _ParallaxOffset: 0.5 + - _PointSpotlightIntensity: 1 + - _PresAdju: 1 + - _RELG: 1 + - _RQSO: 0 + - _ReduSha: 0.5 + - _RefMetallic: 0 + - _RefVal: 0 + - _Reflectance: 0.04 + - _ReflectionApplyTransparency: 1 + - _ReflectionBlendMode: 1 + - _ReflectionCubeEnableLighting: 1 + - _ReflectionCubeOverride: 0 + - _ReflectionIntensity: 0 + - _ReflectionNormalStrength: 1 + - _RefractionFresnelPower: 1 + - _RefractionStrength: 0.5 + - _RimApplyTransparency: 1 + - _RimBackfaceMask: 0 + - _RimBlendMode: 1 + - _RimBlur: 0.1 + - _RimBorder: 0.5 + - _RimDirRange: 0 + - _RimDirStrength: 0 + - _RimEnableLighting: 1 + - _RimFresnelPower: 3 + - _RimIndirBlur: 0.1 + - _RimIndirBorder: 0.5 + - _RimIndirRange: 0 + - _RimLigInt: 1 + - _RimLightColorPower: 10 + - _RimLightInLight: 1 + - _RimLightSoftness: 1 + - _RimLightUnfill: 1.5 + - _RimMainStrength: 0 + - _RimNormalStrength: 1 + - _RimShadeBlur: 1 + - _RimShadeBorder: 0.5 + - _RimShadeFresnelPower: 1 + - _RimShadeNormalStrength: 1 + - _RimShadowMask: 0 + - _RimVRParallaxStrength: 1 + - _SPECIN: 1 + - _SPECMODE: 0 + - _STIL: 0 + - _Saturation: 1 + - _SelfLitHighContrast: 1 + - _SelfLitIntensity: 0 + - _SelfLitPower: 2 + - _SelfShadowAffectedByLightShadowStrength: 0 + - _SelfShadowHardness: 1 + - _SelfShadowRealTimeShadowColorPower: 1 + - _SelfShadowRealtimeShadowIntensity: 0 + - _SelfShadowShadowTAtViewDirection: 0 + - _SelfShadowThreshold: 0.93 + - _Shadow2ndBlur: 0.3 + - _Shadow2ndBorder: 0.5 + - _Shadow2ndNormalStrength: 1 + - _Shadow2ndReceive: 0 + - _Shadow3rdBlur: 0.1 + - _Shadow3rdBorder: 0.25 + - _Shadow3rdNormalStrength: 1 + - _Shadow3rdReceive: 0 + - _ShadowBlur: 0.1 + - _ShadowBlurMaskLOD: 0 + - _ShadowBorder: 0.5 + - _ShadowBorderMaskLOD: 0 + - _ShadowBorderRange: 0 + - _ShadowColorTexturePower: 0 + - _ShadowColorType: 0 + - _ShadowEnvStrength: 0 + - _ShadowFlatBlur: 1 + - _ShadowFlatBorder: 1 + - _ShadowHardness: 0 + - _ShadowMainStrength: 1 + - _ShadowMaskType: 0 + - _ShadowNormalStrength: 1 + - _ShadowPostAO: 0 + - _ShadowReceive: 0 + - _ShadowStrength: 1 + - _ShadowStrengthMaskLOD: 0 + - _ShadowTColorPower: 1 + - _ShadowTHardness: 1 + - _ShadowTIntensity: 1 + - _ShadowTLightThreshold: 50 + - _ShadowTShadowThreshold: 0 + - _ShifAnis: 0 + - _ShiftBackfaceUV: 0 + - _ShowInAmbientLightShadowIntensity: 1 + - _ShowInAmbientLightShadowThreshold: 0.4 + - _ShowNormal: 0 + - _SimTrans: 0 + - _SkinMatrixIndex: 0 + - _SmoothObjectNormal: 0 + - _Smoothness: 1 + - _SpecularBlur: 0 + - _SpecularBorder: 0.5 + - _SpecularNormalStrength: 1 + - _SpecularToon: 1 + - _SrcBlend: 1 + - _SrcBlendAlpha: 1 + - _SrcBlendAlphaFA: 0 + - _SrcBlendFA: 1 + - _StencilComp: 8 + - _StencilFail: 0 + - _StencilPass: 0 + - _StencilReadMask: 255 + - _StencilRef: 0 + - _StencilWriteMask: 255 + - _StencilZFail: 0 + - _StraWidt: 10 + - _SubpassCutoff: 0.5 + - _TEXMCOLINT: 1 + - _TRANSMODE: 0 + - _TessEdge: 10 + - _TessFactorMax: 3 + - _TessShrink: 0 + - _TessStrength: 0.5 + - _TessellationFar: 1 + - _TessellationNear: 1 + - _TessellationSmoothness: 0.5 + - _TessellationTransition: 0.8 + - _TexturePatternStyle: 0 + - _TrailSize: 1.5 + - _TransAffSha: 1 + - _TransparentMode: 0 + - _TransparentThreshold: 0 + - _TriPlaBlend: 4 + - _TriPlaTile: 1 + - _UDIMDiscardCompile: 0 + - _UDIMDiscardMode: 0 + - _UDIMDiscardRow0_0: 0 + - _UDIMDiscardRow0_1: 0 + - _UDIMDiscardRow0_2: 0 + - _UDIMDiscardRow0_3: 0 + - _UDIMDiscardRow1_0: 0 + - _UDIMDiscardRow1_1: 0 + - _UDIMDiscardRow1_2: 0 + - _UDIMDiscardRow1_3: 0 + - _UDIMDiscardRow2_0: 0 + - _UDIMDiscardRow2_1: 0 + - _UDIMDiscardRow2_2: 0 + - _UDIMDiscardRow2_3: 0 + - _UDIMDiscardRow3_0: 0 + - _UDIMDiscardRow3_1: 0 + - _UDIMDiscardRow3_2: 0 + - _UDIMDiscardRow3_3: 0 + - _UDIMDiscardUV: 0 + - _UVSet: 0 + - _UseAnisotropy: 0 + - _UseAudioLink: 0 + - _UseBacklight: 0 + - _UseBump2ndMap: 0 + - _UseBumpMap: 0 + - _UseClippingCanceller: 0 + - _UseDither: 0 + - _UseEmission: 0 + - _UseEmission2nd: 0 + - _UseGlitter: 0 + - _UseMain2ndTex: 0 + - _UseMain3rdTex: 0 + - _UseMatCap: 0 + - _UseMatCap2nd: 0 + - _UseOutline: 0 + - _UsePOM: 0 + - _UseParallax: 0 + - _UseReflection: 0 + - _UseRim: 0 + - _UseRimShade: 0 + - _UseSecondaryCutout: 0 + - _UseShadow: 0 + - _UseTLB: 0 + - _VertexColorBlueAffectOutlineWitdh: 0 + - _VertexColorGreenControlSelfShadowThreshold: 0 + - _VertexColorRedControlSmoothObjectNormal: 0 + - _VertexLightStrength: 0 + - _ZClip: 1 + - _ZTest: 4 + - _ZWrite: 0 + - _e2gai: 2 + - _e2gci: 2 + - _egai: 2 + - _egci: 2 + - _lilDirectionalLightStrength: 1 + - _lilShadowCasterBias: 0 + - _lilToonVersion: 42 + m_Colors: + - _AudioLinkDefaultValue: {r: 0, g: 0, b: 2, a: 0.75} + - _AudioLinkLocalMapParams: {r: 120, g: 1, b: 0, a: 0} + - _AudioLinkMask_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _AudioLinkStart: {r: 0, g: 0, b: 0, a: 0} + - _AudioLinkUVParams: {r: 0.25, g: 0, b: 0, a: 0.125} + - _AudioLinkVertexStart: {r: 0, g: 0, b: 0, a: 0} + - _AudioLinkVertexStrength: {r: 0, g: 0, b: 0, a: 1} + - _AudioLinkVertexUVParams: {r: 0.25, g: 0, b: 0, a: 0.125} + - _BackfaceColor: {r: 0, g: 0, b: 0, a: 0} + - _BacklightColor: {r: 0.85, g: 0.8, b: 0.7, a: 1} + - _BaseColor: {r: 0, g: 0.68, b: 2.9960785, a: 1} + - _Color: {r: 0, g: 0.68, b: 2.9960785, a: 1} + - _Color2nd: {r: 1, g: 1, b: 1, a: 1} + - _Color3rd: {r: 1, g: 1, b: 1, a: 1} + - _CustomLightDirection: {r: 0, g: 0, b: 10, a: 0} + - _DissolveColor: {r: 1, g: 1, b: 1, a: 1} + - _DissolveNoiseMask_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _DissolveParams: {r: 0, g: 0, b: 0.5, a: 0.1} + - _DissolvePos: {r: 0, g: 0, b: 0, a: 0} + - _DistanceFade: {r: 0.1, g: 0.01, b: 0, a: 0} + - _DistanceFadeColor: {r: 0, g: 0, b: 0, a: 1} + - _DistanceFadeRimColor: {r: 0, g: 0, b: 0, a: 0} + - _Emission2ndBlendMask_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _Emission2ndBlink: {r: 0, g: 0, b: 3.141593, a: 0} + - _Emission2ndColor: {r: 1, g: 1, b: 1, a: 1} + - _Emission2ndMap_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _EmissionBlendMask_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _EmissionBlink: {r: 0, g: 0, b: 3.141593, a: 0} + - _EmissionColor: {r: 1, g: 1, b: 1, a: 1} + - _EmissionMap_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _GemEnvColor: {r: 1, g: 1, b: 1, a: 1} + - _GemParticleColor: {r: 4, g: 4, b: 4, a: 1} + - _GlitterAtras: {r: 1, g: 1, b: 0, a: 0} + - _GlitterColor: {r: 1, g: 1, b: 1, a: 1} + - _GlitterParams1: {r: 256, g: 256, b: 0.16, a: 50} + - _GlitterParams2: {r: 0.25, g: 0, b: 0, a: 0} + - _GlossColor: {r: 1, g: 1, b: 1, a: 1} + - _Glow_Color: {r: 1, g: 1, b: 1, a: 1} + - _HighlightColor: {r: 0, g: 0.020439148, b: 1, a: 1} + - _Keys: {r: 0, g: 0, b: 0, a: 0} + - _LightDirectionOverride: {r: 0, g: 0.001, b: 0, a: 0} + - _Main2ndDissolveColor: {r: 1, g: 1, b: 1, a: 1} + - _Main2ndDissolveNoiseMask_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _Main2ndDissolveParams: {r: 0, g: 0, b: 0.5, a: 0.1} + - _Main2ndDissolvePos: {r: 0, g: 0, b: 0, a: 0} + - _Main2ndDistanceFade: {r: 0.1, g: 0.01, b: 0, a: 0} + - _Main2ndTexDecalAnimation: {r: 1, g: 1, b: 1, a: 30} + - _Main2ndTexDecalSubParam: {r: 1, g: 1, b: 0, a: 1} + - _Main2ndTex_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _Main3rdDissolveColor: {r: 1, g: 1, b: 1, a: 1} + - _Main3rdDissolveNoiseMask_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _Main3rdDissolveParams: {r: 0, g: 0, b: 0.5, a: 0.1} + - _Main3rdDissolvePos: {r: 0, g: 0, b: 0, a: 0} + - _Main3rdDistanceFade: {r: 0.1, g: 0.01, b: 0, a: 0} + - _Main3rdTexDecalAnimation: {r: 1, g: 1, b: 1, a: 30} + - _Main3rdTexDecalSubParam: {r: 1, g: 1, b: 0, a: 1} + - _Main3rdTex_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _MainColor: {r: 1, g: 1, b: 1, a: 1} + - _MainTexHSVG: {r: 0, g: 1, b: 1, a: 1} + - _MainTex_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _MatCap2ndBlendUV1: {r: 0, g: 0, b: 0, a: 0} + - _MatCap2ndColor: {r: 1, g: 1, b: 1, a: 1} + - _MatCapBlendUV1: {r: 0, g: 0, b: 0, a: 0} + - _MatCapColor: {r: 1, g: 1, b: 1, a: 1} + - _ObjPosi: {r: 0, g: 0, b: 0, a: 0} + - _ObjectForward: {r: 0, g: 0, b: 0, a: 0} + - _ObjectRight: {r: 0, g: 0, b: 0, a: 0} + - _OutResi: {r: 1, g: 1, b: 1, a: 1} + - _OutlineColor: {r: 0.6, g: 0.56, b: 0.73, a: 1} + - _OutlineLitColor: {r: 1, g: 0.19999996, b: 0, a: 0} + - _OutlineOffset: {r: 0, g: 0, b: 0, a: 1} + - _OutlineTexHSVG: {r: 0, g: 1, b: 1, a: 1} + - _OutlineTex_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _OverallShadowColor: {r: 0, g: 0, b: 0, a: 1} + - _PTCol: {r: 0, g: 0, b: 0, a: 1} + - _PrevPosition: {r: 0, g: 0, b: 0, a: 0} + - _ReflectionColor: {r: 1, g: 1, b: 1, a: 1} + - _ReflectionCubeColor: {r: 0, g: 0, b: 0, a: 1} + - _RimColor: {r: 1, g: 1, b: 1, a: 1} + - _RimIndirColor: {r: 1, g: 1, b: 1, a: 1} + - _RimLigPosi: {r: 1, g: 1, b: 1, a: 1} + - _RimLightColor: {r: 1, g: 1, b: 1, a: 1} + - _RimShadeColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} + - _SSAOColor: {r: 0, g: 0, b: 0, a: 0} + - _SelfLitColor: {r: 1, g: 1, b: 1, a: 1} + - _SelfShadowRealTimeShadowColor: {r: 1, g: 1, b: 1, a: 1} + - _Shadow2ndColor: {r: 0, g: 0, b: 0, a: 0} + - _Shadow3rdColor: {r: 0, g: 0, b: 0, a: 0} + - _ShadowAOShift: {r: 1, g: 0, b: 1, a: 0} + - _ShadowAOShift2: {r: 1, g: 0, b: 1, a: 0} + - _ShadowBorderColor: {r: 1, g: 0, b: 0, a: 1} + - _ShadowColor: {r: 0.7, g: 0.75, b: 0.85, a: 1} + - _ShadowTColor: {r: 1, g: 1, b: 1, a: 1} + - _XYZPosition: {r: 0, g: 0, b: 0, a: 0} + - _e2ga0: {r: 1, g: 0, b: 0, a: 0} + - _e2ga1: {r: 1, g: 0, b: 0, a: 1} + - _e2ga2: {r: 1, g: 0, b: 0, a: 0} + - _e2ga3: {r: 1, g: 0, b: 0, a: 0} + - _e2ga4: {r: 1, g: 0, b: 0, a: 0} + - _e2ga5: {r: 1, g: 0, b: 0, a: 0} + - _e2ga6: {r: 1, g: 0, b: 0, a: 0} + - _e2ga7: {r: 1, g: 0, b: 0, a: 0} + - _e2gc0: {r: 1, g: 1, b: 1, a: 0} + - _e2gc1: {r: 1, g: 1, b: 1, a: 1} + - _e2gc2: {r: 1, g: 1, b: 1, a: 0} + - _e2gc3: {r: 1, g: 1, b: 1, a: 0} + - _e2gc4: {r: 1, g: 1, b: 1, a: 0} + - _e2gc5: {r: 1, g: 1, b: 1, a: 0} + - _e2gc6: {r: 1, g: 1, b: 1, a: 0} + - _e2gc7: {r: 1, g: 1, b: 1, a: 0} + - _ega0: {r: 1, g: 0, b: 0, a: 0} + - _ega1: {r: 1, g: 0, b: 0, a: 1} + - _ega2: {r: 1, g: 0, b: 0, a: 0} + - _ega3: {r: 1, g: 0, b: 0, a: 0} + - _ega4: {r: 1, g: 0, b: 0, a: 0} + - _ega5: {r: 1, g: 0, b: 0, a: 0} + - _ega6: {r: 1, g: 0, b: 0, a: 0} + - _ega7: {r: 1, g: 0, b: 0, a: 0} + - _egc0: {r: 1, g: 1, b: 1, a: 0} + - _egc1: {r: 1, g: 1, b: 1, a: 1} + - _egc2: {r: 1, g: 1, b: 1, a: 0} + - _egc3: {r: 1, g: 1, b: 1, a: 0} + - _egc4: {r: 1, g: 1, b: 1, a: 0} + - _egc5: {r: 1, g: 1, b: 1, a: 0} + - _egc6: {r: 1, g: 1, b: 1, a: 0} + - _egc7: {r: 1, g: 1, b: 1, a: 0} + m_BuildTextureStacks: [] + m_AllowLocking: 1 diff --git a/Assets/04_Models/Characters/Fariy/Materials/Komono/Jewel_Blue.mat.meta b/Assets/04_Models/Characters/Fariy/Materials/Komono/Jewel_Blue.mat.meta new file mode 100644 index 00000000..285ec83e --- /dev/null +++ b/Assets/04_Models/Characters/Fariy/Materials/Komono/Jewel_Blue.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 54d340b7837b65346af0333fa5c8f9a8 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/04_Models/Characters/Fariy/Materials/Komono/Metal_Gold.mat b/Assets/04_Models/Characters/Fariy/Materials/Komono/Metal_Gold.mat new file mode 100644 index 00000000..1f6e9ce1 --- /dev/null +++ b/Assets/04_Models/Characters/Fariy/Materials/Komono/Metal_Gold.mat @@ -0,0 +1,996 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 8 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: Metal_Gold + m_Shader: {fileID: 4800000, guid: 6459b2db96a08ca41b0f9b39dc7ad59e, type: 3} + m_Parent: {fileID: 0} + m_ModifiedSerializedProperties: 0 + m_ValidKeywords: + - N_F_DDMD_ON + - N_F_EAL_ON + - N_F_O_ON + - N_F_RDC_ON + - N_F_RELGI_ON + - N_F_SS_ON + - N_F_TRANSAFFSHA_ON + - _UVSET_UV0 + m_InvalidKeywords: [] + m_LightmapFlags: 0 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: -1 + stringTagMap: {} + disabledShaderPasses: [] + m_LockedProperties: + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _AlphaMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _AnisotropyScaleMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _AnisotropyShiftNoiseMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _AnisotropyTangentMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _AudioLinkLocalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _AudioLinkMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BacklightColorTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BaseColorMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BaseMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Bump2ndMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Bump2ndScaleMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DissolveMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DissolveNoiseMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DitherTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Emission2ndBlendMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Emission2ndGradTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Emission2ndMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionBlendMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionGradTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _FReflection: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _GlitterColorTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _GlitterShapeTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _GlossTexture: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MCap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MCapMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main2ndBlendMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main2ndDissolveMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main2ndDissolveNoiseMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main2ndTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main3rdBlendMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main3rdDissolveMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main3rdDissolveNoiseMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main3rdTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainColorAdjustMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainGradationTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MaskGloss: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MaskReflection: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MaskSelfLit: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MaskTransparency: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MatCap2ndBlendMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MatCap2ndBumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MatCap2ndTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MatCapBlendMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MatCapBumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MatCapTex: + m_Texture: {fileID: 2800000, guid: a06ed8ab718f1884fa52fe010de1c3c7, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _NormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OutlineTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OutlineVectorTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OutlineWidthControl: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OutlineWidthMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _PTexture: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ReflectionColorTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ReflectionCubeTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _RimColorTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _RimShadeMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _SecondaryCutout: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Shadow2ndColorTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Shadow3rdColorTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ShadowBlurMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ShadowBorderMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ShadowColorTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ShadowColorTexture: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ShadowStrengthMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ShadowT: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _SmoothnessTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Ints: [] + m_Floats: + - _AAS: 0.0001 + - _AAStrength: 1 + - _AlpToCov: 0 + - _AlphaBaseCutout: 1 + - _AlphaBoostFA: 10 + - _AlphaMaskMode: 0 + - _AlphaMaskScale: 1 + - _AlphaMaskValue: 0 + - _AlphaToMask: 0 + - _Anisotropy2MatCap: 0 + - _Anisotropy2MatCap2nd: 0 + - _Anisotropy2Reflection: 0 + - _Anisotropy2ndBitangentWidth: 1 + - _Anisotropy2ndShift: 0 + - _Anisotropy2ndShiftNoiseScale: 0 + - _Anisotropy2ndSpecularStrength: 0 + - _Anisotropy2ndTangentWidth: 1 + - _AnisotropyBitangentWidth: 1 + - _AnisotropyScale: 1 + - _AnisotropyShift: 0 + - _AnisotropyShiftNoiseScale: 0 + - _AnisotropySpecularStrength: 1 + - _AnisotropyTangentWidth: 1 + - _ApplyReflection: 0 + - _ApplySpecular: 1 + - _ApplySpecularFA: 1 + - _AsOverlay: 0 + - _AsUnlit: 0 + - _AudioLink2Emission: 0 + - _AudioLink2Emission2nd: 0 + - _AudioLink2Emission2ndGrad: 0 + - _AudioLink2EmissionGrad: 0 + - _AudioLink2Main2nd: 0 + - _AudioLink2Main3rd: 0 + - _AudioLink2Vertex: 0 + - _AudioLinkAsLocal: 0 + - _AudioLinkMask_UVMode: 0 + - _AudioLinkUVMode: 1 + - _AudioLinkVertexUVMode: 1 + - _BackfaceForceShadow: 0 + - _BacklightBackfaceMask: 1 + - _BacklightBlur: 0.05 + - _BacklightBorder: 0.35 + - _BacklightDirectivity: 5 + - _BacklightMainStrength: 0 + - _BacklightNormalStrength: 1 + - _BacklightReceiveShadow: 1 + - _BacklightViewStrength: 1 + - _BeforeExposureLimit: 10000 + - _BitKey0: 0 + - _BitKey1: 0 + - _BitKey10: 0 + - _BitKey11: 0 + - _BitKey12: 0 + - _BitKey13: 0 + - _BitKey14: 0 + - _BitKey15: 0 + - _BitKey16: 0 + - _BitKey17: 0 + - _BitKey18: 0 + - _BitKey19: 0 + - _BitKey2: 0 + - _BitKey20: 0 + - _BitKey21: 0 + - _BitKey22: 0 + - _BitKey23: 0 + - _BitKey24: 0 + - _BitKey25: 0 + - _BitKey26: 0 + - _BitKey27: 0 + - _BitKey28: 0 + - _BitKey29: 0 + - _BitKey3: 0 + - _BitKey30: 0 + - _BitKey31: 0 + - _BitKey4: 0 + - _BitKey5: 0 + - _BitKey6: 0 + - _BitKey7: 0 + - _BitKey8: 0 + - _BitKey9: 0 + - _BleModDest: 0 + - _BleModSour: 1 + - _BlendOp: 0 + - _BlendOpAlpha: 0 + - _BlendOpAlphaFA: 4 + - _BlendOpFA: 4 + - _Bump2ndMap_UVMode: 0 + - _Bump2ndScale: 1 + - _BumpScale: 1 + - _ClipAdju: 0 + - _ColorMask: 15 + - _Compa: 4 + - _ComputeMeshIndex: 0 + - _Cull: 0 + - _Culling: 2 + - _CustomLightDirectionFollowObjectRotation: 0 + - _CustomLightDirectionIntensity: 0 + - _Cutoff: 0.5 + - _Cutout: 0.5 + - _DepthThreshold: 900 + - _DirectionalLightIntensity: 1 + - _DissolveNoiseStrength: 0.1 + - _DistanceFadeMode: 0 + - _DistanceFadeRimFresnelPower: 5 + - _DitherMaxValue: 255 + - _DoubleSidedOutline: 1 + - _DstBlend: 0 + - _DstBlendAlpha: 10 + - _DstBlendAlphaFA: 1 + - _DstBlendFA: 1 + - _DummyProperty: 0 + - _DynamicNoisyOutline: 0 + - _Emission2ndBlend: 1 + - _Emission2ndBlendMode: 1 + - _Emission2ndFluorescence: 0 + - _Emission2ndGradSpeed: 1 + - _Emission2ndMainStrength: 0 + - _Emission2ndMap_UVMode: 0 + - _Emission2ndParallaxDepth: 0 + - _Emission2ndUseGrad: 0 + - _EmissionBlend: 1 + - _EmissionBlendMode: 1 + - _EmissionFluorescence: 0 + - _EmissionGradSpeed: 1 + - _EmissionMainStrength: 0 + - _EmissionMap_UVMode: 0 + - _EmissionParallaxDepth: 0 + - _EmissionUseGrad: 0 + - _EnvironmentalLightingIntensity: 1 + - _FarDistanceMaxWidth: 10 + - _FlipNormal: 0 + - _GIFlatShade: 0 + - _GIShadeThreshold: 0 + - _GSAAStrength: 0 + - _GlitterAngleRandomize: 0 + - _GlitterApplyShape: 0 + - _GlitterApplyTransparency: 1 + - _GlitterBackfaceMask: 0 + - _GlitterColorTex_UVMode: 0 + - _GlitterEnableLighting: 1 + - _GlitterMainStrength: 0 + - _GlitterNormalStrength: 1 + - _GlitterPostContrast: 1 + - _GlitterScaleRandomize: 0 + - _GlitterSensitivity: 0.25 + - _GlitterShadowMask: 0 + - _GlitterUVMode: 0 + - _GlitterVRParallaxStrength: 1 + - _GlossColorPower: 10 + - _GlossIntensity: 1 + - _GlossSoftness: 0 + - _GlossTextureFollowLight: 0 + - _GlossTextureFollowObjectRotation: 0 + - _GlossTextureRotate: 0 + - _GlossTextureSoftness: 0 + - _Glossiness: 0.6 + - _Glow_Edge_Width: 1 + - _HighlightColorPower: 2 + - _IDMask1: 0 + - _IDMask2: 0 + - _IDMask3: 0 + - _IDMask4: 0 + - _IDMask5: 0 + - _IDMask6: 0 + - _IDMask7: 0 + - _IDMask8: 0 + - _IDMaskCompile: 0 + - _IDMaskControlsDissolve: 0 + - _IDMaskFrom: 8 + - _IDMaskIndex1: 0 + - _IDMaskIndex2: 0 + - _IDMaskIndex3: 0 + - _IDMaskIndex4: 0 + - _IDMaskIndex5: 0 + - _IDMaskIndex6: 0 + - _IDMaskIndex7: 0 + - _IDMaskIndex8: 0 + - _IDMaskIsBitmap: 0 + - _IDMaskPrior1: 0 + - _IDMaskPrior2: 0 + - _IDMaskPrior3: 0 + - _IDMaskPrior4: 0 + - _IDMaskPrior5: 0 + - _IDMaskPrior6: 0 + - _IDMaskPrior7: 0 + - _IDMaskPrior8: 0 + - _IgnoreEncryption: 0 + - _Invisible: 0 + - _LLI_Max: 1 + - _LLI_Min: 0 + - _LigIgnoYNorDir: 0 + - _LightAffectOutlineColor: 0 + - _LightAffectRimLightColor: 0 + - _LightAffectShadow: 0 + - _LightFalloffAffectShadowT: 0 + - _LightFalloffSoftness: 1 + - _LightIntensity: 1 + - _LightMaxLimit: 1 + - _LightMinLimit: 0.05 + - _MCIALO: 0 + - _MCapIntensity: 1 + - _MVCOL: 0 + - _MaiColPo: 0.8 + - _Main2ndDissolveNoiseStrength: 0.1 + - _Main2ndEnableLighting: 1 + - _Main2ndTexAlphaMode: 0 + - _Main2ndTexAngle: 0 + - _Main2ndTexBlendMode: 0 + - _Main2ndTexIsDecal: 0 + - _Main2ndTexIsLeftOnly: 0 + - _Main2ndTexIsMSDF: 0 + - _Main2ndTexIsRightOnly: 0 + - _Main2ndTexShouldCopy: 0 + - _Main2ndTexShouldFlipCopy: 0 + - _Main2ndTexShouldFlipMirror: 0 + - _Main2ndTex_Cull: 0 + - _Main2ndTex_UVMode: 0 + - _Main3rdDissolveNoiseStrength: 0.1 + - _Main3rdEnableLighting: 1 + - _Main3rdTexAlphaMode: 0 + - _Main3rdTexAngle: 0 + - _Main3rdTexBlendMode: 0 + - _Main3rdTexIsDecal: 0 + - _Main3rdTexIsLeftOnly: 0 + - _Main3rdTexIsMSDF: 0 + - _Main3rdTexIsRightOnly: 0 + - _Main3rdTexShouldCopy: 0 + - _Main3rdTexShouldFlipCopy: 0 + - _Main3rdTexShouldFlipMirror: 0 + - _Main3rdTex_Cull: 0 + - _Main3rdTex_UVMode: 0 + - _MainGradationStrength: 0 + - _MatCap2ndApplyTransparency: 1 + - _MatCap2ndBackfaceMask: 0 + - _MatCap2ndBlend: 1 + - _MatCap2ndBlendMode: 1 + - _MatCap2ndBumpScale: 1 + - _MatCap2ndCustomNormal: 0 + - _MatCap2ndEnableLighting: 1 + - _MatCap2ndLod: 0 + - _MatCap2ndMainStrength: 0 + - _MatCap2ndNormalStrength: 1 + - _MatCap2ndPerspective: 1 + - _MatCap2ndShadowMask: 0 + - _MatCap2ndVRParallaxStrength: 1 + - _MatCap2ndZRotCancel: 1 + - _MatCapApplyTransparency: 1 + - _MatCapBackfaceMask: 0 + - _MatCapBlend: 1 + - _MatCapBlendMode: 3 + - _MatCapBumpScale: 1 + - _MatCapCustomNormal: 0 + - _MatCapEnableLighting: 0 + - _MatCapLod: 0 + - _MatCapMainStrength: 0 + - _MatCapNormalStrength: 1 + - _MatCapPerspective: 1 + - _MatCapShadowMask: 0 + - _MatCapVRParallaxStrength: 1 + - _MatCapZRotCancel: 1 + - _MaxFadDistance: 2 + - _Metallic: 0 + - _MinFadDistance: 0 + - _MixMainTexToOutline: 0 + - _MonochromeLighting: 0 + - _N_F_ANIS: 0 + - _N_F_CA: 0 + - _N_F_CLD: 0 + - _N_F_CO: 0 + - _N_F_COEDGL: 0 + - _N_F_DCS: 0 + - _N_F_DDMD: 1 + - _N_F_EAL: 1 + - _N_F_ESSAO: 0 + - _N_F_FR: 0 + - _N_F_GLO: 0 + - _N_F_GLOT: 0 + - _N_F_HDLS: 0 + - _N_F_HPSS: 0 + - _N_F_LLI: 0 + - _N_F_MC: 0 + - _N_F_MSSOLTFO: 0 + - _N_F_NFD: 0 + - _N_F_NLASOBF: 0 + - _N_F_NM: 0 + - _N_F_O: 1 + - _N_F_OFLMB: 0 + - _N_F_PA: 0 + - _N_F_PT: 0 + - _N_F_R: 0 + - _N_F_RDC: 1 + - _N_F_RL: 0 + - _N_F_RLIS: 0 + - _N_F_SCO: 0 + - _N_F_SCT: 0 + - _N_F_SE: 0 + - _N_F_SL: 0 + - _N_F_SLMM: 0 + - _N_F_SON: 0 + - _N_F_SS: 1 + - _N_F_ST: 0 + - _N_F_STIAL: 0 + - _N_F_STIS: 0 + - _N_F_STSDFM: 0 + - _N_F_TP: 0 + - _NoiTexAffStraWidt: 0 + - _NoisTexInten: 1 + - _NoiseSize: 100 + - _NoisyOutlineIntensity: 0 + - _NorMapAsDis: 0 + - _NormalMapIntensity: 1 + - _ObjePosiZCS: 0 + - _OffsetFactor: 0 + - _OffsetUnits: 0 + - _Opacity: 1 + - _Oper: 0 + - _OutStenPass: 0 + - _OutZTest: 4 + - _OutZWrite: 1 + - _OutlineAlphaToMask: 0 + - _OutlineBlendOp: 0 + - _OutlineBlendOpAlpha: 0 + - _OutlineBlendOpAlphaFA: 4 + - _OutlineBlendOpFA: 4 + - _OutlineColorMask: 15 + - _OutlineCull: 1 + - _OutlineDeleteMesh: 0 + - _OutlineDisableInVR: 0 + - _OutlineDstBlend: 0 + - _OutlineDstBlendAlpha: 10 + - _OutlineDstBlendAlphaFA: 1 + - _OutlineDstBlendFA: 1 + - _OutlineEnableLighting: 1 + - _OutlineExtrudeMethod: 0 + - _OutlineFixWidth: 0.5 + - _OutlineLitApplyTex: 0 + - _OutlineLitOffset: -8 + - _OutlineLitScale: 10 + - _OutlineLitShadowReceive: 0 + - _OutlineOffsetFactor: 0 + - _OutlineOffsetUnits: 0 + - _OutlineSrcBlend: 1 + - _OutlineSrcBlendAlpha: 1 + - _OutlineSrcBlendAlphaFA: 0 + - _OutlineSrcBlendFA: 1 + - _OutlineStencilComp: 8 + - _OutlineStencilFail: 0 + - _OutlineStencilPass: 0 + - _OutlineStencilReadMask: 255 + - _OutlineStencilRef: 0 + - _OutlineStencilWriteMask: 255 + - _OutlineStencilZFail: 0 + - _OutlineVectorScale: 1 + - _OutlineVectorUVMode: 0 + - _OutlineVertexR2Width: 0 + - _OutlineWidth: 0.08 + - _OutlineWidthAffectedByViewDistance: 0 + - _OutlineZBias: 0 + - _OutlineZClip: 1 + - _OutlineZPostionInCamera: 0 + - _OutlineZTest: 2 + - _OutlineZWrite: 1 + - _OverallShadowColorPower: 1 + - _PADist: 0 + - _PASize: 0.5 + - _PASmooTrans: 1 + - _PSGLOTEX: 0 + - _PTexturePower: 1 + - _Parallax: 0.02 + - _ParallaxOffset: 0.5 + - _PointSpotlightIntensity: 1 + - _PresAdju: 1 + - _RELG: 1 + - _RQSO: 0 + - _ReduSha: 0.5 + - _RefMetallic: 0 + - _RefVal: 0 + - _Reflectance: 0.04 + - _ReflectionApplyTransparency: 1 + - _ReflectionBlendMode: 1 + - _ReflectionCubeEnableLighting: 1 + - _ReflectionCubeOverride: 0 + - _ReflectionIntensity: 0 + - _ReflectionNormalStrength: 1 + - _RimApplyTransparency: 1 + - _RimBackfaceMask: 0 + - _RimBlendMode: 1 + - _RimBlur: 0.1 + - _RimBorder: 0.5 + - _RimDirRange: 0 + - _RimDirStrength: 0 + - _RimEnableLighting: 1 + - _RimFresnelPower: 3 + - _RimIndirBlur: 0.1 + - _RimIndirBorder: 0.5 + - _RimIndirRange: 0 + - _RimLigInt: 1 + - _RimLightColorPower: 10 + - _RimLightInLight: 1 + - _RimLightSoftness: 1 + - _RimLightUnfill: 1.5 + - _RimMainStrength: 0 + - _RimNormalStrength: 1 + - _RimShadeBlur: 1 + - _RimShadeBorder: 0.5 + - _RimShadeFresnelPower: 1 + - _RimShadeNormalStrength: 1 + - _RimShadowMask: 0 + - _RimVRParallaxStrength: 1 + - _SPECIN: 1 + - _SPECMODE: 0 + - _STIL: 0 + - _Saturation: 1 + - _SelfLitHighContrast: 1 + - _SelfLitIntensity: 0 + - _SelfLitPower: 2 + - _SelfShadowAffectedByLightShadowStrength: 0 + - _SelfShadowHardness: 1 + - _SelfShadowRealTimeShadowColorPower: 1 + - _SelfShadowRealtimeShadowIntensity: 0 + - _SelfShadowShadowTAtViewDirection: 0 + - _SelfShadowThreshold: 0.93 + - _Shadow2ndBlur: 0.3 + - _Shadow2ndBorder: 0.5 + - _Shadow2ndNormalStrength: 1 + - _Shadow2ndReceive: 0 + - _Shadow3rdBlur: 0.1 + - _Shadow3rdBorder: 0.25 + - _Shadow3rdNormalStrength: 1 + - _Shadow3rdReceive: 0 + - _ShadowBlur: 0.1 + - _ShadowBlurMaskLOD: 0 + - _ShadowBorder: 0.1 + - _ShadowBorderMaskLOD: 0 + - _ShadowBorderRange: 0 + - _ShadowColorTexturePower: 0 + - _ShadowColorType: 0 + - _ShadowEnvStrength: 0 + - _ShadowFlatBlur: 1 + - _ShadowFlatBorder: 1 + - _ShadowHardness: 0 + - _ShadowMainStrength: 1 + - _ShadowMaskType: 0 + - _ShadowNormalStrength: 1 + - _ShadowPostAO: 0 + - _ShadowReceive: 0 + - _ShadowStrength: 1 + - _ShadowStrengthMaskLOD: 0 + - _ShadowTColorPower: 1 + - _ShadowTHardness: 1 + - _ShadowTIntensity: 1 + - _ShadowTLightThreshold: 50 + - _ShadowTShadowThreshold: 0 + - _ShifAnis: 0 + - _ShiftBackfaceUV: 0 + - _ShowInAmbientLightShadowIntensity: 1 + - _ShowInAmbientLightShadowThreshold: 0.4 + - _ShowNormal: 0 + - _SimTrans: 0 + - _SkinMatrixIndex: 0 + - _SmoothObjectNormal: 0 + - _Smoothness: 1 + - _SpecularBlur: 0 + - _SpecularBorder: 0.5 + - _SpecularNormalStrength: 1 + - _SpecularToon: 1 + - _SrcBlend: 1 + - _SrcBlendAlpha: 1 + - _SrcBlendAlphaFA: 0 + - _SrcBlendFA: 1 + - _StencilComp: 8 + - _StencilFail: 0 + - _StencilPass: 0 + - _StencilReadMask: 255 + - _StencilRef: 0 + - _StencilWriteMask: 255 + - _StencilZFail: 0 + - _StraWidt: 10 + - _SubpassCutoff: 0.5 + - _TEXMCOLINT: 1 + - _TRANSMODE: 0 + - _TessEdge: 10 + - _TessFactorMax: 3 + - _TessShrink: 0 + - _TessStrength: 0.5 + - _TessellationFar: 1 + - _TessellationNear: 1 + - _TessellationSmoothness: 0.5 + - _TessellationTransition: 0.8 + - _TexturePatternStyle: 0 + - _TrailSize: 1.5 + - _TransAffSha: 1 + - _TransparentMode: 0 + - _TransparentThreshold: 0 + - _TriPlaBlend: 4 + - _TriPlaTile: 1 + - _UDIMDiscardCompile: 0 + - _UDIMDiscardMode: 0 + - _UDIMDiscardRow0_0: 0 + - _UDIMDiscardRow0_1: 0 + - _UDIMDiscardRow0_2: 0 + - _UDIMDiscardRow0_3: 0 + - _UDIMDiscardRow1_0: 0 + - _UDIMDiscardRow1_1: 0 + - _UDIMDiscardRow1_2: 0 + - _UDIMDiscardRow1_3: 0 + - _UDIMDiscardRow2_0: 0 + - _UDIMDiscardRow2_1: 0 + - _UDIMDiscardRow2_2: 0 + - _UDIMDiscardRow2_3: 0 + - _UDIMDiscardRow3_0: 0 + - _UDIMDiscardRow3_1: 0 + - _UDIMDiscardRow3_2: 0 + - _UDIMDiscardRow3_3: 0 + - _UDIMDiscardUV: 0 + - _UVSet: 0 + - _UseAnisotropy: 0 + - _UseAudioLink: 0 + - _UseBacklight: 0 + - _UseBump2ndMap: 0 + - _UseBumpMap: 0 + - _UseClippingCanceller: 0 + - _UseDither: 0 + - _UseEmission: 0 + - _UseEmission2nd: 0 + - _UseGlitter: 0 + - _UseMain2ndTex: 0 + - _UseMain3rdTex: 0 + - _UseMatCap: 1 + - _UseMatCap2nd: 0 + - _UseOutline: 0 + - _UsePOM: 0 + - _UseParallax: 0 + - _UseReflection: 0 + - _UseRim: 0 + - _UseRimShade: 0 + - _UseSecondaryCutout: 0 + - _UseShadow: 0 + - _UseTLB: 0 + - _VertexColorBlueAffectOutlineWitdh: 0 + - _VertexColorGreenControlSelfShadowThreshold: 0 + - _VertexColorRedControlSmoothObjectNormal: 0 + - _VertexLightStrength: 0 + - _ZClip: 1 + - _ZTest: 4 + - _ZWrite: 1 + - _e2gai: 2 + - _e2gci: 2 + - _egai: 2 + - _egci: 2 + - _lilDirectionalLightStrength: 1 + - _lilShadowCasterBias: 0 + - _lilToonVersion: 42 + m_Colors: + - _AudioLinkDefaultValue: {r: 0, g: 0, b: 2, a: 0.75} + - _AudioLinkLocalMapParams: {r: 120, g: 1, b: 0, a: 0} + - _AudioLinkMask_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _AudioLinkStart: {r: 0, g: 0, b: 0, a: 0} + - _AudioLinkUVParams: {r: 0.25, g: 0, b: 0, a: 0.125} + - _AudioLinkVertexStart: {r: 0, g: 0, b: 0, a: 0} + - _AudioLinkVertexStrength: {r: 0, g: 0, b: 0, a: 1} + - _AudioLinkVertexUVParams: {r: 0.25, g: 0, b: 0, a: 0.125} + - _BackfaceColor: {r: 0, g: 0, b: 0, a: 0} + - _BacklightColor: {r: 0.85, g: 0.8, b: 0.7, a: 1} + - _BaseColor: {r: 1, g: 0.7405456, b: 0, a: 1} + - _Color: {r: 1, g: 0.7405456, b: 0, a: 1} + - _Color2nd: {r: 1, g: 1, b: 1, a: 1} + - _Color3rd: {r: 1, g: 1, b: 1, a: 1} + - _CustomLightDirection: {r: 0, g: 0, b: 10, a: 0} + - _DissolveColor: {r: 1, g: 1, b: 1, a: 1} + - _DissolveNoiseMask_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _DissolveParams: {r: 0, g: 0, b: 0.5, a: 0.1} + - _DissolvePos: {r: 0, g: 0, b: 0, a: 0} + - _DistanceFade: {r: 0.1, g: 0.01, b: 0, a: 0} + - _DistanceFadeColor: {r: 0, g: 0, b: 0, a: 1} + - _DistanceFadeRimColor: {r: 0, g: 0, b: 0, a: 0} + - _Emission2ndBlendMask_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _Emission2ndBlink: {r: 0, g: 0, b: 3.141593, a: 0} + - _Emission2ndColor: {r: 1, g: 1, b: 1, a: 1} + - _Emission2ndMap_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _EmissionBlendMask_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _EmissionBlink: {r: 0, g: 0, b: 3.141593, a: 0} + - _EmissionColor: {r: 1, g: 1, b: 1, a: 1} + - _EmissionMap_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _GlitterAtras: {r: 1, g: 1, b: 0, a: 0} + - _GlitterColor: {r: 1, g: 1, b: 1, a: 1} + - _GlitterParams1: {r: 256, g: 256, b: 0.16, a: 50} + - _GlitterParams2: {r: 0.25, g: 0, b: 0, a: 0} + - _GlossColor: {r: 1, g: 1, b: 1, a: 1} + - _Glow_Color: {r: 1, g: 1, b: 1, a: 1} + - _HighlightColor: {r: 0, g: 0.045587063, b: 1, a: 1} + - _Keys: {r: 0, g: 0, b: 0, a: 0} + - _LightDirectionOverride: {r: 0, g: 0.001, b: 0, a: 0} + - _Main2ndDissolveColor: {r: 1, g: 1, b: 1, a: 1} + - _Main2ndDissolveNoiseMask_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _Main2ndDissolveParams: {r: 0, g: 0, b: 0.5, a: 0.1} + - _Main2ndDissolvePos: {r: 0, g: 0, b: 0, a: 0} + - _Main2ndDistanceFade: {r: 0.1, g: 0.01, b: 0, a: 0} + - _Main2ndTexDecalAnimation: {r: 1, g: 1, b: 1, a: 30} + - _Main2ndTexDecalSubParam: {r: 1, g: 1, b: 0, a: 1} + - _Main2ndTex_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _Main3rdDissolveColor: {r: 1, g: 1, b: 1, a: 1} + - _Main3rdDissolveNoiseMask_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _Main3rdDissolveParams: {r: 0, g: 0, b: 0.5, a: 0.1} + - _Main3rdDissolvePos: {r: 0, g: 0, b: 0, a: 0} + - _Main3rdDistanceFade: {r: 0.1, g: 0.01, b: 0, a: 0} + - _Main3rdTexDecalAnimation: {r: 1, g: 1, b: 1, a: 30} + - _Main3rdTexDecalSubParam: {r: 1, g: 1, b: 0, a: 1} + - _Main3rdTex_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _MainColor: {r: 1, g: 1, b: 1, a: 1} + - _MainTexHSVG: {r: 0, g: 1, b: 1, a: 1} + - _MainTex_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _MatCap2ndBlendUV1: {r: 0, g: 0, b: 0, a: 0} + - _MatCap2ndColor: {r: 1, g: 1, b: 1, a: 1} + - _MatCapBlendUV1: {r: 0, g: 0, b: 0, a: 0} + - _MatCapColor: {r: 2.9960785, g: 2.9960785, b: 2.9960785, a: 1} + - _ObjPosi: {r: 0, g: 0, b: 0, a: 0} + - _ObjectForward: {r: 0, g: 0, b: 0, a: 0} + - _ObjectRight: {r: 0, g: 0, b: 0, a: 0} + - _OutResi: {r: 1, g: 1, b: 1, a: 1} + - _OutlineColor: {r: 0.6, g: 0.56, b: 0.73, a: 1} + - _OutlineLitColor: {r: 1, g: 0.19999996, b: 0, a: 0} + - _OutlineOffset: {r: 0, g: 0, b: 0, a: 1} + - _OutlineTexHSVG: {r: 0, g: 1, b: 1, a: 1} + - _OutlineTex_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _OverallShadowColor: {r: 0, g: 0, b: 0, a: 1} + - _PTCol: {r: 0, g: 0, b: 0, a: 1} + - _PrevPosition: {r: 0, g: 0, b: 0, a: 0} + - _ReflectionColor: {r: 1, g: 1, b: 1, a: 1} + - _ReflectionCubeColor: {r: 0, g: 0, b: 0, a: 1} + - _RimColor: {r: 1, g: 1, b: 1, a: 1} + - _RimIndirColor: {r: 1, g: 1, b: 1, a: 1} + - _RimLigPosi: {r: 1, g: 1, b: 1, a: 1} + - _RimLightColor: {r: 1, g: 1, b: 1, a: 1} + - _RimShadeColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} + - _SSAOColor: {r: 0, g: 0, b: 0, a: 0} + - _SelfLitColor: {r: 1, g: 1, b: 1, a: 1} + - _SelfShadowRealTimeShadowColor: {r: 1, g: 1, b: 1, a: 1} + - _Shadow2ndColor: {r: 0, g: 0, b: 0, a: 0} + - _Shadow3rdColor: {r: 0, g: 0, b: 0, a: 0} + - _ShadowAOShift: {r: 1, g: 0, b: 1, a: 0} + - _ShadowAOShift2: {r: 1, g: 0, b: 1, a: 0} + - _ShadowBorderColor: {r: 1, g: 0, b: 0, a: 1} + - _ShadowColor: {r: 0.7, g: 0.75, b: 0.85, a: 1} + - _ShadowTColor: {r: 1, g: 1, b: 1, a: 1} + - _XYZPosition: {r: 0, g: 0, b: 0, a: 0} + - _e2ga0: {r: 1, g: 0, b: 0, a: 0} + - _e2ga1: {r: 1, g: 0, b: 0, a: 1} + - _e2ga2: {r: 1, g: 0, b: 0, a: 0} + - _e2ga3: {r: 1, g: 0, b: 0, a: 0} + - _e2ga4: {r: 1, g: 0, b: 0, a: 0} + - _e2ga5: {r: 1, g: 0, b: 0, a: 0} + - _e2ga6: {r: 1, g: 0, b: 0, a: 0} + - _e2ga7: {r: 1, g: 0, b: 0, a: 0} + - _e2gc0: {r: 1, g: 1, b: 1, a: 0} + - _e2gc1: {r: 1, g: 1, b: 1, a: 1} + - _e2gc2: {r: 1, g: 1, b: 1, a: 0} + - _e2gc3: {r: 1, g: 1, b: 1, a: 0} + - _e2gc4: {r: 1, g: 1, b: 1, a: 0} + - _e2gc5: {r: 1, g: 1, b: 1, a: 0} + - _e2gc6: {r: 1, g: 1, b: 1, a: 0} + - _e2gc7: {r: 1, g: 1, b: 1, a: 0} + - _ega0: {r: 1, g: 0, b: 0, a: 0} + - _ega1: {r: 1, g: 0, b: 0, a: 1} + - _ega2: {r: 1, g: 0, b: 0, a: 0} + - _ega3: {r: 1, g: 0, b: 0, a: 0} + - _ega4: {r: 1, g: 0, b: 0, a: 0} + - _ega5: {r: 1, g: 0, b: 0, a: 0} + - _ega6: {r: 1, g: 0, b: 0, a: 0} + - _ega7: {r: 1, g: 0, b: 0, a: 0} + - _egc0: {r: 1, g: 1, b: 1, a: 0} + - _egc1: {r: 1, g: 1, b: 1, a: 1} + - _egc2: {r: 1, g: 1, b: 1, a: 0} + - _egc3: {r: 1, g: 1, b: 1, a: 0} + - _egc4: {r: 1, g: 1, b: 1, a: 0} + - _egc5: {r: 1, g: 1, b: 1, a: 0} + - _egc6: {r: 1, g: 1, b: 1, a: 0} + - _egc7: {r: 1, g: 1, b: 1, a: 0} + m_BuildTextureStacks: [] + m_AllowLocking: 1 diff --git a/Assets/04_Models/Characters/Fariy/Materials/Komono/Metal_Gold.mat.meta b/Assets/04_Models/Characters/Fariy/Materials/Komono/Metal_Gold.mat.meta new file mode 100644 index 00000000..288b9d33 --- /dev/null +++ b/Assets/04_Models/Characters/Fariy/Materials/Komono/Metal_Gold.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: d65d67af019c21e4090c03f494b1958c +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/04_Models/Characters/Fariy/Materials/wing_effects.mat b/Assets/04_Models/Characters/Fariy/Materials/wing_effects.mat new file mode 100644 index 00000000..947fd2ef --- /dev/null +++ b/Assets/04_Models/Characters/Fariy/Materials/wing_effects.mat @@ -0,0 +1,137 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 8 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: wing_effects + m_Shader: {fileID: 4800000, guid: 0406db5a14f94604a8c57ccfbc9f3b46, type: 3} + m_Parent: {fileID: 0} + m_ModifiedSerializedProperties: 0 + m_ValidKeywords: + - _SURFACE_TYPE_TRANSPARENT + m_InvalidKeywords: + - _ALPHABLEND_ON + - _FLIPBOOKBLENDING_OFF + m_LightmapFlags: 0 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: 3000 + stringTagMap: + RenderType: Transparent + disabledShaderPasses: + - GRABPASS + - DepthOnly + - SHADOWCASTER + m_LockedProperties: + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _BaseMap: + m_Texture: {fileID: 2800000, guid: df447867c7b49b44eafa9aa27d119770, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailAlbedoMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 2800000, guid: df447867c7b49b44eafa9aa27d119770, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OcclusionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Ints: [] + m_Floats: + - _AlphaClip: 0 + - _AlphaToMask: 0 + - _Blend: 0 + - _BlendOp: 0 + - _BumpScale: 1 + - _CameraFadingEnabled: 0 + - _CameraFarFadeDistance: 2 + - _CameraNearFadeDistance: 1 + - _ColorMode: 0 + - _Cull: 2 + - _Cutoff: 0.759 + - _DetailNormalMapScale: 1 + - _DistortionBlend: 0.5 + - _DistortionEnabled: 0 + - _DistortionStrength: 1 + - _DistortionStrengthScaled: 0 + - _DstBlend: 10 + - _DstBlendAlpha: 10 + - _EmissionEnabled: 0 + - _FlipbookBlending: 0 + - _FlipbookMode: 0 + - _GlossMapScale: 1 + - _Glossiness: 0.5 + - _GlossyReflections: 1 + - _LightingEnabled: 0 + - _Metallic: 0 + - _Mode: 2 + - _OcclusionStrength: 1 + - _Parallax: 0.02 + - _QueueOffset: 0 + - _SmoothnessTextureChannel: 0 + - _SoftParticlesEnabled: 0 + - _SoftParticlesFarFadeDistance: 1 + - _SoftParticlesNearFadeDistance: 0 + - _SpecularHighlights: 1 + - _SrcBlend: 5 + - _SrcBlendAlpha: 1 + - _Surface: 1 + - _UVSec: 0 + - _ZWrite: 0 + m_Colors: + - _BaseColor: {r: 1.3041189, g: 1.3041189, b: 1.3041189, a: 1} + - _BaseColorAddSubDiff: {r: 0, g: 0, b: 0, a: 0} + - _CameraFadeParams: {r: 0, g: Infinity, b: 0, a: 0} + - _Color: {r: 1.3041189, g: 1.3041189, b: 1.3041189, a: 1} + - _ColorAddSubDiff: {r: 0, g: 0, b: 0, a: 0} + - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} + - _SoftParticleFadeParams: {r: 0, g: 0, b: 0, a: 0} + m_BuildTextureStacks: [] + m_AllowLocking: 1 +--- !u!114 &7416825320795440829 +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: Unity.RenderPipelines.Universal.Editor::UnityEditor.Rendering.Universal.AssetVersion + version: 10 diff --git a/Assets/04_Models/Characters/Fariy/Materials/wing_effects.mat.meta b/Assets/04_Models/Characters/Fariy/Materials/wing_effects.mat.meta new file mode 100644 index 00000000..9919ad27 --- /dev/null +++ b/Assets/04_Models/Characters/Fariy/Materials/wing_effects.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 03eb55f12985e7a489f93579fdf8ce07 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/04_Models/Characters/Fariy/Materials/wing_mat.mat b/Assets/04_Models/Characters/Fariy/Materials/wing_mat.mat new file mode 100644 index 00000000..d6e0b933 --- /dev/null +++ b/Assets/04_Models/Characters/Fariy/Materials/wing_mat.mat @@ -0,0 +1,1027 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 8 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: wing_mat + m_Shader: {fileID: 4800000, guid: 6459b2db96a08ca41b0f9b39dc7ad59e, type: 3} + m_Parent: {fileID: 0} + m_ModifiedSerializedProperties: 0 + m_ValidKeywords: + - N_F_DDMD_ON + - N_F_EAL_ON + - N_F_LLI_ON + - N_F_O_ON + - N_F_RDC_ON + - N_F_RELGI_ON + - N_F_SS_ON + - N_F_TRANSAFFSHA_ON + - _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A + - _UVSET_UV0 + m_InvalidKeywords: + - UNITY_UI_CLIP_RECT + - _EMISSION + - _METALLICGLOSSMAP + - _REQUIRE_UV2 + - _SPECGLOSSMAP + m_LightmapFlags: 0 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: -1 + stringTagMap: {} + disabledShaderPasses: [] + m_LockedProperties: + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _AlphaMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _AnisotropyScaleMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _AnisotropyShiftNoiseMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _AnisotropyTangentMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _AudioLinkLocalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _AudioLinkMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BacklightColorTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BaseColorMap: + m_Texture: {fileID: 2800000, guid: cc50bff8e08ffa649877aa0890e95edf, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BaseMap: + m_Texture: {fileID: 2800000, guid: cc50bff8e08ffa649877aa0890e95edf, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Bump2ndMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Bump2ndScaleMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailAlbedoMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DissolveMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DissolveNoiseMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DitherTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Emission2ndBlendMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Emission2ndGradTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Emission2ndMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionBlendMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionGradTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 2800000, guid: cc50bff8e08ffa649877aa0890e95edf, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _FReflection: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _GlitterColorTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _GlitterShapeTex: + m_Texture: {fileID: 2800000, guid: 6432d6f480a91aa4aa2ae56c90a08961, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _GlossTexture: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MCap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MCapMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main2ndBlendMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main2ndDissolveMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main2ndDissolveNoiseMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main2ndTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main3rdBlendMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main3rdDissolveMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main3rdDissolveNoiseMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main3rdTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainColorAdjustMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainGradationTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 2800000, guid: cc50bff8e08ffa649877aa0890e95edf, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MaskGloss: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MaskReflection: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MaskSelfLit: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MaskTransparency: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MatCap2ndBlendMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MatCap2ndBumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MatCap2ndTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MatCapBlendMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MatCapBumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MatCapTex: + m_Texture: {fileID: 2800000, guid: 7d34b02ec05d5a44c8a3e592ea8a3c3e, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _NormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OcclusionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OutlineTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OutlineVectorTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OutlineWidthControl: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OutlineWidthMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _PTexture: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ReflectionColorTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ReflectionCubeTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _RimColorTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _RimShadeMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _SecondaryCutout: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Shadow2ndColorTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Shadow3rdColorTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ShadowBlurMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ShadowBorderMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ShadowColorTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ShadowColorTexture: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ShadowStrengthMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ShadowT: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _SmoothnessTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Ints: [] + m_Floats: + - _AAS: 0.0001 + - _AAStrength: 1 + - _AlpToCov: 0 + - _AlphaBaseCutout: 1 + - _AlphaBoostFA: 10 + - _AlphaMaskMode: 0 + - _AlphaMaskScale: 1 + - _AlphaMaskValue: 0 + - _AlphaToMask: 0 + - _Anisotropy2MatCap: 0 + - _Anisotropy2MatCap2nd: 0 + - _Anisotropy2Reflection: 0 + - _Anisotropy2ndBitangentWidth: 1 + - _Anisotropy2ndShift: 0 + - _Anisotropy2ndShiftNoiseScale: 0 + - _Anisotropy2ndSpecularStrength: 0 + - _Anisotropy2ndTangentWidth: 1 + - _AnisotropyBitangentWidth: 1 + - _AnisotropyScale: 1 + - _AnisotropyShift: 0 + - _AnisotropyShiftNoiseScale: 0 + - _AnisotropySpecularStrength: 1 + - _AnisotropyTangentWidth: 1 + - _ApplyReflection: 0 + - _ApplySpecular: 1 + - _ApplySpecularFA: 1 + - _AsOverlay: 0 + - _AsUnlit: 0 + - _AudioLink2Emission: 0 + - _AudioLink2Emission2nd: 0 + - _AudioLink2Emission2ndGrad: 0 + - _AudioLink2EmissionGrad: 0 + - _AudioLink2Main2nd: 0 + - _AudioLink2Main3rd: 0 + - _AudioLink2Vertex: 0 + - _AudioLinkAsLocal: 0 + - _AudioLinkMask_UVMode: 0 + - _AudioLinkUVMode: 1 + - _AudioLinkVertexUVMode: 1 + - _BackfaceForceShadow: 1 + - _BacklightBackfaceMask: 1 + - _BacklightBlur: 0.05 + - _BacklightBorder: 0.35 + - _BacklightDirectivity: 5 + - _BacklightMainStrength: 0 + - _BacklightNormalStrength: 1 + - _BacklightReceiveShadow: 1 + - _BacklightViewStrength: 1 + - _BeforeExposureLimit: 10000 + - _BitKey0: 0 + - _BitKey1: 0 + - _BitKey10: 0 + - _BitKey11: 0 + - _BitKey12: 0 + - _BitKey13: 0 + - _BitKey14: 0 + - _BitKey15: 0 + - _BitKey16: 0 + - _BitKey17: 0 + - _BitKey18: 0 + - _BitKey19: 0 + - _BitKey2: 0 + - _BitKey20: 0 + - _BitKey21: 0 + - _BitKey22: 0 + - _BitKey23: 0 + - _BitKey24: 0 + - _BitKey25: 0 + - _BitKey26: 0 + - _BitKey27: 0 + - _BitKey28: 0 + - _BitKey29: 0 + - _BitKey3: 0 + - _BitKey30: 0 + - _BitKey31: 0 + - _BitKey4: 0 + - _BitKey5: 0 + - _BitKey6: 0 + - _BitKey7: 0 + - _BitKey8: 0 + - _BitKey9: 0 + - _BleModDest: 0 + - _BleModSour: 1 + - _BlendOp: 0 + - _BlendOpAlpha: 0 + - _BlendOpAlphaFA: 4 + - _BlendOpFA: 4 + - _Bump2ndMap_UVMode: 0 + - _Bump2ndScale: 1 + - _BumpScale: 1 + - _ClipAdju: 0 + - _ColorMask: 15 + - _Compa: 4 + - _ComputeMeshIndex: 0 + - _Cull: 0 + - _Culling: 2 + - _CustomLightDirectionFollowObjectRotation: 0 + - _CustomLightDirectionIntensity: 0 + - _Cutoff: -0.001 + - _Cutout: 0.5 + - _DepthThreshold: 900 + - _DetailNormalMapScale: 1 + - _DirectionalLightIntensity: 0.8 + - _DissolveNoiseStrength: 0.1 + - _DistanceFadeMode: 0 + - _DistanceFadeRimFresnelPower: 5 + - _DitherMaxValue: 255 + - _DoubleSidedOutline: 1 + - _DstBlend: 10 + - _DstBlendAlpha: 10 + - _DstBlendAlphaFA: 1 + - _DstBlendFA: 1 + - _DummyProperty: 0 + - _DynamicNoisyOutline: 0 + - _Emission2ndBlend: 1 + - _Emission2ndBlendMode: 1 + - _Emission2ndFluorescence: 0 + - _Emission2ndGradSpeed: 1 + - _Emission2ndMainStrength: 0 + - _Emission2ndMap_UVMode: 0 + - _Emission2ndParallaxDepth: 0 + - _Emission2ndUseGrad: 0 + - _EmissionBlend: 1 + - _EmissionBlendMode: 1 + - _EmissionFluorescence: 0 + - _EmissionGradSpeed: 1 + - _EmissionMainStrength: 1 + - _EmissionMap_UVMode: 0 + - _EmissionParallaxDepth: 0 + - _EmissionUseGrad: 0 + - _EnvironmentalLightingIntensity: 1 + - _FarDistanceMaxWidth: 10 + - _FlipNormal: 0 + - _GIFlatShade: 0 + - _GIShadeThreshold: 0 + - _GSAAStrength: 0 + - _GlitterAngleRandomize: 0 + - _GlitterApplyShape: 1 + - _GlitterApplyTransparency: 1 + - _GlitterBackfaceMask: 0 + - _GlitterColorTex_UVMode: 0 + - _GlitterEnableLighting: 1 + - _GlitterMainStrength: 1 + - _GlitterNormalStrength: 1 + - _GlitterPostContrast: 1 + - _GlitterScaleRandomize: 1 + - _GlitterSensitivity: 0.9545943 + - _GlitterShadowMask: 0 + - _GlitterUVMode: 0 + - _GlitterVRParallaxStrength: 0 + - _GlossColorPower: 10 + - _GlossIntensity: 1 + - _GlossMapScale: 1 + - _GlossSoftness: 0 + - _GlossTextureFollowLight: 0 + - _GlossTextureFollowObjectRotation: 0 + - _GlossTextureRotate: 0 + - _GlossTextureSoftness: 0 + - _Glossiness: 0.25123277 + - _GlossyReflections: 1 + - _Glow_Edge_Width: 1 + - _HighlightColorPower: 4 + - _IDMask1: 0 + - _IDMask2: 0 + - _IDMask3: 0 + - _IDMask4: 0 + - _IDMask5: 0 + - _IDMask6: 0 + - _IDMask7: 0 + - _IDMask8: 0 + - _IDMaskCompile: 0 + - _IDMaskControlsDissolve: 0 + - _IDMaskFrom: 8 + - _IDMaskIndex1: 0 + - _IDMaskIndex2: 0 + - _IDMaskIndex3: 0 + - _IDMaskIndex4: 0 + - _IDMaskIndex5: 0 + - _IDMaskIndex6: 0 + - _IDMaskIndex7: 0 + - _IDMaskIndex8: 0 + - _IDMaskIsBitmap: 0 + - _IDMaskPrior1: 0 + - _IDMaskPrior2: 0 + - _IDMaskPrior3: 0 + - _IDMaskPrior4: 0 + - _IDMaskPrior5: 0 + - _IDMaskPrior6: 0 + - _IDMaskPrior7: 0 + - _IDMaskPrior8: 0 + - _IgnoreEncryption: 0 + - _Invisible: 0 + - _LLI_Max: 3 + - _LLI_Min: 1 + - _LigIgnoYNorDir: 0 + - _LightAffectOutlineColor: 0 + - _LightAffectRimLightColor: 0 + - _LightAffectShadow: 0 + - _LightFalloffAffectShadowT: 0 + - _LightFalloffSoftness: 1 + - _LightIntensity: 1 + - _LightMaxLimit: 1 + - _LightMinLimit: 0.05 + - _MCIALO: 0 + - _MCapIntensity: 1 + - _MVCOL: 0 + - _MaiColPo: 1 + - _Main2ndDissolveNoiseStrength: 0.1 + - _Main2ndEnableLighting: 1 + - _Main2ndTexAlphaMode: 0 + - _Main2ndTexAngle: 0 + - _Main2ndTexBlendMode: 0 + - _Main2ndTexIsDecal: 0 + - _Main2ndTexIsLeftOnly: 0 + - _Main2ndTexIsMSDF: 0 + - _Main2ndTexIsRightOnly: 0 + - _Main2ndTexShouldCopy: 0 + - _Main2ndTexShouldFlipCopy: 0 + - _Main2ndTexShouldFlipMirror: 0 + - _Main2ndTex_Cull: 0 + - _Main2ndTex_UVMode: 0 + - _Main3rdDissolveNoiseStrength: 0.1 + - _Main3rdEnableLighting: 1 + - _Main3rdTexAlphaMode: 0 + - _Main3rdTexAngle: 0 + - _Main3rdTexBlendMode: 0 + - _Main3rdTexIsDecal: 0 + - _Main3rdTexIsLeftOnly: 0 + - _Main3rdTexIsMSDF: 0 + - _Main3rdTexIsRightOnly: 0 + - _Main3rdTexShouldCopy: 0 + - _Main3rdTexShouldFlipCopy: 0 + - _Main3rdTexShouldFlipMirror: 0 + - _Main3rdTex_Cull: 0 + - _Main3rdTex_UVMode: 0 + - _MainGradationStrength: 0 + - _MatCap2ndApplyTransparency: 1 + - _MatCap2ndBackfaceMask: 0 + - _MatCap2ndBlend: 1 + - _MatCap2ndBlendMode: 1 + - _MatCap2ndBumpScale: 1 + - _MatCap2ndCustomNormal: 0 + - _MatCap2ndEnableLighting: 1 + - _MatCap2ndLod: 0 + - _MatCap2ndMainStrength: 0 + - _MatCap2ndNormalStrength: 1 + - _MatCap2ndPerspective: 1 + - _MatCap2ndShadowMask: 0 + - _MatCap2ndVRParallaxStrength: 1 + - _MatCap2ndZRotCancel: 1 + - _MatCapApplyTransparency: 1 + - _MatCapBackfaceMask: 0 + - _MatCapBlend: 1 + - _MatCapBlendMode: 2 + - _MatCapBumpScale: 1 + - _MatCapCustomNormal: 0 + - _MatCapEnableLighting: 1 + - _MatCapLod: 0 + - _MatCapMainStrength: 0 + - _MatCapNormalStrength: 1 + - _MatCapPerspective: 1 + - _MatCapShadowMask: 0 + - _MatCapVRParallaxStrength: 1 + - _MatCapZRotCancel: 1 + - _MaxFadDistance: 2 + - _Metallic: 0 + - _MinFadDistance: 0 + - _MixMainTexToOutline: 0 + - _Mode: 0 + - _MonochromeLighting: 0 + - _N_F_ANIS: 0 + - _N_F_CA: 0 + - _N_F_CLD: 0 + - _N_F_CO: 0 + - _N_F_COEDGL: 0 + - _N_F_DCS: 0 + - _N_F_DDMD: 1 + - _N_F_EAL: 1 + - _N_F_ESSAO: 0 + - _N_F_FR: 0 + - _N_F_GLO: 0 + - _N_F_GLOT: 0 + - _N_F_HDLS: 0 + - _N_F_HPSS: 0 + - _N_F_LLI: 1 + - _N_F_MC: 0 + - _N_F_MSSOLTFO: 0 + - _N_F_NFD: 0 + - _N_F_NLASOBF: 0 + - _N_F_NM: 0 + - _N_F_O: 1 + - _N_F_OFLMB: 0 + - _N_F_PA: 0 + - _N_F_PT: 0 + - _N_F_R: 0 + - _N_F_RDC: 1 + - _N_F_RL: 0 + - _N_F_RLIS: 0 + - _N_F_SCO: 0 + - _N_F_SCT: 0 + - _N_F_SE: 0 + - _N_F_SL: 0 + - _N_F_SLMM: 0 + - _N_F_SON: 0 + - _N_F_SS: 1 + - _N_F_ST: 0 + - _N_F_STIAL: 0 + - _N_F_STIS: 0 + - _N_F_STSDFM: 0 + - _N_F_TP: 0 + - _NoiTexAffStraWidt: 0 + - _NoisTexInten: 1 + - _NoiseSize: 100 + - _NoisyOutlineIntensity: 0 + - _NorMapAsDis: 0 + - _NormalMapIntensity: 1 + - _ObjePosiZCS: 0 + - _OcclusionStrength: 1 + - _OffsetFactor: 0 + - _OffsetUnits: 0 + - _Opacity: 1 + - _Oper: 0 + - _OutStenPass: 0 + - _OutZTest: 4 + - _OutZWrite: 1 + - _OutlineAlphaToMask: 0 + - _OutlineBlendOp: 0 + - _OutlineBlendOpAlpha: 0 + - _OutlineBlendOpAlphaFA: 4 + - _OutlineBlendOpFA: 4 + - _OutlineColorMask: 15 + - _OutlineCull: 1 + - _OutlineDeleteMesh: 0 + - _OutlineDisableInVR: 0 + - _OutlineDstBlend: 10 + - _OutlineDstBlendAlpha: 10 + - _OutlineDstBlendAlphaFA: 1 + - _OutlineDstBlendFA: 1 + - _OutlineEnableLighting: 1 + - _OutlineExtrudeMethod: 0 + - _OutlineFixWidth: 0.5 + - _OutlineLitApplyTex: 0 + - _OutlineLitOffset: -8 + - _OutlineLitScale: 10 + - _OutlineLitShadowReceive: 0 + - _OutlineOffsetFactor: 0 + - _OutlineOffsetUnits: 0 + - _OutlineSrcBlend: 5 + - _OutlineSrcBlendAlpha: 1 + - _OutlineSrcBlendAlphaFA: 0 + - _OutlineSrcBlendFA: 1 + - _OutlineStencilComp: 6 + - _OutlineStencilFail: 0 + - _OutlineStencilPass: 0 + - _OutlineStencilReadMask: 255 + - _OutlineStencilRef: 1 + - _OutlineStencilWriteMask: 255 + - _OutlineStencilZFail: 0 + - _OutlineVectorScale: 1 + - _OutlineVectorUVMode: 0 + - _OutlineVertexR2Width: 0 + - _OutlineWidth: 0.22 + - _OutlineWidthAffectedByViewDistance: 0 + - _OutlineZBias: 0 + - _OutlineZClip: 1 + - _OutlineZPostionInCamera: 0 + - _OutlineZTest: 2 + - _OutlineZWrite: 1 + - _OverallShadowColorPower: 1 + - _PADist: 0 + - _PASize: 0.5 + - _PASmooTrans: 1 + - _PSGLOTEX: 0 + - _PTexturePower: 1 + - _Parallax: 0.02 + - _ParallaxOffset: 0.5 + - _PointSpotlightIntensity: 1 + - _PresAdju: 1 + - _RELG: 1 + - _RQSO: 0 + - _ReduSha: 0.5 + - _RefMetallic: 0 + - _RefVal: 0 + - _Reflectance: 0.04 + - _ReflectionApplyTransparency: 1 + - _ReflectionBlendMode: 1 + - _ReflectionCubeEnableLighting: 1 + - _ReflectionCubeOverride: 0 + - _ReflectionIntensity: 0 + - _ReflectionNormalStrength: 1 + - _RimApplyTransparency: 1 + - _RimBackfaceMask: 1 + - _RimBlendMode: 1 + - _RimBlur: 0.65 + - _RimBorder: 0.33999997 + - _RimDirRange: 0 + - _RimDirStrength: 0 + - _RimEnableLighting: 1 + - _RimFresnelPower: 3.5 + - _RimIndirBlur: 0.1 + - _RimIndirBorder: 0.5 + - _RimIndirRange: 0 + - _RimLigInt: 1 + - _RimLightColorPower: 10 + - _RimLightInLight: 1 + - _RimLightSoftness: 1 + - _RimLightUnfill: 1.5 + - _RimMainStrength: 0 + - _RimNormalStrength: 1 + - _RimShadeBlur: 1 + - _RimShadeBorder: 0.5 + - _RimShadeFresnelPower: 1 + - _RimShadeNormalStrength: 1 + - _RimShadowMask: 0.5 + - _RimVRParallaxStrength: 1 + - _SPECIN: 1 + - _SPECMODE: 0 + - _STIL: 0 + - _Saturation: 1 + - _SelfLitHighContrast: 1 + - _SelfLitIntensity: 0 + - _SelfLitPower: 2 + - _SelfShadowAffectedByLightShadowStrength: 0 + - _SelfShadowHardness: 1 + - _SelfShadowRealTimeShadowColorPower: 1 + - _SelfShadowRealtimeShadowIntensity: 0 + - _SelfShadowShadowTAtViewDirection: 0 + - _SelfShadowThreshold: 1 + - _Shadow2ndBlur: 0.1 + - _Shadow2ndBorder: 0.15 + - _Shadow2ndNormalStrength: 1 + - _Shadow2ndReceive: 0 + - _Shadow3rdBlur: 0.1 + - _Shadow3rdBorder: 0.25 + - _Shadow3rdNormalStrength: 1 + - _Shadow3rdReceive: 0 + - _ShadowBlur: 0 + - _ShadowBlurMaskLOD: 0 + - _ShadowBorder: 0.78 + - _ShadowBorderMaskLOD: 0 + - _ShadowBorderRange: 0.08 + - _ShadowColorTexturePower: 0 + - _ShadowColorType: 0 + - _ShadowEnvStrength: 0 + - _ShadowFlatBlur: 1 + - _ShadowFlatBorder: 1 + - _ShadowHardness: 0 + - _ShadowMainStrength: 0 + - _ShadowMaskType: 0 + - _ShadowNormalStrength: 1 + - _ShadowPostAO: 0 + - _ShadowReceive: 0 + - _ShadowStrength: 1 + - _ShadowStrengthMaskLOD: 0 + - _ShadowTColorPower: 1 + - _ShadowTHardness: 1 + - _ShadowTIntensity: 1 + - _ShadowTLightThreshold: 50 + - _ShadowTShadowThreshold: 0 + - _ShifAnis: 0 + - _ShiftBackfaceUV: 0 + - _ShowInAmbientLightShadowIntensity: 1 + - _ShowInAmbientLightShadowThreshold: 0.4 + - _ShowNormal: 0 + - _SimTrans: 0 + - _SkinMatrixIndex: 0 + - _SmoothObjectNormal: 0 + - _Smoothness: 1 + - _SmoothnessTextureChannel: 0 + - _SpecularBlur: 0 + - _SpecularBorder: 0.5 + - _SpecularHighlights: 1 + - _SpecularNormalStrength: 1 + - _SpecularToon: 1 + - _SrcBlend: 1 + - _SrcBlendAlpha: 1 + - _SrcBlendAlphaFA: 0 + - _SrcBlendFA: 1 + - _StencilComp: 6 + - _StencilFail: 0 + - _StencilPass: 0 + - _StencilReadMask: 255 + - _StencilRef: 1 + - _StencilWriteMask: 255 + - _StencilZFail: 0 + - _StraWidt: 10 + - _SubpassCutoff: 0.5 + - _TEXMCOLINT: 1 + - _TRANSMODE: 0 + - _TessEdge: 10 + - _TessFactorMax: 3 + - _TessShrink: 0 + - _TessStrength: 0.5 + - _TessellationFar: 1 + - _TessellationNear: 1 + - _TessellationSmoothness: 0.5 + - _TessellationTransition: 0.8 + - _TexturePatternStyle: 0 + - _TrailSize: 1.5 + - _TransAffSha: 1 + - _TransparentMode: 2 + - _TransparentThreshold: 0 + - _TriPlaBlend: 4 + - _TriPlaTile: 1 + - _UDIMDiscardCompile: 0 + - _UDIMDiscardMode: 0 + - _UDIMDiscardRow0_0: 0 + - _UDIMDiscardRow0_1: 0 + - _UDIMDiscardRow0_2: 0 + - _UDIMDiscardRow0_3: 0 + - _UDIMDiscardRow1_0: 0 + - _UDIMDiscardRow1_1: 0 + - _UDIMDiscardRow1_2: 0 + - _UDIMDiscardRow1_3: 0 + - _UDIMDiscardRow2_0: 0 + - _UDIMDiscardRow2_1: 0 + - _UDIMDiscardRow2_2: 0 + - _UDIMDiscardRow2_3: 0 + - _UDIMDiscardRow3_0: 0 + - _UDIMDiscardRow3_1: 0 + - _UDIMDiscardRow3_2: 0 + - _UDIMDiscardRow3_3: 0 + - _UDIMDiscardUV: 0 + - _UVSec: 0 + - _UVSet: 0 + - _UseAnisotropy: 0 + - _UseAudioLink: 0 + - _UseBacklight: 0 + - _UseBump2ndMap: 0 + - _UseBumpMap: 0 + - _UseClippingCanceller: 0 + - _UseDither: 0 + - _UseEmission: 1 + - _UseEmission2nd: 0 + - _UseGlitter: 1 + - _UseMain2ndTex: 0 + - _UseMain3rdTex: 0 + - _UseMatCap: 1 + - _UseMatCap2nd: 0 + - _UseOutline: 0 + - _UsePOM: 0 + - _UseParallax: 0 + - _UseReflection: 0 + - _UseRim: 1 + - _UseRimShade: 0 + - _UseSecondaryCutout: 0 + - _UseShadow: 1 + - _UseTLB: 0 + - _VertexColorBlueAffectOutlineWitdh: 0 + - _VertexColorGreenControlSelfShadowThreshold: 0 + - _VertexColorRedControlSmoothObjectNormal: 0 + - _VertexLightStrength: 0 + - _ZClip: 1 + - _ZTest: 4 + - _ZWrite: 1 + - _e2gai: 2 + - _e2gci: 2 + - _egai: 2 + - _egci: 2 + - _lilDirectionalLightStrength: 1 + - _lilShadowCasterBias: 0 + - _lilToonVersion: 44 + m_Colors: + - _AudioLinkDefaultValue: {r: 0, g: 0, b: 2, a: 0.75} + - _AudioLinkLocalMapParams: {r: 120, g: 1, b: 0, a: 0} + - _AudioLinkMask_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _AudioLinkStart: {r: 0, g: 0, b: 0, a: 0} + - _AudioLinkUVParams: {r: 0.25, g: 0, b: 0, a: 0.125} + - _AudioLinkVertexStart: {r: 0, g: 0, b: 0, a: 0} + - _AudioLinkVertexStrength: {r: 0, g: 0, b: 0, a: 1} + - _AudioLinkVertexUVParams: {r: 0.25, g: 0, b: 0, a: 0.125} + - _BackfaceColor: {r: 0, g: 0, b: 0, a: 0} + - _BacklightColor: {r: 0.85, g: 0.8, b: 0.7, a: 1} + - _BaseColor: {r: 1, g: 1, b: 1, a: 1} + - _Color: {r: 1, g: 1, b: 1, a: 1} + - _Color2nd: {r: 1, g: 1, b: 1, a: 1} + - _Color3rd: {r: 1, g: 1, b: 1, a: 1} + - _CustomLightDirection: {r: 0, g: 0, b: 10, a: 0} + - _DissolveColor: {r: 1, g: 1, b: 1, a: 1} + - _DissolveNoiseMask_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _DissolveParams: {r: 0, g: 0, b: 0.5, a: 0.1} + - _DissolvePos: {r: 0, g: 0, b: 0, a: 0} + - _DistanceFade: {r: 0.1, g: 0.01, b: 0, a: 0} + - _DistanceFadeColor: {r: 0, g: 0, b: 0, a: 1} + - _DistanceFadeRimColor: {r: 0, g: 0, b: 0, a: 0} + - _Emission2ndBlendMask_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _Emission2ndBlink: {r: 0, g: 0, b: 3.141593, a: 0} + - _Emission2ndColor: {r: 1, g: 1, b: 1, a: 1} + - _Emission2ndMap_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _EmissionBlendMask_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _EmissionBlink: {r: 0, g: 0, b: 3.141593, a: 0} + - _EmissionColor: {r: 1, g: 1, b: 1, a: 0.47} + - _EmissionMap_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _GlitterAtras: {r: 1, g: 1, b: 0, a: 0} + - _GlitterColor: {r: 1, g: 1, b: 1, a: 1} + - _GlitterParams1: {r: 256, g: 256, b: 1.4641001, a: 3.4293556} + - _GlitterParams2: {r: 0.25, g: 1.48, b: 0, a: 1} + - _GlossColor: {r: 1, g: 1, b: 1, a: 1} + - _Glow_Color: {r: 1, g: 1, b: 1, a: 1} + - _HighlightColor: {r: 0, g: 0.11449838, b: 1, a: 1} + - _Keys: {r: 0, g: 0, b: 0, a: 0} + - _LightDirectionOverride: {r: 0.001, g: 0.002, b: 0.001, a: 0} + - _Main2ndDissolveColor: {r: 1, g: 1, b: 1, a: 1} + - _Main2ndDissolveNoiseMask_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _Main2ndDissolveParams: {r: 0, g: 0, b: 0.5, a: 0.1} + - _Main2ndDissolvePos: {r: 0, g: 0, b: 0, a: 0} + - _Main2ndDistanceFade: {r: 0.1, g: 0.01, b: 0, a: 0} + - _Main2ndTexDecalAnimation: {r: 1, g: 1, b: 1, a: 30} + - _Main2ndTexDecalSubParam: {r: 1, g: 1, b: 0, a: 1} + - _Main2ndTex_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _Main3rdDissolveColor: {r: 1, g: 1, b: 1, a: 1} + - _Main3rdDissolveNoiseMask_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _Main3rdDissolveParams: {r: 0, g: 0, b: 0.5, a: 0.1} + - _Main3rdDissolvePos: {r: 0, g: 0, b: 0, a: 0} + - _Main3rdDistanceFade: {r: 0.1, g: 0.01, b: 0, a: 0} + - _Main3rdTexDecalAnimation: {r: 1, g: 1, b: 1, a: 30} + - _Main3rdTexDecalSubParam: {r: 1, g: 1, b: 0, a: 1} + - _Main3rdTex_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _MainColor: {r: 0.5339979, g: 0.5487908, b: 0.9056604, a: 1} + - _MainTexHSVG: {r: 0, g: 1, b: 1, a: 1} + - _MainTex_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _MatCap2ndBlendUV1: {r: 0, g: 0, b: 0, a: 0} + - _MatCap2ndColor: {r: 1, g: 1, b: 1, a: 1} + - _MatCapBlendUV1: {r: 0, g: 0, b: 0, a: 0} + - _MatCapColor: {r: 1, g: 1, b: 1, a: 0.19} + - _ObjPosi: {r: 0, g: 0, b: 0, a: 0} + - _ObjectForward: {r: 0, g: 0, b: 0, a: 0} + - _ObjectRight: {r: 0, g: 0, b: 0, a: 0} + - _OutResi: {r: 1, g: 1, b: 1, a: 1} + - _OutlineColor: {r: 0.16037738, g: 0.16037738, b: 0.16037738, a: 1} + - _OutlineLitColor: {r: 1, g: 0.19999996, b: 0, a: 0} + - _OutlineOffset: {r: 0, g: 0, b: 0, a: 1} + - _OutlineTexHSVG: {r: 0, g: 1, b: 1, a: 1} + - _OutlineTex_ScrollRotate: {r: 0, g: 0, b: 0, a: 0} + - _OverallShadowColor: {r: 0, g: 0, b: 0, a: 1} + - _PTCol: {r: 0, g: 0, b: 0, a: 1} + - _PrevPosition: {r: 0, g: 0, b: 0, a: 0} + - _ReflectionColor: {r: 1, g: 1, b: 1, a: 1} + - _ReflectionCubeColor: {r: 0, g: 0, b: 0, a: 1} + - _RimColor: {r: 0.9811321, g: 0.72659314, b: 0.884591, a: 1} + - _RimIndirColor: {r: 1, g: 1, b: 1, a: 1} + - _RimLigPosi: {r: 1, g: 1, b: 1, a: 1} + - _RimLightColor: {r: 1, g: 1, b: 1, a: 1} + - _RimShadeColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} + - _SSAOColor: {r: 0, g: 0, b: 0, a: 0} + - _SelfLitColor: {r: 1, g: 1, b: 1, a: 1} + - _SelfShadowRealTimeShadowColor: {r: 1, g: 1, b: 1, a: 1} + - _Shadow2ndColor: {r: 0.68, g: 0.65999997, b: 0.78999996, a: 1} + - _Shadow3rdColor: {r: 0, g: 0, b: 0, a: 0} + - _ShadowAOShift: {r: 1, g: 0, b: 1, a: 0} + - _ShadowAOShift2: {r: 1, g: 0, b: 1, a: 0} + - _ShadowBorderColor: {r: 1, g: 0.09999997, b: 0, a: 1} + - _ShadowColor: {r: 0.97538966, g: 0.9292453, b: 1, a: 1} + - _ShadowTColor: {r: 1, g: 1, b: 1, a: 1} + - _XYZPosition: {r: 0, g: 0, b: 0, a: 0} + - _e2ga0: {r: 1, g: 0, b: 0, a: 0} + - _e2ga1: {r: 1, g: 0, b: 0, a: 1} + - _e2ga2: {r: 1, g: 0, b: 0, a: 0} + - _e2ga3: {r: 1, g: 0, b: 0, a: 0} + - _e2ga4: {r: 1, g: 0, b: 0, a: 0} + - _e2ga5: {r: 1, g: 0, b: 0, a: 0} + - _e2ga6: {r: 1, g: 0, b: 0, a: 0} + - _e2ga7: {r: 1, g: 0, b: 0, a: 0} + - _e2gc0: {r: 1, g: 1, b: 1, a: 0} + - _e2gc1: {r: 1, g: 1, b: 1, a: 1} + - _e2gc2: {r: 1, g: 1, b: 1, a: 0} + - _e2gc3: {r: 1, g: 1, b: 1, a: 0} + - _e2gc4: {r: 1, g: 1, b: 1, a: 0} + - _e2gc5: {r: 1, g: 1, b: 1, a: 0} + - _e2gc6: {r: 1, g: 1, b: 1, a: 0} + - _e2gc7: {r: 1, g: 1, b: 1, a: 0} + - _ega0: {r: 1, g: 0, b: 0, a: 0} + - _ega1: {r: 1, g: 0, b: 0, a: 1} + - _ega2: {r: 1, g: 0, b: 0, a: 0} + - _ega3: {r: 1, g: 0, b: 0, a: 0} + - _ega4: {r: 1, g: 0, b: 0, a: 0} + - _ega5: {r: 1, g: 0, b: 0, a: 0} + - _ega6: {r: 1, g: 0, b: 0, a: 0} + - _ega7: {r: 1, g: 0, b: 0, a: 0} + - _egc0: {r: 1, g: 1, b: 1, a: 0} + - _egc1: {r: 1, g: 1, b: 1, a: 1} + - _egc2: {r: 1, g: 1, b: 1, a: 0} + - _egc3: {r: 1, g: 1, b: 1, a: 0} + - _egc4: {r: 1, g: 1, b: 1, a: 0} + - _egc5: {r: 1, g: 1, b: 1, a: 0} + - _egc6: {r: 1, g: 1, b: 1, a: 0} + - _egc7: {r: 1, g: 1, b: 1, a: 0} + m_BuildTextureStacks: [] + m_AllowLocking: 1 diff --git a/Assets/04_Models/Characters/Fariy/Materials/wing_mat.mat.meta b/Assets/04_Models/Characters/Fariy/Materials/wing_mat.mat.meta new file mode 100644 index 00000000..afd53122 --- /dev/null +++ b/Assets/04_Models/Characters/Fariy/Materials/wing_mat.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 6705337112664b647b77d78bb08704fb +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/04_Models/Characters/Fariy/Materials/wing_trail.mat b/Assets/04_Models/Characters/Fariy/Materials/wing_trail.mat new file mode 100644 index 00000000..b93931c5 --- /dev/null +++ b/Assets/04_Models/Characters/Fariy/Materials/wing_trail.mat @@ -0,0 +1,139 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &-6421258964859668105 +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: Unity.RenderPipelines.Universal.Editor::UnityEditor.Rendering.Universal.AssetVersion + version: 10 +--- !u!21 &2100000 +Material: + serializedVersion: 8 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: wing_trail + m_Shader: {fileID: 4800000, guid: 0406db5a14f94604a8c57ccfbc9f3b46, type: 3} + m_Parent: {fileID: 0} + m_ModifiedSerializedProperties: 0 + m_ValidKeywords: + - _FADING_ON + - _SOFTPARTICLES_ON + - _SURFACE_TYPE_TRANSPARENT + m_InvalidKeywords: + - _ALPHABLEND_ON + - _FLIPBOOKBLENDING_OFF + m_LightmapFlags: 0 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 1 + m_CustomRenderQueue: 3000 + stringTagMap: + RenderType: Transparent + disabledShaderPasses: + - GRABPASS + - DepthOnly + - SHADOWCASTER + m_LockedProperties: + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _BaseMap: + m_Texture: {fileID: 2800000, guid: a0025c0eef7b3f540b9f5e85a42dc557, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailAlbedoMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 2800000, guid: a0025c0eef7b3f540b9f5e85a42dc557, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OcclusionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Ints: [] + m_Floats: + - _AlphaClip: 0 + - _AlphaToMask: 0 + - _Blend: 0 + - _BlendOp: 0 + - _BumpScale: 1 + - _CameraFadingEnabled: 1 + - _CameraFarFadeDistance: 2 + - _CameraNearFadeDistance: 1 + - _ColorMode: 0 + - _Cull: 0 + - _Cutoff: 0.5 + - _DetailNormalMapScale: 1 + - _DistortionBlend: 0.5 + - _DistortionEnabled: 0 + - _DistortionStrength: 1 + - _DistortionStrengthScaled: 0 + - _DstBlend: 10 + - _DstBlendAlpha: 10 + - _EmissionEnabled: 0 + - _FlipbookBlending: 0 + - _FlipbookMode: 0 + - _GlossMapScale: 1 + - _Glossiness: 0 + - _GlossyReflections: 1 + - _LightingEnabled: 0 + - _Metallic: 0 + - _Mode: 2 + - _OcclusionStrength: 1 + - _Parallax: 0.02 + - _QueueOffset: 0 + - _SmoothnessTextureChannel: 0 + - _SoftParticlesEnabled: 1 + - _SoftParticlesFarFadeDistance: 1 + - _SoftParticlesNearFadeDistance: 0 + - _SpecularHighlights: 1 + - _SrcBlend: 5 + - _SrcBlendAlpha: 1 + - _Surface: 1 + - _UVSec: 0 + - _ZWrite: 0 + m_Colors: + - _BaseColor: {r: 0.9883372, g: 0.9883372, b: 0.9883372, a: 1} + - _BaseColorAddSubDiff: {r: 0, g: 0, b: 0, a: 0} + - _CameraFadeParams: {r: 1, g: 1, b: 0, a: 0} + - _Color: {r: 0.9883372, g: 0.9883372, b: 0.9883372, a: 1} + - _ColorAddSubDiff: {r: 0, g: 0, b: 0, a: 0} + - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} + - _SoftParticleFadeParams: {r: 0, g: 1, b: 0, a: 0} + m_BuildTextureStacks: [] + m_AllowLocking: 1 diff --git a/Assets/04_Models/Characters/Fariy/Materials/wing_trail.mat.meta b/Assets/04_Models/Characters/Fariy/Materials/wing_trail.mat.meta new file mode 100644 index 00000000..bab53ee1 --- /dev/null +++ b/Assets/04_Models/Characters/Fariy/Materials/wing_trail.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 8bfa74ea827894c4fb41b47df4ea083f +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/04_Models/Characters/Fariy/Textures.meta b/Assets/04_Models/Characters/Fariy/Textures.meta new file mode 100644 index 00000000..e2146cc5 --- /dev/null +++ b/Assets/04_Models/Characters/Fariy/Textures.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: fb2157b26ebfc2549b8862cdabc04f1c +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/04_Models/Characters/Fariy/Textures/Body_Hair.meta b/Assets/04_Models/Characters/Fariy/Textures/Body_Hair.meta new file mode 100644 index 00000000..64724786 --- /dev/null +++ b/Assets/04_Models/Characters/Fariy/Textures/Body_Hair.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 66642a4a0eddd064e834f9a45173bbb0 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/04_Models/Characters/Fariy/Textures/Body_Hair/Alistia_Body.png b/Assets/04_Models/Characters/Fariy/Textures/Body_Hair/Alistia_Body.png new file mode 100644 index 00000000..9032405d --- /dev/null +++ b/Assets/04_Models/Characters/Fariy/Textures/Body_Hair/Alistia_Body.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7041182aeb607bb48452f04ea52ea8ad78dbc932b153580407f4efcac8959151 +size 3557678 diff --git a/Assets/04_Models/Characters/Fariy/Textures/Body_Hair/Alistia_Body.png.meta b/Assets/04_Models/Characters/Fariy/Textures/Body_Hair/Alistia_Body.png.meta new file mode 100644 index 00000000..f1826f0f --- /dev/null +++ b/Assets/04_Models/Characters/Fariy/Textures/Body_Hair/Alistia_Body.png.meta @@ -0,0 +1,104 @@ +fileFormatVersion: 2 +guid: 38eb494fcb7511e49a5a0dafcb8aec73 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 11 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 1 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + applyGammaDecoding: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/04_Models/Characters/Fariy/Textures/Body_Hair/Alistia_Face.png b/Assets/04_Models/Characters/Fariy/Textures/Body_Hair/Alistia_Face.png new file mode 100644 index 00000000..27290621 --- /dev/null +++ b/Assets/04_Models/Characters/Fariy/Textures/Body_Hair/Alistia_Face.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6cd515b725dff72fcaa5eb7b54c4c7cfb68778d4b0b582163d2727e8fa11386f +size 2790895 diff --git a/Assets/04_Models/Characters/Fariy/Textures/Body_Hair/Alistia_Face.png.meta b/Assets/04_Models/Characters/Fariy/Textures/Body_Hair/Alistia_Face.png.meta new file mode 100644 index 00000000..6b65ae8f --- /dev/null +++ b/Assets/04_Models/Characters/Fariy/Textures/Body_Hair/Alistia_Face.png.meta @@ -0,0 +1,104 @@ +fileFormatVersion: 2 +guid: 59cc88e58da82534b9ef6df2b16d0789 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 11 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 1 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + applyGammaDecoding: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/04_Models/Characters/Fariy/Textures/Body_Hair/Alistia_Face_Alpha.png b/Assets/04_Models/Characters/Fariy/Textures/Body_Hair/Alistia_Face_Alpha.png new file mode 100644 index 00000000..722aed64 --- /dev/null +++ b/Assets/04_Models/Characters/Fariy/Textures/Body_Hair/Alistia_Face_Alpha.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3352d6899c049d8a5a66741d75015949aa91a661a1f430acb6638417b09dd7a1 +size 89734 diff --git a/Assets/04_Models/Characters/Fariy/Textures/Body_Hair/Alistia_Face_Alpha.png.meta b/Assets/04_Models/Characters/Fariy/Textures/Body_Hair/Alistia_Face_Alpha.png.meta new file mode 100644 index 00000000..9734bdba --- /dev/null +++ b/Assets/04_Models/Characters/Fariy/Textures/Body_Hair/Alistia_Face_Alpha.png.meta @@ -0,0 +1,104 @@ +fileFormatVersion: 2 +guid: e9127ca5d92e63940bdc0358062db97b +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 11 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 1 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + applyGammaDecoding: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/04_Models/Characters/Fariy/Textures/Body_Hair/Alistia_Face_mask.png b/Assets/04_Models/Characters/Fariy/Textures/Body_Hair/Alistia_Face_mask.png new file mode 100644 index 00000000..105e821d --- /dev/null +++ b/Assets/04_Models/Characters/Fariy/Textures/Body_Hair/Alistia_Face_mask.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6fd35c21129b82dcfa53e48e293344899c93d136464d0a9a903e95484141f207 +size 367919 diff --git a/Assets/04_Models/Characters/Fariy/Textures/Body_Hair/Alistia_Face_mask.png.meta b/Assets/04_Models/Characters/Fariy/Textures/Body_Hair/Alistia_Face_mask.png.meta new file mode 100644 index 00000000..d25a5284 --- /dev/null +++ b/Assets/04_Models/Characters/Fariy/Textures/Body_Hair/Alistia_Face_mask.png.meta @@ -0,0 +1,104 @@ +fileFormatVersion: 2 +guid: 513f256d33e4b294cb9a238d2ae516c4 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 11 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 1 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + applyGammaDecoding: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/04_Models/Characters/Fariy/Textures/Body_Hair/Alistia_Hair.png b/Assets/04_Models/Characters/Fariy/Textures/Body_Hair/Alistia_Hair.png new file mode 100644 index 00000000..727c4cae --- /dev/null +++ b/Assets/04_Models/Characters/Fariy/Textures/Body_Hair/Alistia_Hair.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6978b32a1f785dd2600303ea973c0b39e3d87c1627b8650447788a8fc8bf9a38 +size 4933039 diff --git a/Assets/04_Models/Characters/Fariy/Textures/Body_Hair/Alistia_Hair.png.meta b/Assets/04_Models/Characters/Fariy/Textures/Body_Hair/Alistia_Hair.png.meta new file mode 100644 index 00000000..068dc0a7 --- /dev/null +++ b/Assets/04_Models/Characters/Fariy/Textures/Body_Hair/Alistia_Hair.png.meta @@ -0,0 +1,104 @@ +fileFormatVersion: 2 +guid: d048c66387fa0bc4f9913dd2d7d7fa87 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 11 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 1 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + applyGammaDecoding: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/04_Models/Characters/Fariy/Textures/Body_Hair/Alistia_Hair_Mask.png b/Assets/04_Models/Characters/Fariy/Textures/Body_Hair/Alistia_Hair_Mask.png new file mode 100644 index 00000000..7a442e17 --- /dev/null +++ b/Assets/04_Models/Characters/Fariy/Textures/Body_Hair/Alistia_Hair_Mask.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ab0acd7324d89f54bf54b8f57df783c150c7d65694c93ae947ec304b9c9f2b38 +size 111582 diff --git a/Assets/04_Models/Characters/Fariy/Textures/Body_Hair/Alistia_Hair_Mask.png.meta b/Assets/04_Models/Characters/Fariy/Textures/Body_Hair/Alistia_Hair_Mask.png.meta new file mode 100644 index 00000000..1bee0ca0 --- /dev/null +++ b/Assets/04_Models/Characters/Fariy/Textures/Body_Hair/Alistia_Hair_Mask.png.meta @@ -0,0 +1,104 @@ +fileFormatVersion: 2 +guid: 782a9af2fc072c2419c418886e440f9d +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 11 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 1 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + applyGammaDecoding: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/04_Models/Characters/Fariy/Textures/Cloth.meta b/Assets/04_Models/Characters/Fariy/Textures/Cloth.meta new file mode 100644 index 00000000..11ed707c --- /dev/null +++ b/Assets/04_Models/Characters/Fariy/Textures/Cloth.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: dd660d0cb0cc18a40b108f321b2ddc32 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/04_Models/Characters/Fariy/Textures/Cloth/Alistia_Cloth_1_blue.png b/Assets/04_Models/Characters/Fariy/Textures/Cloth/Alistia_Cloth_1_blue.png new file mode 100644 index 00000000..0387a698 --- /dev/null +++ b/Assets/04_Models/Characters/Fariy/Textures/Cloth/Alistia_Cloth_1_blue.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:16757907c116513464c62a9f0fb8707c94eb74fede58b498ed2f8e44a90ffba3 +size 3965312 diff --git a/Assets/04_Models/Characters/Fariy/Textures/Cloth/Alistia_Cloth_1_blue.png.meta b/Assets/04_Models/Characters/Fariy/Textures/Cloth/Alistia_Cloth_1_blue.png.meta new file mode 100644 index 00000000..74374947 --- /dev/null +++ b/Assets/04_Models/Characters/Fariy/Textures/Cloth/Alistia_Cloth_1_blue.png.meta @@ -0,0 +1,104 @@ +fileFormatVersion: 2 +guid: 083e7f8c110fa364c817bb3c34f9fdeb +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 11 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 1 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + applyGammaDecoding: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/04_Models/Characters/Fariy/Textures/Cloth/Alistia_Cloth_2.png b/Assets/04_Models/Characters/Fariy/Textures/Cloth/Alistia_Cloth_2.png new file mode 100644 index 00000000..d612e01e --- /dev/null +++ b/Assets/04_Models/Characters/Fariy/Textures/Cloth/Alistia_Cloth_2.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a43a46fb311ef47ecac95fdb447e6ce1f4834c7aab3f133994589ec4046955df +size 5211285 diff --git a/Assets/04_Models/Characters/Fariy/Textures/Cloth/Alistia_Cloth_2.png.meta b/Assets/04_Models/Characters/Fariy/Textures/Cloth/Alistia_Cloth_2.png.meta new file mode 100644 index 00000000..ec2e7d97 --- /dev/null +++ b/Assets/04_Models/Characters/Fariy/Textures/Cloth/Alistia_Cloth_2.png.meta @@ -0,0 +1,104 @@ +fileFormatVersion: 2 +guid: 093a9db6b1fee594380cc05560ae5e8a +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 11 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 1 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + applyGammaDecoding: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/04_Models/Characters/Fariy/Textures/wing_effects_tex.png b/Assets/04_Models/Characters/Fariy/Textures/wing_effects_tex.png new file mode 100644 index 00000000..6d613d11 --- /dev/null +++ b/Assets/04_Models/Characters/Fariy/Textures/wing_effects_tex.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d6727dbfa2337db97c349c585fc8ac890394327bf640222eb1c9eece60aa4c50 +size 192023 diff --git a/Assets/04_Models/Characters/Fariy/Textures/wing_effects_tex.png.meta b/Assets/04_Models/Characters/Fariy/Textures/wing_effects_tex.png.meta new file mode 100644 index 00000000..bff26192 --- /dev/null +++ b/Assets/04_Models/Characters/Fariy/Textures/wing_effects_tex.png.meta @@ -0,0 +1,140 @@ +fileFormatVersion: 2 +guid: df447867c7b49b44eafa9aa27d119770 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 12 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Android + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Server + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/04_Models/Characters/Fariy/Textures/wing_mat_BaseMap.png b/Assets/04_Models/Characters/Fariy/Textures/wing_mat_BaseMap.png new file mode 100644 index 00000000..172a6630 --- /dev/null +++ b/Assets/04_Models/Characters/Fariy/Textures/wing_mat_BaseMap.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1373b7ff273cb2af36041f60e864786f5e31184781432ca68a98f98abd1f1111 +size 6062156 diff --git a/Assets/04_Models/Characters/Fariy/Textures/wing_mat_BaseMap.png.meta b/Assets/04_Models/Characters/Fariy/Textures/wing_mat_BaseMap.png.meta new file mode 100644 index 00000000..3bb8c96a --- /dev/null +++ b/Assets/04_Models/Characters/Fariy/Textures/wing_mat_BaseMap.png.meta @@ -0,0 +1,140 @@ +fileFormatVersion: 2 +guid: cc50bff8e08ffa649877aa0890e95edf +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 12 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Android + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Server + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/04_Models/Characters/Fariy/Textures/wing_matcap.png b/Assets/04_Models/Characters/Fariy/Textures/wing_matcap.png new file mode 100644 index 00000000..fb66a254 --- /dev/null +++ b/Assets/04_Models/Characters/Fariy/Textures/wing_matcap.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0bd82587588611b818d811b5d8c11057e4cb5d4774c0f2a19a56247deaab50e5 +size 2870852 diff --git a/Assets/04_Models/Characters/Fariy/Textures/wing_matcap.png.meta b/Assets/04_Models/Characters/Fariy/Textures/wing_matcap.png.meta new file mode 100644 index 00000000..69a69283 --- /dev/null +++ b/Assets/04_Models/Characters/Fariy/Textures/wing_matcap.png.meta @@ -0,0 +1,140 @@ +fileFormatVersion: 2 +guid: 7d34b02ec05d5a44c8a3e592ea8a3c3e +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 12 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Android + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Server + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/04_Models/Characters/Fariy/Textures/wing_trail_tex.png b/Assets/04_Models/Characters/Fariy/Textures/wing_trail_tex.png new file mode 100644 index 00000000..89860967 --- /dev/null +++ b/Assets/04_Models/Characters/Fariy/Textures/wing_trail_tex.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5a18bd6e03eba9cab09b12de07964e67d28d6068f82650bdc8c95895e9cb3642 +size 96215 diff --git a/Assets/04_Models/Characters/Fariy/Textures/wing_trail_tex.png.meta b/Assets/04_Models/Characters/Fariy/Textures/wing_trail_tex.png.meta new file mode 100644 index 00000000..9c49cf1b --- /dev/null +++ b/Assets/04_Models/Characters/Fariy/Textures/wing_trail_tex.png.meta @@ -0,0 +1,140 @@ +fileFormatVersion: 2 +guid: a0025c0eef7b3f540b9f5e85a42dc557 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 12 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Android + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Server + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/MagicaCloth2.meta b/Assets/MagicaCloth2.meta new file mode 100644 index 00000000..899bd46d --- /dev/null +++ b/Assets/MagicaCloth2.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: f31820b1e966ca049a982e2a30795d24 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/MagicaCloth2/Example (Can be deleted).meta b/Assets/MagicaCloth2/Example (Can be deleted).meta new file mode 100644 index 00000000..ea812ecc --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted).meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: b13ad20384f6dd8459a0ee155e8181f1 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/Common.meta b/Assets/MagicaCloth2/Example (Can be deleted)/Common.meta new file mode 100644 index 00000000..fcc83fdf --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/Common.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 791ca5043c61c164093a43f6e1134756 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/Common/Materials.meta b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Materials.meta new file mode 100644 index 00000000..d56df5f5 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Materials.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 319509eb5d501a04f8a0d2e3a8f5b0a0 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/Common/Materials/MC2_Floor.mat b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Materials/MC2_Floor.mat new file mode 100644 index 00000000..e75b1e12 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Materials/MC2_Floor.mat @@ -0,0 +1,202 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &-5413520746483021427 +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: da692e001514ec24dbc4cca1949ff7e8, type: 3} + m_Name: + m_EditorClassIdentifier: + version: 12 + hdPluginSubTargetMaterialVersions: + m_Keys: [] + m_Values: +--- !u!114 &-3015027763282864326 +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 &-2537191031519904044 +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: 639247ca83abc874e893eb93af2b5e44, type: 3} + m_Name: + m_EditorClassIdentifier: + version: 0 +--- !u!21 &2100000 +Material: + serializedVersion: 8 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: MC2_Floor + m_Shader: {fileID: -6465566751694194690, guid: e0b73429f84a56840ba17b216237f806, type: 3} + m_Parent: {fileID: 0} + m_ModifiedSerializedProperties: 0 + m_ValidKeywords: [] + m_InvalidKeywords: + - _DISABLE_SSR_TRANSPARENT + m_LightmapFlags: 4 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: 2000 + stringTagMap: + MotionVector: User + disabledShaderPasses: + - TransparentDepthPrepass + - TransparentDepthPostpass + - TransparentBackface + - RayTracingPrepass + - MOTIONVECTORS + m_LockedProperties: + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailAlbedoMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main: + m_Texture: {fileID: 10309, guid: 0000000000000000f000000000000000, type: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OcclusionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_Lightmaps: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_LightmapsInd: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_ShadowMasks: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Ints: [] + m_Floats: + - _AddPrecomputedVelocity: 0 + - _AlphaCutoffEnable: 0 + - _AlphaDstBlend: 0 + - _AlphaSrcBlend: 1 + - _AlphaToMask: 0 + - _AlphaToMaskInspectorValue: 0 + - _BUILTIN_QueueControl: 0 + - _BUILTIN_QueueOffset: 0 + - _BlendMode: 0 + - _BumpScale: 1 + - _ConservativeDepthOffsetEnable: 0 + - _CullMode: 2 + - _CullModeForward: 2 + - _Cutoff: 0.5 + - _DepthOffsetEnable: 0 + - _DetailNormalMapScale: 1 + - _DoubleSidedEnable: 0 + - _DoubleSidedGIMode: 0 + - _DoubleSidedNormalMode: 2 + - _DstBlend: 0 + - _EnableBlendModePreserveSpecularLighting: 1 + - _EnableFogOnTransparent: 1 + - _GlossMapScale: 1 + - _Glossiness: 0.5 + - _GlossyReflections: 1 + - _Metallic: 0 + - _Mode: 0 + - _OcclusionStrength: 1 + - _OpaqueCullMode: 2 + - _Parallax: 0.02 + - _QueueControl: 1 + - _QueueOffset: 0 + - _RayTracing: 0 + - _ReceivesSSR: 1 + - _ReceivesSSRTransparent: 0 + - _RefractionModel: 0 + - _RenderQueueType: 1 + - _RequireSplitLighting: 0 + - _Smoothness: 0 + - _SmoothnessTextureChannel: 0 + - _SpecularHighlights: 1 + - _SrcBlend: 1 + - _StencilRef: 0 + - _StencilRefDepth: 8 + - _StencilRefDistortionVec: 4 + - _StencilRefGBuffer: 10 + - _StencilRefMV: 40 + - _StencilWriteMask: 6 + - _StencilWriteMaskDepth: 8 + - _StencilWriteMaskDistortionVec: 4 + - _StencilWriteMaskGBuffer: 14 + - _StencilWriteMaskMV: 40 + - _SupportDecals: 1 + - _SurfaceType: 0 + - _TransparentBackfaceEnable: 0 + - _TransparentCullMode: 2 + - _TransparentDepthPostpassEnable: 0 + - _TransparentDepthPrepassEnable: 0 + - _TransparentSortPriority: 0 + - _TransparentWritingMotionVec: 0 + - _TransparentZWrite: 0 + - _UVSec: 0 + - _UseShadowThreshold: 0 + - _ZTestDepthEqualForOpaque: 3 + - _ZTestGBuffer: 4 + - _ZTestTransparent: 4 + - _ZWrite: 1 + m_Colors: + - _Color: {r: 0.14150941, g: 0.14150941, b: 0.14150941, a: 1} + - _DoubleSidedConstants: {r: 1, g: 1, b: -1, a: 0} + - _EmissionColor: {r: 1, g: 1, b: 1, a: 1} + - _Tiling: {r: 100, g: 100, b: 0, a: 0} + m_BuildTextureStacks: [] + m_AllowLocking: 1 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/Common/Materials/MC2_Floor.mat.meta b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Materials/MC2_Floor.mat.meta new file mode 100644 index 00000000..10dc968c --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Materials/MC2_Floor.mat.meta @@ -0,0 +1,15 @@ +fileFormatVersion: 2 +guid: 1a8d0a0ce31bbbd49ad39beb17ee9326 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/Common/Materials/MC2_Floor.mat + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/Common/Materials/MC2_Test_Back.mat b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Materials/MC2_Test_Back.mat new file mode 100644 index 00000000..ae68f77d --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Materials/MC2_Test_Back.mat @@ -0,0 +1,202 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 8 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: MC2_Test_Back + m_Shader: {fileID: -6465566751694194690, guid: b969454d26657854a8fe82c813fb0876, type: 3} + m_Parent: {fileID: 0} + m_ModifiedSerializedProperties: 0 + m_ValidKeywords: [] + m_InvalidKeywords: + - _DISABLE_SSR_TRANSPARENT + m_LightmapFlags: 4 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: 2450 + stringTagMap: + MotionVector: User + disabledShaderPasses: + - TransparentDepthPrepass + - TransparentDepthPostpass + - TransparentBackface + - RayTracingPrepass + - MOTIONVECTORS + m_LockedProperties: + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailAlbedoMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main: + m_Texture: {fileID: 10309, guid: 0000000000000000f000000000000000, type: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OcclusionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_Lightmaps: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_LightmapsInd: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_ShadowMasks: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Ints: [] + m_Floats: + - _AddPrecomputedVelocity: 0 + - _AlphaCutoffEnable: 0 + - _AlphaDstBlend: 0 + - _AlphaSrcBlend: 1 + - _AlphaToMask: 0 + - _AlphaToMaskInspectorValue: 0 + - _BUILTIN_QueueControl: 0 + - _BUILTIN_QueueOffset: 0 + - _BlendMode: 0 + - _BumpScale: 1 + - _ConservativeDepthOffsetEnable: 0 + - _CullMode: 1 + - _CullModeForward: 1 + - _Cutoff: 0.5 + - _DepthOffsetEnable: 0 + - _DetailNormalMapScale: 1 + - _DoubleSidedEnable: 0 + - _DoubleSidedGIMode: 0 + - _DoubleSidedNormalMode: 2 + - _DstBlend: 0 + - _EnableBlendModePreserveSpecularLighting: 1 + - _EnableFogOnTransparent: 1 + - _GlossMapScale: 1 + - _Glossiness: 0.5 + - _GlossyReflections: 1 + - _Metallic: 0 + - _Mode: 0 + - _OcclusionStrength: 1 + - _OpaqueCullMode: 1 + - _Parallax: 0.02 + - _QueueControl: 1 + - _QueueOffset: 0 + - _RayTracing: 0 + - _ReceivesSSR: 1 + - _ReceivesSSRTransparent: 0 + - _RefractionModel: 0 + - _RenderQueueType: 1 + - _RequireSplitLighting: 0 + - _Smoothness: 0 + - _SmoothnessTextureChannel: 0 + - _SpecularHighlights: 1 + - _SrcBlend: 1 + - _StencilRef: 0 + - _StencilRefDepth: 8 + - _StencilRefDistortionVec: 4 + - _StencilRefGBuffer: 10 + - _StencilRefMV: 40 + - _StencilWriteMask: 6 + - _StencilWriteMaskDepth: 8 + - _StencilWriteMaskDistortionVec: 4 + - _StencilWriteMaskGBuffer: 14 + - _StencilWriteMaskMV: 40 + - _SupportDecals: 1 + - _SurfaceType: 0 + - _TransparentBackfaceEnable: 0 + - _TransparentCullMode: 2 + - _TransparentDepthPostpassEnable: 0 + - _TransparentDepthPrepassEnable: 0 + - _TransparentSortPriority: 0 + - _TransparentWritingMotionVec: 0 + - _TransparentZWrite: 0 + - _UVSec: 0 + - _UseShadowThreshold: 0 + - _ZTestDepthEqualForOpaque: 3 + - _ZTestGBuffer: 4 + - _ZTestTransparent: 4 + - _ZWrite: 1 + m_Colors: + - _Color: {r: 1, g: 1, b: 1, a: 1} + - _DoubleSidedConstants: {r: 1, g: 1, b: -1, a: 0} + - _EmissionColor: {r: 1, g: 1, b: 1, a: 1} + - _Tiling: {r: 1, g: 1, b: 0, a: 0} + m_BuildTextureStacks: [] + m_AllowLocking: 1 +--- !u!114 &542807876330787821 +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: da692e001514ec24dbc4cca1949ff7e8, type: 3} + m_Name: + m_EditorClassIdentifier: + version: 12 + hdPluginSubTargetMaterialVersions: + m_Keys: [] + m_Values: +--- !u!114 &5888084634695096061 +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: 639247ca83abc874e893eb93af2b5e44, type: 3} + m_Name: + m_EditorClassIdentifier: + version: 0 +--- !u!114 &7297074712781543736 +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/MagicaCloth2/Example (Can be deleted)/Common/Materials/MC2_Test_Back.mat.meta b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Materials/MC2_Test_Back.mat.meta new file mode 100644 index 00000000..17334c4a --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Materials/MC2_Test_Back.mat.meta @@ -0,0 +1,15 @@ +fileFormatVersion: 2 +guid: 586d53852ab2fac4cba5cac70300497d +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/Common/Materials/MC2_Test_Back.mat + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/Common/Materials/MC2_Test_Front.mat b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Materials/MC2_Test_Front.mat new file mode 100644 index 00000000..d606521c --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Materials/MC2_Test_Front.mat @@ -0,0 +1,202 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &-2678523629483602278 +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 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: MC2_Test_Front + m_Shader: {fileID: -6465566751694194690, guid: e0b73429f84a56840ba17b216237f806, type: 3} + m_Parent: {fileID: 0} + m_ModifiedSerializedProperties: 0 + m_ValidKeywords: [] + m_InvalidKeywords: + - _DISABLE_SSR_TRANSPARENT + m_LightmapFlags: 4 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: 2000 + stringTagMap: + MotionVector: User + disabledShaderPasses: + - TransparentDepthPrepass + - TransparentDepthPostpass + - TransparentBackface + - RayTracingPrepass + - MOTIONVECTORS + m_LockedProperties: + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailAlbedoMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main: + m_Texture: {fileID: 10309, guid: 0000000000000000f000000000000000, type: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OcclusionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_Lightmaps: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_LightmapsInd: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_ShadowMasks: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Ints: [] + m_Floats: + - _AddPrecomputedVelocity: 0 + - _AlphaCutoffEnable: 0 + - _AlphaDstBlend: 0 + - _AlphaSrcBlend: 1 + - _AlphaToMask: 0 + - _AlphaToMaskInspectorValue: 0 + - _BUILTIN_QueueControl: 0 + - _BUILTIN_QueueOffset: 0 + - _BlendMode: 0 + - _BumpScale: 1 + - _ConservativeDepthOffsetEnable: 0 + - _CullMode: 2 + - _CullModeForward: 2 + - _Cutoff: 0.5 + - _DepthOffsetEnable: 0 + - _DetailNormalMapScale: 1 + - _DoubleSidedEnable: 0 + - _DoubleSidedGIMode: 0 + - _DoubleSidedNormalMode: 2 + - _DstBlend: 0 + - _EnableBlendModePreserveSpecularLighting: 1 + - _EnableFogOnTransparent: 1 + - _GlossMapScale: 1 + - _Glossiness: 0.5 + - _GlossyReflections: 1 + - _Metallic: 0 + - _Mode: 0 + - _OcclusionStrength: 1 + - _OpaqueCullMode: 2 + - _Parallax: 0.02 + - _QueueControl: 1 + - _QueueOffset: 0 + - _RayTracing: 0 + - _ReceivesSSR: 1 + - _ReceivesSSRTransparent: 0 + - _RefractionModel: 0 + - _RenderQueueType: 1 + - _RequireSplitLighting: 0 + - _Smoothness: 0 + - _SmoothnessTextureChannel: 0 + - _SpecularHighlights: 1 + - _SrcBlend: 1 + - _StencilRef: 0 + - _StencilRefDepth: 8 + - _StencilRefDistortionVec: 4 + - _StencilRefGBuffer: 10 + - _StencilRefMV: 40 + - _StencilWriteMask: 6 + - _StencilWriteMaskDepth: 8 + - _StencilWriteMaskDistortionVec: 4 + - _StencilWriteMaskGBuffer: 14 + - _StencilWriteMaskMV: 40 + - _SupportDecals: 1 + - _SurfaceType: 0 + - _TransparentBackfaceEnable: 0 + - _TransparentCullMode: 2 + - _TransparentDepthPostpassEnable: 0 + - _TransparentDepthPrepassEnable: 0 + - _TransparentSortPriority: 0 + - _TransparentWritingMotionVec: 0 + - _TransparentZWrite: 0 + - _UVSec: 0 + - _UseShadowThreshold: 0 + - _ZTestDepthEqualForOpaque: 3 + - _ZTestGBuffer: 4 + - _ZTestTransparent: 4 + - _ZWrite: 1 + m_Colors: + - _Color: {r: 1, g: 1, b: 1, a: 1} + - _DoubleSidedConstants: {r: 1, g: 1, b: -1, a: 0} + - _EmissionColor: {r: 1, g: 1, b: 1, a: 1} + - _Tiling: {r: 1, g: 1, b: 0, a: 0} + m_BuildTextureStacks: [] + m_AllowLocking: 1 +--- !u!114 &3436996967411815949 +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: da692e001514ec24dbc4cca1949ff7e8, type: 3} + m_Name: + m_EditorClassIdentifier: + version: 12 + hdPluginSubTargetMaterialVersions: + m_Keys: [] + m_Values: +--- !u!114 &5888084634695096061 +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: 639247ca83abc874e893eb93af2b5e44, type: 3} + m_Name: + m_EditorClassIdentifier: + version: 0 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/Common/Materials/MC2_Test_Front.mat.meta b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Materials/MC2_Test_Front.mat.meta new file mode 100644 index 00000000..aac2baec --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Materials/MC2_Test_Front.mat.meta @@ -0,0 +1,15 @@ +fileFormatVersion: 2 +guid: e668c51d0e0125e4dbae8a37cb0d45e4 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/Common/Materials/MC2_Test_Front.mat + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/Common/Materials/MC2_White.mat b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Materials/MC2_White.mat new file mode 100644 index 00000000..6b876a94 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Materials/MC2_White.mat @@ -0,0 +1,133 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &-3650841247374319034 +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: Unity.RenderPipelines.Universal.Editor::UnityEditor.Rendering.Universal.AssetVersion + version: 10 +--- !u!21 &2100000 +Material: + serializedVersion: 8 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: MC2_White + m_Shader: {fileID: -6465566751694194690, guid: e0b73429f84a56840ba17b216237f806, type: 3} + m_Parent: {fileID: 0} + m_ModifiedSerializedProperties: 0 + m_ValidKeywords: [] + m_InvalidKeywords: [] + m_LightmapFlags: 4 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: -1 + stringTagMap: {} + disabledShaderPasses: + - MOTIONVECTORS + m_LockedProperties: + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailAlbedoMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OcclusionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_Lightmaps: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_LightmapsInd: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_ShadowMasks: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Ints: [] + m_Floats: + - _BUILTIN_QueueControl: 0 + - _BUILTIN_QueueOffset: 0 + - _BumpScale: 1 + - _Cutoff: 0.5 + - _DetailNormalMapScale: 1 + - _DstBlend: 0 + - _GlossMapScale: 1 + - _Glossiness: 0.5 + - _GlossyReflections: 1 + - _Metallic: 0 + - _Mode: 0 + - _OcclusionStrength: 1 + - _Parallax: 0.02 + - _QueueControl: 0 + - _QueueOffset: 0 + - _Smoothness: 0 + - _SmoothnessTextureChannel: 0 + - _SpecularHighlights: 1 + - _SrcBlend: 1 + - _UVSec: 0 + - _ZWrite: 1 + m_Colors: + - _Color: {r: 0.6886792, g: 0.6886792, b: 0.6886792, a: 1} + - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} + - _Tiling: {r: 1, g: 1, b: 0, a: 0} + m_BuildTextureStacks: [] + m_AllowLocking: 1 +--- !u!114 &5537520944958903688 +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: 639247ca83abc874e893eb93af2b5e44, type: 3} + m_Name: + m_EditorClassIdentifier: + version: 0 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/Common/Materials/MC2_White.mat.meta b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Materials/MC2_White.mat.meta new file mode 100644 index 00000000..33f321c1 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Materials/MC2_White.mat.meta @@ -0,0 +1,15 @@ +fileFormatVersion: 2 +guid: 9dc80f717b8cf0f44a1328de60c05a87 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/Common/Materials/MC2_White.mat + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/Common/Model.meta b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Model.meta new file mode 100644 index 00000000..add85f94 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Model.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 174ae74532988144eaa22b5d3ce3b54b +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/Common/Model/Materials.meta b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Model/Materials.meta new file mode 100644 index 00000000..edecb123 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Model/Materials.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: e22374f5956c7fe49ba058092885078b +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/Common/Model/Materials/Arrow.mat b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Model/Materials/Arrow.mat new file mode 100644 index 00000000..b1e3909b --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Model/Materials/Arrow.mat @@ -0,0 +1,151 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 8 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: Arrow + m_Shader: {fileID: -6465566751694194690, guid: e0b73429f84a56840ba17b216237f806, type: 3} + m_Parent: {fileID: 0} + m_ModifiedSerializedProperties: 0 + m_ValidKeywords: [] + m_InvalidKeywords: [] + m_LightmapFlags: 4 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: -1 + stringTagMap: {} + disabledShaderPasses: + - MOTIONVECTORS + m_LockedProperties: + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _BaseMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailAlbedoMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OcclusionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _SpecGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_Lightmaps: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_LightmapsInd: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_ShadowMasks: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Ints: [] + m_Floats: + - _AlphaClip: 0 + - _BUILTIN_QueueControl: 0 + - _BUILTIN_QueueOffset: 0 + - _Blend: 0 + - _BumpScale: 1 + - _ClearCoatMask: 0 + - _ClearCoatSmoothness: 0 + - _Cull: 2 + - _Cutoff: 0.5 + - _DetailAlbedoMapScale: 1 + - _DetailNormalMapScale: 1 + - _DstBlend: 0 + - _EnvironmentReflections: 1 + - _GlossMapScale: 0 + - _Glossiness: 0 + - _GlossyReflections: 0 + - _Metallic: 0 + - _OcclusionStrength: 1 + - _Parallax: 0.005 + - _QueueControl: 0 + - _QueueOffset: 0 + - _ReceiveShadows: 1 + - _Smoothness: 0.5 + - _SmoothnessTextureChannel: 0 + - _SpecularHighlights: 1 + - _SrcBlend: 1 + - _Surface: 0 + - _WorkflowMode: 1 + - _ZWrite: 1 + m_Colors: + - _BaseColor: {r: 0.8, g: 0.8, b: 0.8, a: 1} + - _Color: {r: 1, g: 1, b: 1, a: 1} + - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} + - _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1} + - _Tiling: {r: 1, g: 1, b: 0, a: 0} + m_BuildTextureStacks: [] + m_AllowLocking: 1 +--- !u!114 &7761228438660005603 +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 &8771852287512767389 +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: 639247ca83abc874e893eb93af2b5e44, type: 3} + m_Name: + m_EditorClassIdentifier: + version: 0 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/Common/Model/Materials/Arrow.mat.meta b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Model/Materials/Arrow.mat.meta new file mode 100644 index 00000000..2518afd3 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Model/Materials/Arrow.mat.meta @@ -0,0 +1,15 @@ +fileFormatVersion: 2 +guid: 9d8e9d2536fe10f448a1440c26ec0bc3 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/Common/Model/Materials/Arrow.mat + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/Common/Model/arrow_b.fbx b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Model/arrow_b.fbx new file mode 100644 index 00000000..2ef7a2d2 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Model/arrow_b.fbx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0160532033ab082715b7fe34c4ba00fb5ecd59ba77dc1e5b3c308cd31c440f29 +size 15660 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/Common/Model/arrow_b.fbx.meta b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Model/arrow_b.fbx.meta new file mode 100644 index 00000000..e69d9b51 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Model/arrow_b.fbx.meta @@ -0,0 +1,132 @@ +fileFormatVersion: 2 +guid: 40f00d3ed65180f4ab14accca4d78735 +ModelImporter: + serializedVersion: 21300 + internalIDToNameTable: + - first: + 1: 100000 + second: //RootNode + - first: + 4: 400000 + second: //RootNode + - first: + 21: 2100000 + second: Arrow + - first: + 23: 2300000 + second: //RootNode + - first: + 33: 3300000 + second: //RootNode + - first: + 43: 4300000 + second: Arrow + externalObjects: {} + materials: + materialImportMode: 1 + materialName: 0 + materialSearch: 1 + materialLocation: 1 + animations: + legacyGenerateAnimations: 4 + bakeSimulation: 0 + resampleCurves: 1 + optimizeGameObjects: 0 + removeConstantScaleCurves: 0 + motionNodeName: + rigImportErrors: + rigImportWarnings: + animationImportErrors: + animationImportWarnings: + animationRetargetingWarnings: + animationDoRetargetingWarnings: 0 + importAnimatedCustomProperties: 0 + importConstraints: 0 + animationCompression: 1 + animationRotationError: 0.5 + animationPositionError: 0.5 + animationScaleError: 0.5 + animationWrapMode: 0 + extraExposedTransformPaths: [] + extraUserProperties: [] + clipAnimations: [] + isReadable: 1 + meshes: + lODScreenPercentages: [] + globalScale: 1 + meshCompression: 0 + addColliders: 0 + useSRGBMaterialColor: 1 + sortHierarchyByName: 1 + importVisibility: 1 + importBlendShapes: 1 + importCameras: 1 + importLights: 1 + nodeNameCollisionStrategy: 0 + fileIdsGeneration: 1 + swapUVChannels: 0 + generateSecondaryUV: 0 + useFileUnits: 1 + keepQuads: 0 + weldVertices: 1 + bakeAxisConversion: 0 + preserveHierarchy: 0 + skinWeightsMode: 0 + maxBonesPerVertex: 4 + minBoneWeight: 0.001 + optimizeBones: 1 + meshOptimizationFlags: -1 + indexFormat: 0 + secondaryUVAngleDistortion: 8 + secondaryUVAreaDistortion: 15.000001 + secondaryUVHardAngle: 88 + secondaryUVMarginMethod: 0 + secondaryUVMinLightmapResolution: 40 + secondaryUVMinObjectScale: 1 + secondaryUVPackMargin: 4 + useFileScale: 1 + strictVertexDataChecks: 0 + tangentSpace: + normalSmoothAngle: 60 + normalImportMode: 0 + tangentImportMode: 3 + normalCalculationMode: 4 + legacyComputeAllNormalsFromSmoothingGroupsWhenMeshHasBlendShapes: 0 + blendShapeNormalImportMode: 1 + normalSmoothingSource: 0 + referencedClips: [] + importAnimation: 1 + humanDescription: + serializedVersion: 3 + human: [] + skeleton: [] + armTwist: 0.5 + foreArmTwist: 0.5 + upperLegTwist: 0.5 + legTwist: 0.5 + armStretch: 0.05 + legStretch: 0.05 + feetSpacing: 0 + globalScale: 1 + rootMotionBoneName: + hasTranslationDoF: 0 + hasExtraRoot: 0 + skeletonHasParents: 1 + lastHumanDescriptionAvatarSource: {instanceID: 0} + autoGenerateAvatarMappingIfUnspecified: 1 + animationType: 0 + humanoidOversampling: 1 + avatarSetup: 0 + addHumanoidExtraRootOnlyWhenUsingAvatar: 0 + remapMaterialsIfMaterialImportModeIsNone: 1 + additionalBone: 0 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/Common/Model/arrow_b.fbx + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs.meta b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs.meta new file mode 100644 index 00000000..eb6b6326 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: f43ab23790f02b24aa62d451e140d7ce +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/Cube.prefab b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/Cube.prefab new file mode 100644 index 00000000..ab6df2cf --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/Cube.prefab @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f169efee1513b12061019e163775bfa5128f163f53cffdbc2ad4317d77cd323a +size 2413 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/Cube.prefab.meta b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/Cube.prefab.meta new file mode 100644 index 00000000..bfadfa3a --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/Cube.prefab.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: baaebd372fee4154e9b08570bc3a230e +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/Cube.prefab + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/CubeRoup.prefab b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/CubeRoup.prefab new file mode 100644 index 00000000..72f6eb21 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/CubeRoup.prefab @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:48f133160179ee92b5499d778694740cee7a65369989f324edfa48ceabeaef38 +size 6748 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/CubeRoup.prefab.meta b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/CubeRoup.prefab.meta new file mode 100644 index 00000000..bb0e25f0 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/CubeRoup.prefab.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: 1950e99f479bef04581d5185a7cf27b3 +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/CubeRoup.prefab + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/Env.prefab b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/Env.prefab new file mode 100644 index 00000000..598223f9 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/Env.prefab @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0bebc9776e0c8f10f095ccb8df1145d85a5414ddb60092d02ed3d359aa5a7696 +size 10022 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/Env.prefab.meta b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/Env.prefab.meta new file mode 100644 index 00000000..9a868bb5 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/Env.prefab.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: b5bac44e9cdf69541b2d1de75e68a9ba +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/Env.prefab + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/Plane.prefab b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/Plane.prefab new file mode 100644 index 00000000..b65951ee --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/Plane.prefab @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9a52573145ff1845f29be4d642fc0d6a85c56b125d12fa5e14305fec633c2837 +size 2971 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/Plane.prefab.meta b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/Plane.prefab.meta new file mode 100644 index 00000000..9a570b0a --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/Plane.prefab.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: f6e49ec628143df48a1d0a213fc770af +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/Plane.prefab + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/RuntimeBuildDemo.prefab b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/RuntimeBuildDemo.prefab new file mode 100644 index 00000000..ed4fe3b2 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/RuntimeBuildDemo.prefab @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1e5c3bbfbf58e8a2cf2384c8a9ff89dc3377eb13c2289fc5408d7ca569bc5efc +size 10344 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/RuntimeBuildDemo.prefab.meta b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/RuntimeBuildDemo.prefab.meta new file mode 100644 index 00000000..ab36424d --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/RuntimeBuildDemo.prefab.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: 57eb8094dff10c34f8fae441c280e0f8 +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/RuntimeBuildDemo.prefab + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/RuntimeDressUpDemo.prefab b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/RuntimeDressUpDemo.prefab new file mode 100644 index 00000000..dbfa96e4 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/RuntimeDressUpDemo.prefab @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:94aef92a3877c5d4a8e01acdd68e46d24d1551f56d5eed3cc97e413d6501e235 +size 1562 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/RuntimeDressUpDemo.prefab.meta b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/RuntimeDressUpDemo.prefab.meta new file mode 100644 index 00000000..6179dfe0 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/RuntimeDressUpDemo.prefab.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: bca76fc2423c0a14db7d44f7745ab286 +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/RuntimeDressUpDemo.prefab + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/SimpleImputManager.prefab b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/SimpleImputManager.prefab new file mode 100644 index 00000000..0eca7f7d --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/SimpleImputManager.prefab @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7d6989df41742a524342d6919406b12184f9d7a275bc7ed6ddb17aef647ba949 +size 1413 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/SimpleImputManager.prefab.meta b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/SimpleImputManager.prefab.meta new file mode 100644 index 00000000..0a612af5 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/SimpleImputManager.prefab.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: e35153ae4a19fa24289b796a4290d4db +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/SimpleImputManager.prefab + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/Stage.prefab b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/Stage.prefab new file mode 100644 index 00000000..636ffec7 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/Stage.prefab @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0feb9a444464642b7c2a97b665826895f45a8445ab81c50f9ab4cf7a60e61c40 +size 3315 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/Stage.prefab.meta b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/Stage.prefab.meta new file mode 100644 index 00000000..314f542f --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/Stage.prefab.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: 23be23f56fcb4ac48ac4de26c111e332 +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/Stage.prefab + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/UI_KAGURA.prefab b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/UI_KAGURA.prefab new file mode 100644 index 00000000..3644f716 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/UI_KAGURA.prefab @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d406b0102a79ef332a057c5373ccb315b28a62ec079ab27d6b10abae72abf574 +size 27331 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/UI_KAGURA.prefab.meta b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/UI_KAGURA.prefab.meta new file mode 100644 index 00000000..f66e640d --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/UI_KAGURA.prefab.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: 94ed6a8f5c3a2ba4d8c93972af7467f0 +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/UI_KAGURA.prefab + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/UI_RuntimeBuild.prefab b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/UI_RuntimeBuild.prefab new file mode 100644 index 00000000..d6589817 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/UI_RuntimeBuild.prefab @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e510f1ce5738c1442c35dadec46ad2ee5fdee57038071fc3cbbee7ee631c1f34 +size 20859 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/UI_RuntimeBuild.prefab.meta b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/UI_RuntimeBuild.prefab.meta new file mode 100644 index 00000000..b71e800e --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/UI_RuntimeBuild.prefab.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: 0b388bd66f5736b4891ceafcaee539a4 +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/UI_RuntimeBuild.prefab + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/UI_RuntimeDressUp.prefab b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/UI_RuntimeDressUp.prefab new file mode 100644 index 00000000..ec16fe6d --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/UI_RuntimeDressUp.prefab @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f8d9e6093648d2e3e36cca00d6fe8133bbc784153337b6949dd2c0fddeab86f0 +size 20875 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/UI_RuntimeDressUp.prefab.meta b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/UI_RuntimeDressUp.prefab.meta new file mode 100644 index 00000000..cb117480 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/UI_RuntimeDressUp.prefab.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: 228b0487b4c6f43448267a8277251bc6 +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/UI_RuntimeDressUp.prefab + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/UI_Wind.prefab b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/UI_Wind.prefab new file mode 100644 index 00000000..b6e8314a --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/UI_Wind.prefab @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ee28a2d280ad07702182810894d644650133f08a698f7029956bd426e036e2ce +size 67305 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/UI_Wind.prefab.meta b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/UI_Wind.prefab.meta new file mode 100644 index 00000000..a2fb0e06 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/UI_Wind.prefab.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: b10f69e1744a07942843e8c00f85501e +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/UI_Wind.prefab + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/WindDemo.prefab b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/WindDemo.prefab new file mode 100644 index 00000000..b5d8f8e3 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/WindDemo.prefab @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5e4b4d9c97ef008f5dc573b06f70fcc7c47ffd660604490e3f9f6a19f7d10877 +size 12894 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/WindDemo.prefab.meta b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/WindDemo.prefab.meta new file mode 100644 index 00000000..04b2fb11 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/WindDemo.prefab.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: c421f5fd48afe284da1a2c74a043723b +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/WindDemo.prefab + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/WindParticle.prefab b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/WindParticle.prefab new file mode 100644 index 00000000..ef929d11 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/WindParticle.prefab @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9c31a916d60d0e0e6a7d520e4272f764f7236b029afd83aad90a7869335e9fd7 +size 116665 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/WindParticle.prefab.meta b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/WindParticle.prefab.meta new file mode 100644 index 00000000..753a4a44 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/WindParticle.prefab.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: 9f50911cfd816e840860425faa5cec57 +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/WindParticle.prefab + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/Common/Resources.meta b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Resources.meta new file mode 100644 index 00000000..1b086c74 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Resources.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 983f0ab2563c0d34eb966719207674dc +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/Common/Resources/MC2_BoneCloth_Ribbon_Demo.json b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Resources/MC2_BoneCloth_Ribbon_Demo.json new file mode 100644 index 00000000..760d000e --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Resources/MC2_BoneCloth_Ribbon_Demo.json @@ -0,0 +1 @@ +{"clothType":1,"sourceRenderers":[],"paintMode":0,"paintMaps":[],"rootBones":[{"instanceID":-1922},{"instanceID":-1974}],"connectionMode":0,"rotationalInterpolation":0.5,"rootRotation":0.5,"animationBlendRatio":0.0,"reductionSetting":{"simpleDistance":0.0,"shapeDistance":0.0},"customSkinningSetting":{"enable":false,"skinningBones":[]},"normalAlignmentSetting":{"alignmentMode":0,"adjustmentTransform":{"instanceID":0}},"normalAxis":1,"gravity":2.0,"gravityDirection":{"x":0.0,"y":-1.0,"z":0.0},"gravityFalloff":0.0,"damping":{"value":0.019999999552965165,"useCurve":false,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}},"radius":{"value":0.019999999552965165,"useCurve":false,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}},"inertiaConstraint":{"movementInertia":1.0,"rotationInertia":1.0,"depthInertia":0.0,"centrifualAcceleration":0.0,"movementSpeedLimit":{"value":5.0,"use":true},"rotationSpeedLimit":{"value":720.0,"use":true},"particleSpeedLimit":{"value":3.0,"use":true}},"tetherConstraint":{"distanceCompression":0.5},"distanceConstraint":{"stiffness":{"value":1.0,"useCurve":false,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":1.0,"inSlope":0.0,"outSlope":-0.5,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":0.5,"inSlope":-0.5,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}}},"triangleBendingConstraint":{"stiffness":0.5},"angleRestorationConstraint":{"useAngleRestoration":true,"stiffness":{"value":0.05400000140070915,"useCurve":true,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":1.0,"inSlope":-0.5040969848632813,"outSlope":-0.5040969848632813,"tangentMode":34,"weightedMode":0,"inWeight":0.0,"outWeight":0.3333333432674408},{"serializedVersion":"3","time":1.0,"value":0.49590301513671877,"inSlope":-0.5040969848632813,"outSlope":-0.5040969848632813,"tangentMode":34,"weightedMode":0,"inWeight":0.3333333432674408,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}},"velocityAttenuation":0.5,"gravityFalloff":0.0},"angleLimitConstraint":{"useAngleLimit":true,"limitAngle":{"value":45.0,"useCurve":true,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":0.0,"inSlope":0.0,"outSlope":1.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":1.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}},"stiffness":0.30000001192092898},"motionConstraint":{"useMaxDistance":false,"maxDistance":{"value":0.30000001192092898,"useCurve":false,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}},"useBackstop":false,"backstopRadius":10.0,"backstopDistance":{"value":0.0,"useCurve":false,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}},"stiffness":1.0},"colliderCollisionConstraint":{"mode":1,"friction":0.05000000074505806,"colliderList":[]},"selfCollisionConstraint":{"selfMode":0,"surfaceThickness":{"value":0.004999999888241291,"useCurve":false,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":0.5,"inSlope":0.0,"outSlope":0.5,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":0.5,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}},"syncMode":0,"syncPartner":{"instanceID":0}}} \ No newline at end of file diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/Common/Resources/MC2_BoneCloth_Ribbon_Demo.json.meta b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Resources/MC2_BoneCloth_Ribbon_Demo.json.meta new file mode 100644 index 00000000..8c3fafb8 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Resources/MC2_BoneCloth_Ribbon_Demo.json.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: 9cb18a57f012d144480f025bca639032 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/Common/Resources/MC2_BoneCloth_Ribbon_Demo.json + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts.meta b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts.meta new file mode 100644 index 00000000..9a8e79f8 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 2ccf7a2872d9e554ea3511882b07a3e7 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/AutoRotate.cs b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/AutoRotate.cs new file mode 100644 index 00000000..17daf4f8 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/AutoRotate.cs @@ -0,0 +1,60 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using UnityEngine; + +namespace MagicaCloth2 +{ + public class AutoRotate : MonoBehaviour + { + 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)] + private float interval = 2.0f; + + public bool useSin = true; + + + private float time = 0; + + protected void FixedUpdate() + { + if (updateMode == UpdateMode.FixedUpdate) + UpdatePosition(Time.fixedDeltaTime); + } + + protected void Update() + { + if (updateMode == UpdateMode.Update) + UpdatePosition(Time.deltaTime); + } + + void UpdatePosition(float dtime) + { + if (useSin) + { + time += dtime; + float ang = (time % interval) / interval * Mathf.PI * 2.0f; + var t = Mathf.Sin(ang); + if (space == Space.World) + transform.eulerAngles = eulers * t; + else + transform.localEulerAngles = eulers * t; + } + else + { + transform.Rotate(eulers * dtime, space); + } + } + } + +} diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/AutoRotate.cs.meta b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/AutoRotate.cs.meta new file mode 100644 index 00000000..39735d8b --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/AutoRotate.cs.meta @@ -0,0 +1,19 @@ +fileFormatVersion: 2 +guid: 4124c59241137374c9cae45d25683042 +timeCreated: 1510336570 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/AutoRotate.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/CameraOrbit.cs b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/CameraOrbit.cs new file mode 100644 index 00000000..8db35753 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/CameraOrbit.cs @@ -0,0 +1,249 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using UnityEngine; + +namespace MagicaCloth2 +{ + /// + /// カメラ回転 + /// + public class CameraOrbit : MonoBehaviour + { + [SerializeField] + private Transform cameraTransform; + + [Header("Camera Target")] + public Transform cameraTarget; + public Vector3 cameraTargetPos; + public Vector3 cameraTargetOffset; + + [Header("Now Position")] + [SerializeField] + private float cameraDist = 1.5f; + [SerializeField] + private float cameraPitch = 21.0f; + [SerializeField] + private float cameraYaw = 180.0f; + + [Header("Parameter")] + [SerializeField] + private float cameraDistHokanTime = 0.1f; + [SerializeField] + private float cameraAngleHokanTime = 0.1f; + + [SerializeField] + private float cameraDistSpeed = 0.02f; + [SerializeField] + private float cameraDistMax = 8.0f; + [SerializeField] + private float cameraDistMin = 0.1f; + + [SerializeField] + private float cameraYawSpeed = 0.3f; + [SerializeField] + private float cameraPitchSpeed = 0.3f; + [SerializeField] + private float cameraMaxAngleSpeed = 100.0f; + [SerializeField] + private float cameraPitchMax = 89.0f; + [SerializeField] + private float cameraPitchMin = -89.0f; + + // 中ボタンドラッグによる移動 + public enum MoveMode + { + None, + UpDown, + Free, + } + [SerializeField] + private MoveMode moveMode = MoveMode.Free; + [SerializeField] + private float moveSpeed = 0.002f; + + // 自動回転 + [Header("Auto Rotation")] + [SerializeField] + private bool useAutoRotation = false; + [SerializeField] + private float autoRotationSpeed = 90.0f; + + + // 移動作業用 + private float setCameraDist; + private float setCameraPitch; + private float setCameraYaw; + private float cameraDistVelocity; + private float cameraPitchVelocity; + private float cameraYawVelocity; + private float offsetYaw; + + protected void Start() + { + if (cameraTransform == null) + { + var cam = GetComponent(); + if (cam) + cameraTransform = cam.transform; + } + if (cameraTransform == null) + enabled = false; + + setCameraDist = cameraDist; + setCameraPitch = cameraPitch; + setCameraYaw = cameraYaw; + } + + protected void OnEnable() + { + // 入力イベント登録 + SimpleInputManager.OnTouchMove += OnTouchMove; + SimpleInputManager.OnDoubleTouchMove += OnDoubleTouchMove; + SimpleInputManager.OnTouchPinch += OnTouchPinch; + } + + protected void OnDisable() + { + // 入力イベント解除 + SimpleInputManager.OnTouchMove -= OnTouchMove; + SimpleInputManager.OnDoubleTouchMove -= OnDoubleTouchMove; + SimpleInputManager.OnTouchPinch -= OnTouchPinch; + } + + protected void LateUpdate() + { + // カメラ更新 + updateCamera(); + } + + // カメラ更新 + private void updateCamera() + { + if (cameraTransform == null) + return; + + // カメラターゲットポジション + cameraTargetPos = cameraTarget ? cameraTarget.position : transform.position; + + // 補間 + cameraDist = Mathf.SmoothDamp(cameraDist, setCameraDist, ref cameraDistVelocity, cameraDistHokanTime); + cameraPitch = Mathf.SmoothDampAngle(cameraPitch, setCameraPitch, ref cameraPitchVelocity, cameraAngleHokanTime); + cameraYaw = Mathf.SmoothDampAngle(cameraYaw, setCameraYaw, ref cameraYawVelocity, cameraAngleHokanTime); + + // 自動回転 + if (useAutoRotation) + { + offsetYaw += autoRotationSpeed * Time.deltaTime; + } + + // 座標確定 + Quaternion q = Quaternion.Euler(cameraPitch, cameraYaw + offsetYaw, 0); + q = transform.rotation * q; // コンポーネントの回転 + Vector3 v = new Vector3(0, 0, -cameraDist); + Vector3 pos = q * v; + + // ターゲットポジション + Vector3 tarpos = cameraTargetPos + transform.TransformVector(cameraTargetOffset); + Vector3 fixpos = tarpos + pos; + cameraTransform.position = fixpos; + + // 回転確定 + Vector3 relativePos = tarpos - cameraTransform.position; + Quaternion rot = Quaternion.LookRotation(relativePos, transform.up); + cameraTransform.rotation = rot; + } + + // 回転操作 + private void updatePitchYaw(Vector2 speed) + { + // Yaw + setCameraYaw += speed.x * cameraYawSpeed; + + // Pitch + setCameraPitch += -speed.y * cameraPitchSpeed; + setCameraPitch = Mathf.Clamp(setCameraPitch, cameraPitchMin, cameraPitchMax); + } + + // 移動操作 + private void updateOffset(Vector2 speed) + { + if (cameraTransform == null) + { + return; + } + + if (moveMode == MoveMode.UpDown) + { + cameraTargetOffset.y -= speed.y * moveSpeed; + } + else if (moveMode == MoveMode.Free) + { + Vector3 offset = moveSpeed * -speed.y * transform.InverseTransformDirection(cameraTransform.up); + offset += moveSpeed * -speed.x * transform.InverseTransformDirection(cameraTransform.right); + + cameraTargetOffset += offset; + } + } + + // ズーム操作 + private void updateZoom(float speed) + { + float value = speed * cameraDistSpeed; + float scl = Mathf.InverseLerp(cameraDistMin, cameraDistMax, setCameraDist); + scl = Mathf.Clamp(scl, 0.1f, 1.0f); + setCameraDist -= value * scl; + setCameraDist = Mathf.Clamp(setCameraDist, cameraDistMin, cameraDistMax); + } + + //============================================================================================= + /// + /// 入力通知:移動 + /// + /// + /// + private void OnTouchMove(int fid, Vector2 screenPos, Vector2 screenVelocity, Vector2 cmVelocity) + { + screenVelocity *= SpeedAdjustment(); + + if (fid == 2) + { + // 中ドラッグ + updateOffset(screenVelocity); + } + else if (fid == 0) + { + // 左ドラッグ + // 最大速度 + screenVelocity = Vector2.ClampMagnitude(screenVelocity, cameraMaxAngleSpeed); + updatePitchYaw(screenVelocity); + } + } + + private void OnDoubleTouchMove(int fid, Vector2 screenPos, Vector2 screenVelocity, Vector2 cmVelocity) + { + screenVelocity *= SpeedAdjustment(); + + if (SimpleInputManager.Instance.GetTouchCount() >= 3) + updateOffset(screenVelocity); + } + + /// + /// 入力通知:ピンチイン/アウト + /// + /// + /// + private void OnTouchPinch(float speedscr, float speedcm) + { + speedcm *= SpeedAdjustment(); + + if (SimpleInputManager.Instance.GetTouchCount() < 3) + updateZoom(speedcm); + } + + private float SpeedAdjustment() + { + return Time.deltaTime * 60.0f; + } + } +} diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/CameraOrbit.cs.meta b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/CameraOrbit.cs.meta new file mode 100644 index 00000000..9b3bf462 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/CameraOrbit.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 1fd18111ed866534a92d0a2a59d1608d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/CameraOrbit.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/CreateSingleton.cs b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/CreateSingleton.cs new file mode 100644 index 00000000..68984fa3 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/CreateSingleton.cs @@ -0,0 +1,136 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using UnityEngine; + +namespace MagicaCloth2 +{ + /// + /// 基本的なシングルトンテンプレート + /// ・シーンに無い場合は作成する + /// ・自動初期化呼び出し機能 + /// ・DontDestroyOnLoad設定 + /// ・実行前でもInstanceアクセス可能 + /// + /// + public abstract class CreateSingleton : MonoBehaviour where T : MonoBehaviour + { + private static T instance; + + /// + /// 初期化フラグ + /// + private static T initInstance; + + private static bool isDestroy; + + + /// + /// Reload Domain 対応 + /// ※残念ながらジェネリッククラスでは[RuntimeInitializeOnLoadMethod]が利用できないため、 + /// この初期化関数を派生元で[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] + /// を使用して呼び出さなければならない + /// + protected static void InitMember() + { + instance = null; + initInstance = null; + isDestroy = false; + } + + public static T Instance + { + get + { + if (instance == null) + { + // FindObjectOfTypeはそれなりに負荷がかかるので注意! + // 非アクティブのオブジェクトは発見できないので注意! +#if UNITY_6000_4_OR_NEWER + instance = FindAnyObjectByType(); +#elif UNITY_2023_1_OR_NEWER + instance = FindFirstObjectByType(); +#else + instance = FindObjectOfType(); +#endif + + if (instance == null && Application.isPlaying) + { + var obj = new GameObject(typeof(T).Name); + instance = obj.AddComponent(); + } + } + + // 初期化 + InitInstance(); + + return instance; + } + } + + private static void InitInstance() + { + if (initInstance == null && instance != null && Application.isPlaying) + { + // シーン切り替えでもオブジェクトが消えないように設定 + //DontDestroyOnLoad(instance.gameObject); + + // 初期化呼び出し + var s = instance as CreateSingleton; + s.InitSingleton(); + + initInstance = instance; + } + } + + /// + /// インスタンスが存在する場合にTrueを返します + /// + /// + public static bool IsInstance() + { + return instance != null && isDestroy == false; + } + + /// + /// Awake()でのインスタンス設定 + /// + protected virtual void Awake() + { + if (instance == null) + { + instance = this as T; + InitInstance(); + } + else if (instance != this) + { + // 2つ目のコンポーネントを発見 + var s = instance as CreateSingleton; + s.DuplicateDetection(this as T); + + // 2つ目のコンポーネントは破棄する + Destroy(this.gameObject); + } + } + + protected virtual void OnDestroy() + { + // インスタンスクラスならば無効化フラグを立てる + if (instance == this) + { + isDestroy = true; + } + } + + /// + /// 2つ目の破棄されるコンポーネントを通知 + /// + /// + protected virtual void DuplicateDetection(T duplicate) { } + + /// + /// 内部初期化 + /// + protected abstract void InitSingleton(); + } +} diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/CreateSingleton.cs.meta b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/CreateSingleton.cs.meta new file mode 100644 index 00000000..d395d9a3 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/CreateSingleton.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 0d1b801c369005647ae0e5a315e0bdaf +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/CreateSingleton.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/Editor.meta b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/Editor.meta new file mode 100644 index 00000000..52f4e504 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/Editor.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 776d5a1b173ef154c9bef26d30c53fcc +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/Editor/ShaderGraph.meta b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/Editor/ShaderGraph.meta new file mode 100644 index 00000000..35c53220 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/Editor/ShaderGraph.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 347fb6ccc378d9442a92b5316d0ff7c9 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/Editor/ShaderGraph/MagicaCloth2UPMImporterShaderGraph.asmdef b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/Editor/ShaderGraph/MagicaCloth2UPMImporterShaderGraph.asmdef new file mode 100644 index 00000000..0f3f8bea --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/Editor/ShaderGraph/MagicaCloth2UPMImporterShaderGraph.asmdef @@ -0,0 +1,24 @@ +{ + "name": "MagicaCloth2UPMImporterShaderGraph", + "rootNamespace": "", + "references": [], + "includePlatforms": [ + "Editor" + ], + "excludePlatforms": [], + "allowUnsafeCode": false, + "overrideReferences": false, + "precompiledReferences": [], + "autoReferenced": true, + "defineConstraints": [ + "!MC2_SHADERGRAPH" + ], + "versionDefines": [ + { + "name": "com.unity.shadergraph", + "expression": "12.0.0", + "define": "MC2_SHADERGRAPH" + } + ], + "noEngineReferences": false +} \ No newline at end of file diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/Editor/ShaderGraph/MagicaCloth2UPMImporterShaderGraph.asmdef.meta b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/Editor/ShaderGraph/MagicaCloth2UPMImporterShaderGraph.asmdef.meta new file mode 100644 index 00000000..05762707 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/Editor/ShaderGraph/MagicaCloth2UPMImporterShaderGraph.asmdef.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: 34d2974f64e7a9f49a48b400abf046ff +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/Editor/ShaderGraph/MagicaCloth2UPMImporterShaderGraph.asmdef + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/Editor/ShaderGraph/UnityPackageImporter.cs b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/Editor/ShaderGraph/UnityPackageImporter.cs new file mode 100644 index 00000000..a879de28 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/Editor/ShaderGraph/UnityPackageImporter.cs @@ -0,0 +1,30 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using UnityEditor; +using UnityEditor.PackageManager; +using UnityEngine; + +namespace MagicaCloth2UPMImporterCollections +{ + /// + /// 必要なUnityPackageの自動インストール + /// + [InitializeOnLoad] + public static class UnityPackageImporter + { + static UnityPackageImporter() + { + Install("com.unity.shadergraph"); + } + + public static bool Install(string id) + { + Debug.Log($"Install...{id}"); + var request = Client.Add(id); + while (!request.IsCompleted) { }; + if (request.Error != null) Debug.LogError(request.Error.message); + return request.Error == null; + } + } +} diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/Editor/ShaderGraph/UnityPackageImporter.cs.meta b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/Editor/ShaderGraph/UnityPackageImporter.cs.meta new file mode 100644 index 00000000..45d878d3 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/Editor/ShaderGraph/UnityPackageImporter.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: dd5d6386919360640adca6564193a8f5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/Editor/ShaderGraph/UnityPackageImporter.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/GameObjectContainer.cs b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/GameObjectContainer.cs new file mode 100644 index 00000000..08e0c962 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/GameObjectContainer.cs @@ -0,0 +1,44 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using System.Collections.Generic; +using UnityEngine; + +namespace MagicaCloth2 +{ + public class GameObjectContainer : MonoBehaviour + { + [SerializeField] + private List gameObjectList = new List(); + + + private Dictionary gameObjectDict = new Dictionary(); + + protected void Awake() + { + // create dictionary. + foreach (var obj in gameObjectList) + { + if (obj) + { + gameObjectDict.Add(obj.name, obj); + } + } + } + + public bool Contains(string objName) + { + return gameObjectDict.ContainsKey(objName); + } + + public GameObject GetGameObject(string objName) + { + if (gameObjectDict.ContainsKey(objName)) + { + return gameObjectDict[objName]; + } + else + return null; + } + } +} diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/GameObjectContainer.cs.meta b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/GameObjectContainer.cs.meta new file mode 100644 index 00000000..2bc7af87 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/GameObjectContainer.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 4357444b3effcf149a7c0557d3c4ddc5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/GameObjectContainer.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/MagicaCloth2Example.asmdef b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/MagicaCloth2Example.asmdef new file mode 100644 index 00000000..f0713e7a --- /dev/null +++ b/Assets/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/MagicaCloth2/Example (Can be deleted)/Common/Scripts/MagicaCloth2Example.asmdef.meta b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/MagicaCloth2Example.asmdef.meta new file mode 100644 index 00000000..8fb4a072 --- /dev/null +++ b/Assets/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.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/MagicaCloth2Example.asmdef + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/ModelController.cs b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/ModelController.cs new file mode 100644 index 00000000..3889240c --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/ModelController.cs @@ -0,0 +1,82 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using System.Collections.Generic; +using UnityEngine; + +namespace MagicaCloth2 +{ + public class ModelController : MonoBehaviour + { + [SerializeField] + private List characterList = new List(); + + [SerializeField] + private float slowTime = 0.1f; + + private bool slow; + + protected void Start() + { + slow = false; + } + + private void AnimatorAction(System.Action act) + { + foreach (var chara in characterList) + { + if (chara && chara.activeInHierarchy) + { + var animator = chara.GetComponent(); + if (animator) + { + act(animator); + } + } + } + } + + private void ClothAction(System.Action act) + { + foreach (var chara in characterList) + { + if (chara && chara.activeInHierarchy) + { + var clothList = chara.GetComponentsInChildren(true); + if (clothList != null) + { + foreach (var cloth in clothList) + { + act(cloth); + } + } + } + } + } + + public void OnNextButton() + { + AnimatorAction((ani) => ani.SetTrigger("Next")); + } + + public void OnBackButton() + { + AnimatorAction((ani) => ani.SetTrigger("Back")); + } + + public void OnSlowButton() + { + slow = !slow; + + float timeScale = slow ? slowTime : 1.0f; + + AnimatorAction((ani) => ani.speed = timeScale); + ClothAction((cloth) => cloth.SetTimeScale(timeScale)); + } + + public void OnActiveButton() + { + ClothAction((cloth) => cloth.gameObject.SetActive(!cloth.gameObject.activeSelf)); + } + } +} diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/ModelController.cs.meta b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/ModelController.cs.meta new file mode 100644 index 00000000..89432ecb --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/ModelController.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 49572a6b5327127438636ad59bdb9226 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/ModelController.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/RuntimeBuildDemo.cs b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/RuntimeBuildDemo.cs new file mode 100644 index 00000000..5837b149 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/RuntimeBuildDemo.cs @@ -0,0 +1,248 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using UnityEngine; + +namespace MagicaCloth2 +{ + /// + /// A sample that builds MagicaCloth at runtime. + /// + public class RuntimeBuildDemo : MonoBehaviour + { + [SerializeField] + private GameObject characterPrefab; + [SerializeField] + private MagicaCloth frontHairSource; + [SerializeField] + private string ribbonPresetName; + [SerializeField] + private string skirtName; + [SerializeField] + private Texture2D skirtPaintMap; + + GameObject character; + GameObjectContainer gameObjectContainer; + + protected void Start() + { + character = null; + gameObjectContainer = null; + } + + public void OnCreateButton() + { + if (character) + return; + + // Generate a character from a prefab. + GenerateCharacter(); + + // BoneCloth construction example (1). + SetupHairTail_BoneCloth(); + + // BoneCloth construction example (2). + SetupFrontHair_BoneCloth(); + + // BoneCloth construction example (3). + SetupRibbon_BoneCloth(); + + // MeshCloth construction example (1). + SetupSkirt_MeshCloth(); + } + + public void OnRemoveButton() + { + if (character) + { + Destroy(character); + character = null; + gameObjectContainer = null; + } + } + + /// + /// Generate a character from a prefab. + /// A character already contains a to reference a GameObject. + /// This component is optional. + /// It's just there to help with data construction. + /// + void GenerateCharacter() + { + if (characterPrefab) + { + character = Instantiate(characterPrefab, transform); + gameObjectContainer = character.GetComponent(); + } + } + + /// + /// BoneCloth construction example (1). + /// Set all parameters from a script. + /// + void SetupHairTail_BoneCloth() + { + if (character == null) + return; + + var obj = new GameObject("HairTail_BoneCloth"); + obj.transform.SetParent(character.transform, false); + + // add Magica Cloth + var cloth = obj.AddComponent(); + var sdata = cloth.SerializeData; + + // bone cloth + sdata.clothType = ClothProcess.ClothType.BoneCloth; + sdata.rootBones.Add(gameObjectContainer.GetGameObject("J_L_HairTail_00_B").transform); + sdata.rootBones.Add(gameObjectContainer.GetGameObject("J_R_HairTail_00_B").transform); + + // setup parameters + sdata.gravity = 3.0f; + sdata.damping.SetValue(0.05f); + sdata.angleRestorationConstraint.stiffness.SetValue(0.15f, 1.0f, 0.15f, true); + sdata.angleRestorationConstraint.velocityAttenuation = 0.6f; + sdata.tetherConstraint.distanceCompression = 0.5f; + sdata.inertiaConstraint.particleSpeedLimit.SetValue(true, 3.0f); + sdata.colliderCollisionConstraint.mode = ColliderCollisionConstraint.Mode.None; + + // start build + cloth.BuildAndRun(); + } + + /// + /// BoneCloth construction example (2). + /// Copy parameters from an existing component. + /// + void SetupFrontHair_BoneCloth() + { + if (character == null || frontHairSource == null) + return; + + var obj = new GameObject("HairFront_BoneCloth"); + obj.transform.SetParent(character.transform, false); + + // add Magica Cloth + var cloth = obj.AddComponent(); + var sdata = cloth.SerializeData; + + // bone cloth + sdata.clothType = ClothProcess.ClothType.BoneCloth; + sdata.rootBones.Add(gameObjectContainer.GetGameObject("J_L_HairFront_00_B").transform); + sdata.rootBones.Add(gameObjectContainer.GetGameObject("J_L_HairSide2_00_B").transform); + sdata.rootBones.Add(gameObjectContainer.GetGameObject("J_L_HairSide_00_B").transform); + sdata.rootBones.Add(gameObjectContainer.GetGameObject("J_R_HairFront_00_B").transform); + sdata.rootBones.Add(gameObjectContainer.GetGameObject("J_R_HairSide2_00_B").transform); + sdata.rootBones.Add(gameObjectContainer.GetGameObject("J_R_HairSide_00_B").transform); + + // Normal direction setting for backstop + sdata.normalAlignmentSetting.alignmentMode = NormalAlignmentSettings.AlignmentMode.Transform; + sdata.normalAlignmentSetting.adjustmentTransform = gameObjectContainer.GetGameObject("HeadCenter").transform; + + // setup parameters + // Copy from source settings + sdata.Import(frontHairSource, false); + + // start build + cloth.BuildAndRun(); + } + + /// + /// BoneCloth construction example (3). + /// Load parameters from saved presets. + /// + void SetupRibbon_BoneCloth() + { + if (character == null || string.IsNullOrEmpty(ribbonPresetName)) + return; + + var obj = new GameObject("Ribbon_BoneCloth"); + obj.transform.SetParent(character.transform, false); + + // add Magica Cloth + var cloth = obj.AddComponent(); + var sdata = cloth.SerializeData; + + // bone cloth + sdata.clothType = ClothProcess.ClothType.BoneCloth; + sdata.rootBones.Add(gameObjectContainer.GetGameObject("J_L_HeadRibbon_00_B").transform); + sdata.rootBones.Add(gameObjectContainer.GetGameObject("J_R_HeadRibbon_00_B").transform); + + // setup parameters + // Load presets from the Resource folder. + // Since presets are in TextAssets format, they can also be used as asset bundles. + var presetText = Resources.Load(ribbonPresetName); + sdata.ImportJson(presetText.text); + + // start build + cloth.BuildAndRun(); + } + + /// + /// MeshCloth construction example (1). + /// Reads vertex attributes from a paintmap. + /// + void SetupSkirt_MeshCloth() + { + if (character == null || skirtPaintMap == null) + return; + + // skirt renderer + var sobj = gameObjectContainer.GetGameObject(skirtName); + if (sobj == null) + return; + if (!sobj.TryGetComponent(out var skirtRenderer)) + return; + + // add Magica Cloth + var obj = new GameObject("Skirt_MeshCloth"); + obj.transform.SetParent(character.transform, false); + var cloth = obj.AddComponent(); + var sdata = cloth.SerializeData; + + // mesh cloth + sdata.clothType = ClothProcess.ClothType.MeshCloth; + sdata.sourceRenderers.Add(skirtRenderer); + + // reduction settings + sdata.reductionSetting.simpleDistance = 0.0212f; + sdata.reductionSetting.shapeDistance = 0.0244f; + + // paint map settings + // *** Paintmaps must have Read/Write attributes enabled! *** + sdata.paintMode = ClothSerializeData.PaintMode.Texture_Fixed_Move; + sdata.paintMaps.Add(skirtPaintMap); + + // setup parameters + sdata.gravity = 1.0f; + sdata.damping.SetValue(0.03f); + sdata.angleRestorationConstraint.stiffness.SetValue(0.05f, 1.0f, 0.5f, true); + sdata.angleRestorationConstraint.velocityAttenuation = 0.5f; + sdata.angleLimitConstraint.useAngleLimit = true; + sdata.angleLimitConstraint.limitAngle.SetValue(45.0f, 0.0f, 1.0f, true); + sdata.distanceConstraint.stiffness.SetValue(0.5f, 1.0f, 0.5f, true); + sdata.tetherConstraint.distanceCompression = 0.9f; + sdata.inertiaConstraint.depthInertia = 0.7f; + sdata.inertiaConstraint.movementSpeedLimit.SetValue(true, 3.0f); + sdata.inertiaConstraint.particleSpeedLimit.SetValue(true, 3.0f); + 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); + lobj.transform.localEulerAngles = new Vector3(0.23f, 16.376f, -0.028f); + var colliderL = lobj.AddComponent(); + colliderL.direction = MagicaCapsuleCollider.Direction.Z; + colliderL.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); + + // start build + cloth.BuildAndRun(); + } + } +} diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/RuntimeBuildDemo.cs.meta b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/RuntimeBuildDemo.cs.meta new file mode 100644 index 00000000..09427b80 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/RuntimeBuildDemo.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: d0126e2925cecdf4a933c28a27f415ac +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/RuntimeBuildDemo.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/RuntimeDressUpDemo.cs b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/RuntimeDressUpDemo.cs new file mode 100644 index 00000000..d11978ff --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/RuntimeDressUpDemo.cs @@ -0,0 +1,210 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using System.Collections.Generic; +using UnityEngine; + +namespace MagicaCloth2 +{ + /// + /// Dress-up sample. + /// + public class RuntimeDressUpDemo : MonoBehaviour + { + /// + /// Avatar to change clothes. + /// + public GameObject targetAvatar; + + /// + /// Hair prefab with MagicaCloth set in advance. + /// + public GameObject hariEqupPrefab; + + /// + /// Clothes prefab with MagicaCloth set in advance. + /// + public GameObject bodyEquipPrefab; + + //========================================================================================= + /// + /// Bones dictionary of avatars to dress up. + /// + Dictionary targetAvatarBoneMap = new Dictionary(); + + /// + /// Information class for canceling dress-up. + /// + class EquipInfo + { + public GameObject equipObject; + public List colliderList; + + public bool IsValid() => equipObject != null; + } + EquipInfo hairEquipInfo = new EquipInfo(); + EquipInfo bodyEquipInfo = new EquipInfo(); + + //========================================================================================= + protected void Start() + { + Init(); + } + + //========================================================================================= + public void OnHairEquipButton() + { + if (hairEquipInfo.IsValid()) + Remove(hairEquipInfo); + else + Equip(hariEqupPrefab, hairEquipInfo); + } + + public void OnBodyEquipButton() + { + if (bodyEquipInfo.IsValid()) + Remove(bodyEquipInfo); + else + Equip(bodyEquipPrefab, bodyEquipInfo); + } + + //========================================================================================= + /// + /// Create an avatar bone dictionary in advance. + /// + void Init() + { + Debug.Assert(targetAvatar); + + // Create all bone maps for the target avatar + foreach (Transform bone in targetAvatar.GetComponentsInChildren()) + { + if (targetAvatarBoneMap.ContainsKey(bone.name) == false) + { + targetAvatarBoneMap.Add(bone.name, bone); + } + else + { + Debug.Log($"Duplicate bone name :{bone.name}"); + } + } + } + + /// + /// Equip clothes. + /// + /// + /// + void Equip(GameObject equipPrefab, EquipInfo einfo) + { + Debug.Assert(equipPrefab); + + // Generate a prefab with cloth set up. + var gobj = Instantiate(equipPrefab, targetAvatar.transform); + + // All cloth components included in the prefab. + var clothList = new List(gobj.GetComponentsInChildren()); + + // All collider components included in the prefab. + var colliderList = new List(gobj.GetComponentsInChildren()); + + // All renderers included in the prefab. + var skinList = new List(gobj.GetComponentsInChildren()); + + // First stop the automatic build that is executed with Start(). + // And just in case, it does some initialization called Awake(). + foreach (var cloth in clothList) + { + // Normally it is called with Awake(), but if the component is disabled, it will not be executed, so call it manually. + // Ignored if already run with Awake(). + cloth.Initialize(); + + // Turn off auto-build on Start(). + cloth.DisableAutoBuild(); + } + + // Swap the bones of the SkinnedMeshRenderer. + // This process is a general dress-up process for SkinnedMeshRenderer. + // Comment out this series of processes when performing this process with functions such as other assets. + foreach (var sren in skinList) + { + var bones = sren.bones; + Transform[] newBones = new Transform[bones.Length]; + + for (int i = 0; i < bones.Length; ++i) + { + Transform bone = bones[i]; + if (!targetAvatarBoneMap.TryGetValue(bone.name, out newBones[i])) + { + // Is the bone the renderer itself? + if (bone.name == sren.name) + { + newBones[i] = sren.transform; + } + else + { + // bone not found + Debug.Log($"[SkinnedMeshRenderer({sren.name})] Unable to map bone [{bone.name}] to target skeleton."); + } + } + } + sren.bones = newBones; + + // root bone + if (targetAvatarBoneMap.ContainsKey(sren.rootBone != null ? sren.rootBone.name : null)) + { + sren.rootBone = targetAvatarBoneMap[sren.rootBone.name]; + } + } + + // Here, replace the bones used by the MagicaCloth component. + foreach (var cloth in clothList) + { + // Replaces a component's transform. + cloth.ReplaceTransform(targetAvatarBoneMap); + } + + // Move all colliders to the new avatar. + foreach (var collider in colliderList) + { + Transform parent = collider.transform.parent; + if (parent && targetAvatarBoneMap.ContainsKey(parent.name)) + { + Transform newParent = targetAvatarBoneMap[parent.name]; + + // After changing the parent, you need to write back the local posture and align it. + collider.transform.GetLocalPositionAndRotation(out var localPosition, out var localRotation); + collider.transform.SetParent(newParent); + collider.transform.SetLocalPositionAndRotation(localPosition, localRotation); + } + } + + // Finally let's start building the cloth component. + foreach (var cloth in clothList) + { + // I disabled the automatic build, so I build it manually. + cloth.BuildAndRun(); + } + + // Record information for release. + einfo.equipObject = gobj; + einfo.colliderList = colliderList; + } + + /// + /// Removes equipped clothing. + /// + /// + void Remove(EquipInfo einfo) + { + Destroy(einfo.equipObject); + foreach (var c in einfo.colliderList) + { + Destroy(c.gameObject); + } + + einfo.equipObject = null; + einfo.colliderList.Clear(); + } + } +} diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/RuntimeDressUpDemo.cs.meta b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/RuntimeDressUpDemo.cs.meta new file mode 100644 index 00000000..9a678e18 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/RuntimeDressUpDemo.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: e72f8cfc2a22d184e86b4e1905cdf3ec +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/RuntimeDressUpDemo.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/SimpleInput.cs b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/SimpleInput.cs new file mode 100644 index 00000000..ab3496ce --- /dev/null +++ b/Assets/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/MagicaCloth2/Example (Can be deleted)/Common/Scripts/SimpleInput.cs.meta b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/SimpleInput.cs.meta new file mode 100644 index 00000000..bed46530 --- /dev/null +++ b/Assets/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.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/SimpleInput.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/SimpleInputManager.cs b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/SimpleInputManager.cs new file mode 100644 index 00000000..80aff6c0 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/SimpleInputManager.cs @@ -0,0 +1,602 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using UnityEngine; +using UnityEngine.Events; +using UnityEngine.EventSystems; + +namespace MagicaCloth2 +{ + /// + /// 入力マネージャ + /// ・簡単なタップやフリック判定 + /// ・PCの場合はマウスによる自動エミュレーション + /// + public class SimpleInputManager : CreateSingleton + { + // 最大タッチ数 + private const int MaxFinger = 3; + + /// + /// タップ有効半径(cm) + /// + public float tapRadiusCm = 0.5f; + + /// + /// フリック判定距離(cm) + /// + public float flickRangeCm = 0.01f; + + /// + /// フリック判定速度(cm/s) + /// + public float flickCheckSpeed = 1.0f; + + /// + /// マウスホイールのピンチイン・ピンチアウト速度係数 + /// + public float mouseWheelSpeed = 5.0f; + + // 入力情報管理 + private int mainFingerId = -1; + private int subFingerId = -1; + private Vector2[] downPos; // 入力開始座標(スクリーン) + private Vector2[] lastPos; + private Vector2[] flickDownPos; // 入力開始座標(スクリーン) + private float[] flickDownTime; + private float lastTime = 0; // バックボタンの連続入力防止用 + + // モバイル情報管理 + private bool mobilePlatform = false; + + // マウスエミュレーション情報管理 + private bool[] mouseDown; + private Vector2[] mouseOldMovePos; + + // モニタ情報 + private float screenDpi; // スクリーンDPI値 + private float screenDpc; // スクリーンDots per cm値(1cm当たりのピクセル数) + + //------------------------------ モバイルタッチパネル/マウスエミュレーション ------------------ + // タッチ開始通知 + // タッチされた時に、フィンガーID、その位置(スクリーン)を通知します。 + public static UnityAction OnTouchDown; + + // 移動通知 + // タッチされたまま移動された場合に、フィンガーID、その位置(スクリーン)、速度(スクリーン比率/s)、速度(cm/s)を通知します。 + public static UnityAction OnTouchMove; + + // ダブルタッチされたまま移動された場合に、フィンガーID、その位置(スクリーン)、速度(スクリーン比率/s)、速度(cm/s)を通知します。 + public static UnityAction OnDoubleTouchMove; + + // タッチ終了通知 + // タッチが離されたフィンガーID、位置(スクリーン)を通知します。 + public static UnityAction OnTouchUp; + + // タッチキャンセル通知 + // タッチ移動がキャンセル(主に画面外に移動)された場合に、フィンガーID、その最終位置(スクリーン)を通知します。 + public static UnityAction OnTouchMoveCancel; + + // タップ通知 + // タップされた時に、フィンガーID、その位置(スクリーン)を通知します。 + public static UnityAction OnTouchTap; + + // フリック通知 + // フリック判定された場合に、フィンガーID、その位置(スクリーン)、フリック速度(スクリーン比率/s)、速度(cm/s)を通知します。 + public static UnityAction OnTouchFlick; + + // ピンチイン/アウト通知 + // ピンチイン/アウトの速度(スクリーン比率/s)、速度(cm/s)を通知します。 + public static UnityAction OnTouchPinch; + + // バックボタン通知(Androiddeでは戻るボタン、PCでは BackSpace ボタン) + public static UnityAction OnBackButton; + + //========================================================================================= + /// + /// Reload Domain 対策 + /// + [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] + private static void Init() + { + InitMember(); + } + + //========================================================================================= + protected override void InitSingleton() + { + SimpleInput.Init(); + + // スクリーン情報 + CalcScreenDpi(); + + // 情報初期化 + downPos = new Vector2[MaxFinger]; + lastPos = new Vector2[MaxFinger]; + flickDownPos = new Vector2[MaxFinger]; + flickDownTime = new float[MaxFinger]; + + // マウス用 + mouseDown = new bool[3]; + mouseOldMovePos = new Vector2[3]; + + AllResetTouchInfo(); + + // モバイルプラットフォーム判定 + mobilePlatform = Application.isMobilePlatform; + } + + protected void Update() + { + // 入力タイプ別更新処理 + if (mobilePlatform) + { + // モバイル用タッチ入力 + UpdateMobile(); + } + else + { + // マウスエミュレーション + UpdateMouse(); + } + } + + //========================================================================================= + /// + /// スクリーンのDPI値(Dots per inchi)1インチ当たりのピクセル数を取得する + /// + public static float ScreenDpi + { + get + { + return Instance.screenDpi; + } + } + + /// + /// スクリーンのDPC値(Dots per cm)1cm当たりのピクセル数を取得する + /// + public static float ScreenDpc + { + get + { + return Instance.screenDpc; + } + } + + /// + /// スクリーンDpi/Dpcの再計算 + /// + private void CalcScreenDpi() + { + screenDpi = Screen.dpi; + if (screenDpi == 0.0f) + { + screenDpi = 96; // ダミー + } + screenDpc = screenDpi / 2.54f; // インチをcmに変換 + } + + // タッチ入力情報リセット + private void AllResetTouchInfo() + { + mainFingerId = -1; + subFingerId = -1; + for (int i = 0; i < 3; i++) + { + mouseDown[i] = false; + } + } + + public int GetTouchCount() + { + return SimpleInput.touchCount; + } + + public bool IsUI() + { + if (EventSystem.current == null) + return false; + + if (mobilePlatform) + { + // モバイル用タッチ入力 + return EventSystem.current.IsPointerOverGameObject(SimpleInput.GetTouch(0).fingerId); + } + else + { + // マウスエミュレーション + return EventSystem.current.IsPointerOverGameObject(); + } + } + + //========================================================================================= + /// + /// モバイル用入力更新 + /// + private void UpdateMobile() + { + int count = SimpleInput.touchCount; + + if (count == 0) + { + AllResetTouchInfo(); + + // バックボタン + if (Application.platform == RuntimePlatform.Android) + { + if (SimpleInput.GetKey(KeyCode.Escape) && lastTime + 0.2f < Time.time) + { + lastTime = Time.time; + if (OnBackButton != null) + { + OnBackButton(); + } + return; + } + } + } + else + { + // メイン + for (int i = 0; i < count; i++) + { + Touch touch = SimpleInput.GetTouch(i); + int fid = touch.fingerId; + + // フィンガーIDが0と1以外は無視する + if (fid >= 2) + { + continue; + } + + if (touch.phase == TouchPhase.Began) + { + if (IsUI()) + continue; + // down pos + downPos[fid] = touch.position; + lastPos[fid] = touch.position; + flickDownPos[fid] = touch.position; + + if (fid == 0) + { + mainFingerId = fid; + } + else + { + subFingerId = fid; + } + + // Downはメインフィンガーのみ + if (fid == 0) + { + flickDownTime[fid] = Time.time; + if (OnTouchDown != null) + { + OnTouchDown(fid, touch.position); + } + } + } + else if (touch.phase == TouchPhase.Moved) + { + // ピンチイン/アウト判定 + if (mainFingerId >= 0 && subFingerId >= 0) + { + Vector2 t1pos = Vector2.zero; + Vector2 t2pos = Vector2.zero; + Vector2 t1delta = Vector2.zero; + Vector2 t2delta = Vector2.zero; + + int setcnt = 0; + for (int j = 0; j < count; j++) + { + Touch t = SimpleInput.GetTouch(j); + if (mainFingerId == t.fingerId) + { + t1pos = t.position; + t1delta = t.deltaPosition; + setcnt++; + } + else if (subFingerId == t.fingerId) + { + t2pos = t.position; + t2delta = t.deltaPosition; + setcnt++; + } + } + + if (setcnt == 2) + { + float nowdist = Vector2.Distance(t1pos, t2pos); + float olddist = Vector2.Distance(t1pos - t1delta, t2pos - t2delta); + float dist = nowdist - olddist; + + // cm/sに変換 + float distcm = dist / screenDpc; // 移動量(cm) + float speedcm = distcm / Time.deltaTime; // 速度(cm/s) + + // スクリーン比率の速度 + float speedscr = (dist / (Screen.width + Screen.height) * 0.5f) / Time.deltaTime; + + // ピンチ通知(移動量(cm), 速度(cm/s)) + if (OnTouchPinch != null) + { + OnTouchPinch(speedscr, speedcm); + } + } + + if (fid == 0) + { + Vector2 distVec2 = touch.position - lastPos[fid]; + Vector2 distcm = distVec2 / screenDpc; // 移動量(cm) + Vector2 speedcm = distcm / Time.deltaTime; // 速度(cm/s) + + // 速度(スクリーン比率) + Vector2 speedscr = CalcScreenRatioVector(distVec2) / Time.deltaTime; + + // 移動通知(現在スクリーン座標、速度(スクリーン比率), 速度(cm/s)) + if (OnDoubleTouchMove != null) + { + OnDoubleTouchMove(fid, touch.position, speedscr, speedcm); + } + + lastPos[fid] = touch.position; + } + } + else + { + // Moveはメインフィンガーのみ + if (fid == 0 && mainFingerId >= 0) + { + Vector2 distVec2 = touch.position - lastPos[fid]; + Vector2 distcm = distVec2 / screenDpc; // 移動量(cm) + Vector2 speedcm = distcm / Time.deltaTime; // 速度(cm/s) + + // 速度(スクリーン比率) + Vector2 speedscr = CalcScreenRatioVector(distVec2) / Time.deltaTime; + + // 移動通知(現在スクリーン座標、速度(スクリーン比率), 速度(cm/s)) + if (OnTouchMove != null) + { + OnTouchMove(fid, touch.position, speedscr, speedcm); + } + + // フリックダウン位置更新 + flickDownPos[fid] = (flickDownPos[fid] + touch.position) * 0.5f; + flickDownTime[fid] = Time.time; + } + + lastPos[fid] = touch.position; + } + } + else if (touch.phase == TouchPhase.Ended) + { + // フィンガーIDのリリース + if (fid == 0) + { + mainFingerId = -1; + subFingerId = -1; + } + else + { + subFingerId = -1; + } + + // End, Tap はメインフィンガーのみ + if (fid == 0) + { + // タップ判定 + float dist = Vector2.Distance(downPos[fid], touch.position); + float distcm = dist / screenDpc; + + if (distcm <= tapRadiusCm) + { + // タップ通知 + if (OnTouchTap != null) + { + OnTouchTap(fid, touch.position); + } + } + // フリック判定 + else + { + CheckFlic(fid, downPos[fid], touch.position, flickDownPos[fid], flickDownTime[fid]); + } + + // タップアップ通知 + if (OnTouchUp != null) + { + OnTouchUp(fid, touch.position); + } + } + } + else if (touch.phase == TouchPhase.Canceled) + { + // フィンガーIDのリリース + if (fid == 0) + { + mainFingerId = -1; + subFingerId = -1; + } + else + { + subFingerId = -1; + } + + // Cancelはメインフィンガーのみ + if (fid == 0) + { + if (OnTouchMoveCancel != null) + { + OnTouchMoveCancel(fid, touch.position); + } + } + } + } + } + } + + /// + /// スクリーン比率に変換したベクトルを求める + /// + /// + /// + private Vector2 CalcScreenRatioVector(Vector2 vec) + { + return new Vector2(vec.x / Screen.width, vec.y / Screen.height); + } + + /// + /// フリック判定 + /// + /// + /// + /// + /// + /// + private bool CheckFlic(int fid, Vector2 oldpos, Vector2 nowpos, Vector2 downpos, float flicktime) + { + // フリック判定 + float dist = Vector2.Distance(nowpos, downpos); + float distcm = dist / screenDpc; + if (distcm > flickRangeCm) + { + { + // 移動ピクセルをcm変換し、速度cm/sを割り出す + Vector2 distVec = (nowpos - downpos); + Vector2 distVec2 = distVec / screenDpc; // cmへ変換(移動量(cm)) + float timeInterval = Time.time - flicktime; + float speedX = distVec2.x / timeInterval; // 速度(cm/s) + float speedY = distVec2.y / timeInterval; // 速度(cm/s) + + //Develop.Log("distVec", distVec * 100); + //Develop.Log("sppedX:", speedX, " speedY:", speedY); + + if (Mathf.Abs(speedX) >= flickCheckSpeed || Mathf.Abs(speedY) >= flickCheckSpeed) + { + // フリック通知(スクリーン位置,速度(スクリーン比率/s),速度(cm/s)) + if (OnTouchFlick != null) + { + OnTouchFlick(fid, nowpos, CalcScreenRatioVector(distVec) / timeInterval, new Vector2(speedX, speedY)); + } + + return true; + } + } + } + + return false; + } + + //========================================================================================= + /// + /// 入力情報更新(PC用) + /// マウスエミュレーション + /// ・右クリックは使わない。 + /// ・ピンチイン/アウトはマウスホイール。 + /// + private void UpdateMouse() + { + // BackSpace を Android 端末のバックボタンに割り当てる + if (SimpleInput.GetKeyDown(KeyCode.Backspace)) + { + if (OnBackButton != null) + OnBackButton(); + return; + } + + for (int i = 0; i < 3; i++) + { + // マウスボタンダウン + if (SimpleInput.GetMouseButtonDown(i)) + { + if (IsUI()) + continue; + + if (mouseDown[i] == false && i == 0) + { + flickDownTime[i] = Time.time; + } + mouseDown[i] = true; + + // 入力位置を記録 + downPos[i] = SimpleInput.mousePosition; + mouseOldMovePos[i] = SimpleInput.mousePosition; + if (i == 0) + flickDownPos[i] = SimpleInput.mousePosition; + + // タッチダウンイベント発行 + if (OnTouchDown != null) + OnTouchDown(i, SimpleInput.mousePosition); + } + + // マウスボタンアップ + if (SimpleInput.GetMouseButtonUp(i) && mouseDown[i]) + { + mouseDown[i] = false; + + // フリック判定 + if (i == 0) + { + CheckFlic(i, mouseOldMovePos[i], SimpleInput.mousePosition, flickDownPos[i], flickDownTime[i]); + } + + mouseOldMovePos[i] = Vector2.zero; + + // タッチアップイベント + if (OnTouchUp != null) + OnTouchUp(i, SimpleInput.mousePosition); + + // タップ判定 + float distcm = Vector2.Distance(downPos[0], SimpleInput.mousePosition) / screenDpc; + if (distcm <= tapRadiusCm) + { + if (OnTouchTap != null) + OnTouchTap(i, SimpleInput.mousePosition); + } + } + + // 移動 + if (mouseDown[i]) + { + Vector2 spos = new Vector2(SimpleInput.mousePosition.x, SimpleInput.mousePosition.y); + Vector2 delta = spos - mouseOldMovePos[i]; + + if (spos != mouseOldMovePos[i]) + { + // 速度 + Vector3 deltacm = delta / screenDpc; // 移動量(cm) + Vector2 speedcm = deltacm / Time.deltaTime; // 速度(cm/s) + + // 移動通知(現在スクリーン座標、速度(スクリーン比率/s)、速度(cm/s)) + if (OnTouchMove != null) + OnTouchMove(i, SimpleInput.mousePosition, CalcScreenRatioVector(delta) / Time.deltaTime, speedcm); + } + + mouseOldMovePos[i] = SimpleInput.mousePosition; + + // フリックダウン位置更新 + flickDownPos[i] = (flickDownPos[i] + spos) * 0.5f; + flickDownTime[i] = Time.time; + } + + } + + // ピンチイン/アウト + float w = SimpleInput.GetMouseScrollWheel(); + if (Mathf.Abs(w) > 0.01f) + { + // モバイル入力とスケール感を合わせるために係数を掛ける + w *= mouseWheelSpeed; + + float speedcm = w / Time.deltaTime; + float speedscr = (w / (Screen.width + Screen.height) * 0.5f) / Time.deltaTime; + + // 通知(速度(スクリーン比率/s)、速度(cm/s) + if (OnTouchPinch != null) + OnTouchPinch(speedscr, speedcm); + } + } + } +} diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/SimpleInputManager.cs.meta b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/SimpleInputManager.cs.meta new file mode 100644 index 00000000..1384c74f --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/SimpleInputManager.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 08208c43232950a4f8b6eae1f7919c13 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/SimpleInputManager.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/SliderText.cs b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/SliderText.cs new file mode 100644 index 00000000..a1d9026c --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/SliderText.cs @@ -0,0 +1,46 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using UnityEngine; +using UnityEngine.UI; + +namespace MagicaCloth2 +{ + public class SliderText : MonoBehaviour + { + [SerializeField] + private Text text = null; + + [SerializeField] + private string lable = ""; + + [SerializeField] + private string format = "0.00"; + + private string formatString; + + protected void Start() + { + formatString = "{0} ({1:" + format + "})"; + + var slider = GetComponent(); + if (slider) + { + slider.onValueChanged.AddListener(OnChangeValue); + + var val = slider.value; + slider.value = 0.001f; + slider.value = val; + } + + } + + private void OnChangeValue(float value) + { + if (text) + { + text.text = string.Format(formatString, lable, value); + } + } + } +} diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/SliderText.cs.meta b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/SliderText.cs.meta new file mode 100644 index 00000000..f42f1549 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/SliderText.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 37e7fecf2cf6fff42800da6e57c20d5d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/SliderText.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/TargetFPS.cs b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/TargetFPS.cs new file mode 100644 index 00000000..adac9cf1 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/TargetFPS.cs @@ -0,0 +1,19 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using UnityEngine; + +namespace MagicaCloth2 +{ + public class TargetFPS : MonoBehaviour + { + public int frameRate = 60; + +#if !UNITY_EDITOR + protected void Start() + { + Application.targetFrameRate = frameRate; + } +#endif + } +} diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/TargetFPS.cs.meta b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/TargetFPS.cs.meta new file mode 100644 index 00000000..abc92766 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/TargetFPS.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 70abefeafa131dd428880b40bd4c183c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/TargetFPS.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/WindDemo.cs b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/WindDemo.cs new file mode 100644 index 00000000..f422c383 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/WindDemo.cs @@ -0,0 +1,94 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using System.Collections.Generic; +using UnityEngine; + +namespace MagicaCloth2 +{ + public class WindDemo : MonoBehaviour + { + [SerializeField] + private MagicaWindZone magicaWindZone; + [SerializeField] + private WindZone unityWindZone; + [SerializeField] + private Renderer arrowRenderer = null; + [SerializeField] + private Gradient arrowGradient = new Gradient(); + [SerializeField] + private List rotationTransforms = new List(); + + private float angleY = 0.0f; + private float angleX = 0.0f; + private float main = 0.0f; + private float turbulence = 0.0f; + + public void OnDirectionY(float value) + { + angleY = value; + UpdateDirection(); + } + + public void OnDirectionX(float value) + { + angleX = value; + UpdateDirection(); + } + + public void OnMain(float value) + { + main = value; + UpdateMagicaWindZone(); + UpdateUnityWindZone(); + UpdateArrowColor(); + } + + public void OnTurbulence(float value) + { + turbulence = value; + UpdateMagicaWindZone(); + } + + //========================================================================================= + void UpdateArrowColor() + { + if (arrowRenderer) + { + // color + var t = Mathf.Clamp01(Mathf.InverseLerp(0.0f, 20.0f, main)); + var col = arrowGradient.Evaluate(t); + arrowRenderer.material.color = col * 0.7f; + } + } + + void UpdateDirection() + { + var lrot = Quaternion.Euler(angleX, angleY, 0.0f); + foreach (var t in rotationTransforms) + if (t) + t.localRotation = lrot; + + UpdateMagicaWindZone(); + } + + void UpdateMagicaWindZone() + { + if (magicaWindZone) + { + magicaWindZone.main = main; + magicaWindZone.turbulence = turbulence; + magicaWindZone.directionAngleX = angleX; + magicaWindZone.directionAngleY = angleY; + } + } + + void UpdateUnityWindZone() + { + if (unityWindZone) + { + unityWindZone.windMain = main; + } + } + } +} diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/WindDemo.cs.meta b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/WindDemo.cs.meta new file mode 100644 index 00000000..7492ff5f --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/WindDemo.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 13f11cb1bd01c684b9a48fd075e6a541 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/WindDemo.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/Common/Shaders.meta b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Shaders.meta new file mode 100644 index 00000000..e5eda76c --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Shaders.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 399b9b712612aee4895e5d0c4dd98d3d +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/Common/Shaders/MC2_Common_Lit_Back.shadergraph b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Shaders/MC2_Common_Lit_Back.shadergraph new file mode 100644 index 00000000..ca01279f --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Shaders/MC2_Common_Lit_Back.shadergraph @@ -0,0 +1,2336 @@ +{ + "m_SGVersion": 3, + "m_Type": "UnityEditor.ShaderGraph.GraphData", + "m_ObjectId": "f41d4d9b57ae4b59b26678b1f6073750", + "m_Properties": [ + { + "m_Id": "4ff00e04725b4223818808fa53a54254" + }, + { + "m_Id": "ddfd2e0ff3934cee81c59223a6aff2c9" + }, + { + "m_Id": "4e56b0554c1541eebaad6914417685a2" + }, + { + "m_Id": "f82b9f46e40e431fae1d5ec7c3707e42" + } + ], + "m_Keywords": [], + "m_Dropdowns": [], + "m_CategoryData": [ + { + "m_Id": "4b4d7767a3c04b13992378fe6f0758c1" + } + ], + "m_Nodes": [ + { + "m_Id": "10be29e472174f9bac547bf66ae09a6e" + }, + { + "m_Id": "d8cd689a35ac40ccb7fc9fa38bfedb1b" + }, + { + "m_Id": "a3f302f80ed844ffbf44b99dd893415e" + }, + { + "m_Id": "dcc961838b80405199d4e7d4c1f4fd7d" + }, + { + "m_Id": "547c3a6093244b539b47f013a879b43a" + }, + { + "m_Id": "7d896f4d35f540dfb9dacc35ddec6afa" + }, + { + "m_Id": "b3a7b8c6105d4a9d99f2c0e475229395" + }, + { + "m_Id": "7f1e5a6638cc46108a2ef6f3335f7db6" + }, + { + "m_Id": "3e52a198523e4e8089a6a40a3969a3b7" + }, + { + "m_Id": "85cc4ac9d59d4ff9a65f96c816207a3f" + }, + { + "m_Id": "f538dbc91a2f4d8d8f4b21556d67960b" + }, + { + "m_Id": "f8ebcdc66077436288a397d204bbd8cd" + }, + { + "m_Id": "f5609f11baf94d889ab3f8bf42aa2131" + }, + { + "m_Id": "85fc068f71f9403e9b327a6076c0726d" + }, + { + "m_Id": "b75bfd40495a47c687573a825b006ec3" + }, + { + "m_Id": "baceccda18a146aabc489ed8fe66e00e" + }, + { + "m_Id": "dad6f28cdb54429b9ec2c4474304b92c" + }, + { + "m_Id": "c3fae475af5f494782e2283aab0b42e4" + }, + { + "m_Id": "36e45cd12e3a4bb39df36dfdba2d165f" + }, + { + "m_Id": "b91e9b998964417096174d43beedd509" + }, + { + "m_Id": "85e4660eb18e4763bd4a2c7fca16df72" + }, + { + "m_Id": "1b135e3a26af4cffae7fb6fc68befcfc" + }, + { + "m_Id": "ad74695cfc12453188fbb4d17b6c96c2" + } + ], + "m_GroupDatas": [], + "m_StickyNoteDatas": [], + "m_Edges": [ + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "36e45cd12e3a4bb39df36dfdba2d165f" + }, + "m_SlotId": 0 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "ad74695cfc12453188fbb4d17b6c96c2" + }, + "m_SlotId": 0 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "85cc4ac9d59d4ff9a65f96c816207a3f" + }, + "m_SlotId": 0 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "f5609f11baf94d889ab3f8bf42aa2131" + }, + "m_SlotId": 0 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "85e4660eb18e4763bd4a2c7fca16df72" + }, + "m_SlotId": 3 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "dad6f28cdb54429b9ec2c4474304b92c" + }, + "m_SlotId": 0 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "85fc068f71f9403e9b327a6076c0726d" + }, + "m_SlotId": 0 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "b3a7b8c6105d4a9d99f2c0e475229395" + }, + "m_SlotId": 0 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "ad74695cfc12453188fbb4d17b6c96c2" + }, + "m_SlotId": 1 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "d8cd689a35ac40ccb7fc9fa38bfedb1b" + }, + "m_SlotId": 0 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "b75bfd40495a47c687573a825b006ec3" + }, + "m_SlotId": 3 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "f8ebcdc66077436288a397d204bbd8cd" + }, + "m_SlotId": 2 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "b91e9b998964417096174d43beedd509" + }, + "m_SlotId": 0 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "85e4660eb18e4763bd4a2c7fca16df72" + }, + "m_SlotId": 0 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "baceccda18a146aabc489ed8fe66e00e" + }, + "m_SlotId": 0 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "b75bfd40495a47c687573a825b006ec3" + }, + "m_SlotId": 1 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "f538dbc91a2f4d8d8f4b21556d67960b" + }, + "m_SlotId": 0 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "f8ebcdc66077436288a397d204bbd8cd" + }, + "m_SlotId": 1 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "f5609f11baf94d889ab3f8bf42aa2131" + }, + "m_SlotId": 2 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "dcc961838b80405199d4e7d4c1f4fd7d" + }, + "m_SlotId": 0 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "f8ebcdc66077436288a397d204bbd8cd" + }, + "m_SlotId": 0 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "f5609f11baf94d889ab3f8bf42aa2131" + }, + "m_SlotId": 1 + } + } + ], + "m_VertexContext": { + "m_Position": { + "x": 0.0, + "y": 0.0 + }, + "m_Blocks": [ + { + "m_Id": "10be29e472174f9bac547bf66ae09a6e" + }, + { + "m_Id": "d8cd689a35ac40ccb7fc9fa38bfedb1b" + }, + { + "m_Id": "a3f302f80ed844ffbf44b99dd893415e" + } + ] + }, + "m_FragmentContext": { + "m_Position": { + "x": 0.0, + "y": 200.0 + }, + "m_Blocks": [ + { + "m_Id": "dcc961838b80405199d4e7d4c1f4fd7d" + }, + { + "m_Id": "547c3a6093244b539b47f013a879b43a" + }, + { + "m_Id": "7d896f4d35f540dfb9dacc35ddec6afa" + }, + { + "m_Id": "b3a7b8c6105d4a9d99f2c0e475229395" + }, + { + "m_Id": "7f1e5a6638cc46108a2ef6f3335f7db6" + }, + { + "m_Id": "3e52a198523e4e8089a6a40a3969a3b7" + }, + { + "m_Id": "dad6f28cdb54429b9ec2c4474304b92c" + }, + { + "m_Id": "c3fae475af5f494782e2283aab0b42e4" + }, + { + "m_Id": "1b135e3a26af4cffae7fb6fc68befcfc" + } + ] + }, + "m_PreviewData": { + "serializedMesh": { + "m_SerializedMesh": "{\"mesh\":{\"instanceID\":0}}", + "m_Guid": "" + }, + "preventRotation": false + }, + "m_Path": "Shader Graphs", + "m_GraphPrecision": 1, + "m_PreviewMode": 2, + "m_OutputNode": { + "m_Id": "" + }, + "m_ActiveTargets": [ + { + "m_Id": "1cefe9920a694056a32d6044c91eb117" + }, + { + "m_Id": "889230749e8b4e5b8ff8388a75e3e6f4" + }, + { + "m_Id": "70351697015745fca15077ddec8afc89" + } + ] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.BooleanMaterialSlot", + "m_ObjectId": "0067ec270e2b4a6c8186ff77a4d24e90", + "m_Id": 0, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 2, + "m_Value": true, + "m_DefaultValue": true +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.Rendering.HighDefinition.ShaderGraph.BuiltinData", + "m_ObjectId": "036dd76274464631a7d3a06d6e8483e7", + "m_Distortion": false, + "m_DistortionMode": 0, + "m_DistortionDepthTest": true, + "m_AddPrecomputedVelocity": false, + "m_TransparentWritesMotionVec": false, + "m_AlphaToMask": false, + "m_DepthOffset": false, + "m_ConservativeDepthOffset": false, + "m_TransparencyFog": true, + "m_AlphaTestShadow": false, + "m_BackThenFrontRendering": false, + "m_TransparentDepthPrepass": false, + "m_TransparentDepthPostpass": false, + "m_SupportLodCrossFade": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", + "m_ObjectId": "0a2d6e54a269462995058e94217b6f82", + "m_Id": 0, + "m_DisplayName": "In", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "In", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", + "m_ObjectId": "0b1293431328425da5ca8c5b3b333166", + "m_Id": 3, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Texture2DMaterialSlot", + "m_ObjectId": "0e30156cfe4e4283a0dde082768d533e", + "m_Id": 0, + "m_DisplayName": "Main", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_BareResource": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.BlockNode", + "m_ObjectId": "10be29e472174f9bac547bf66ae09a6e", + "m_Group": { + "m_Id": "" + }, + "m_Name": "VertexDescription.Position", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": 0.0, + "y": 0.0, + "width": 0.0, + "height": 0.0 + } + }, + "m_Slots": [ + { + "m_Id": "79a8c2197a1843f58e31684f0ac49dcb" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_SerializedDescriptor": "VertexDescription.Position" +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.BlockNode", + "m_ObjectId": "1b135e3a26af4cffae7fb6fc68befcfc", + "m_Group": { + "m_Id": "" + }, + "m_Name": "SurfaceDescription.AlphaClipThreshold", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": 0.0, + "y": 0.0, + "width": 0.0, + "height": 0.0 + } + }, + "m_Slots": [ + { + "m_Id": "ab9406cddef148cba7c487de1453ce4d" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_SerializedDescriptor": "SurfaceDescription.AlphaClipThreshold" +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "1c6b14984c74490d9e22845b989d3c38", + "m_Id": 7, + "m_DisplayName": "A", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "A", + "m_StageCapability": 2, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector2MaterialSlot", + "m_ObjectId": "1cb440ca7c114bc7bbf5c85750d2a3b1", + "m_Id": 2, + "m_DisplayName": "Offset", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "Offset", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 2, + "m_Type": "UnityEditor.Rendering.BuiltIn.ShaderGraph.BuiltInTarget", + "m_ObjectId": "1cefe9920a694056a32d6044c91eb117", + "m_ActiveSubTarget": { + "m_Id": "be4795b19cdd4426bcdabf79f1c24b0a" + }, + "m_AllowMaterialOverride": false, + "m_SurfaceType": 0, + "m_ZWriteControl": 0, + "m_ZTestMode": 4, + "m_AlphaMode": 0, + "m_RenderFace": 0, + "m_AlphaClip": true, + "m_CustomEditorGUI": "" +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector3MaterialSlot", + "m_ObjectId": "26c1f3e8ea1d4795b62c3dfe9fd0f48d", + "m_Id": 0, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 1.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "27a353a5cc96432fa692fdda747d8c67", + "m_Id": 5, + "m_DisplayName": "G", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "G", + "m_StageCapability": 2, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.ColorRGBMaterialSlot", + "m_ObjectId": "30615abfe8e94f039230bb345e2dc291", + "m_Id": 0, + "m_DisplayName": "Emission", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "Emission", + "m_StageCapability": 2, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [], + "m_ColorMode": 1, + "m_DefaultColor": { + "r": 0.0, + "g": 0.0, + "b": 0.0, + "a": 1.0 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.NormalVectorNode", + "m_ObjectId": "36e45cd12e3a4bb39df36dfdba2d165f", + "m_Group": { + "m_Id": "" + }, + "m_Name": "Normal Vector", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -930.3999633789063, + "y": -163.20001220703126, + "width": 206.4000244140625, + "height": 128.80001831054688 + } + }, + "m_Slots": [ + { + "m_Id": "26c1f3e8ea1d4795b62c3dfe9fd0f48d" + } + ], + "synonyms": [ + "surface direction" + ], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_PreviewMode": 2, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_Space": 0 +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.Rendering.HighDefinition.ShaderGraph.SystemData", + "m_ObjectId": "37519b892be8480ab341c1c4f7f12ff1", + "m_MaterialNeedsUpdateHash": 529, + "m_SurfaceType": 0, + "m_RenderingPass": 1, + "m_BlendMode": 0, + "m_ZTest": 4, + "m_ZWrite": false, + "m_TransparentCullMode": 2, + "m_OpaqueCullMode": 2, + "m_SortPriority": 0, + "m_AlphaTest": false, + "m_TransparentDepthPrepass": false, + "m_TransparentDepthPostpass": false, + "m_SupportLodCrossFade": false, + "m_DoubleSidedMode": 0, + "m_DOTSInstancing": false, + "m_CustomVelocity": false, + "m_Tessellation": false, + "m_TessellationMode": 0, + "m_TessellationFactorMinDistance": 20.0, + "m_TessellationFactorMaxDistance": 50.0, + "m_TessellationFactorTriangleSize": 100.0, + "m_TessellationShapeFactor": 0.75, + "m_TessellationBackFaceCullEpsilon": -0.25, + "m_TessellationMaxDisplacement": 0.009999999776482582, + "m_Version": 1, + "inspectorFoldoutMask": 1 +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.BlockNode", + "m_ObjectId": "3e52a198523e4e8089a6a40a3969a3b7", + "m_Group": { + "m_Id": "" + }, + "m_Name": "SurfaceDescription.Occlusion", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": 0.0, + "y": 0.0, + "width": 0.0, + "height": 0.0 + } + }, + "m_Slots": [ + { + "m_Id": "d62d1c4bb772482a93392ab836e9a3d9" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_SerializedDescriptor": "SurfaceDescription.Occlusion" +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.TangentMaterialSlot", + "m_ObjectId": "3f29e230e3d24419aee114c671d1e1a2", + "m_Id": 0, + "m_DisplayName": "Tangent", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "Tangent", + "m_StageCapability": 1, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [], + "m_Space": 0 +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.CategoryData", + "m_ObjectId": "4b4d7767a3c04b13992378fe6f0758c1", + "m_Name": "", + "m_ChildObjectList": [ + { + "m_Id": "4ff00e04725b4223818808fa53a54254" + }, + { + "m_Id": "ddfd2e0ff3934cee81c59223a6aff2c9" + }, + { + "m_Id": "4e56b0554c1541eebaad6914417685a2" + }, + { + "m_Id": "f82b9f46e40e431fae1d5ec7c3707e42" + } + ] +} + +{ + "m_SGVersion": 1, + "m_Type": "UnityEditor.ShaderGraph.Internal.Vector1ShaderProperty", + "m_ObjectId": "4e56b0554c1541eebaad6914417685a2", + "m_Guid": { + "m_GuidSerialized": "291c9d7d-b925-4410-9719-cbd950781678" + }, + "m_Name": "Smoothness", + "m_DefaultRefNameVersion": 1, + "m_RefNameGeneratedByDisplayName": "Smoothness", + "m_DefaultReferenceName": "_Smoothness", + "m_OverrideReferenceName": "", + "m_GeneratePropertyBlock": true, + "m_UseCustomSlotLabel": false, + "m_CustomSlotLabel": "", + "m_Precision": 0, + "overrideHLSLDeclaration": false, + "hlslDeclarationOverride": 0, + "m_Hidden": false, + "m_Value": 0.0, + "m_FloatType": 1, + "m_RangeValues": { + "x": 0.0, + "y": 1.0 + } +} + +{ + "m_SGVersion": 3, + "m_Type": "UnityEditor.ShaderGraph.Internal.ColorShaderProperty", + "m_ObjectId": "4ff00e04725b4223818808fa53a54254", + "m_Guid": { + "m_GuidSerialized": "2b85b46b-4c2e-4207-b64c-9ea0d9e7fe37" + }, + "m_Name": "Color", + "m_DefaultRefNameVersion": 1, + "m_RefNameGeneratedByDisplayName": "Color", + "m_DefaultReferenceName": "_Color", + "m_OverrideReferenceName": "", + "m_GeneratePropertyBlock": true, + "m_UseCustomSlotLabel": false, + "m_CustomSlotLabel": "", + "m_Precision": 0, + "overrideHLSLDeclaration": false, + "hlslDeclarationOverride": 0, + "m_Hidden": false, + "m_Value": { + "r": 1.0, + "g": 1.0, + "b": 1.0, + "a": 1.0 + }, + "isMainColor": false, + "m_ColorMode": 0 +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.UVMaterialSlot", + "m_ObjectId": "502dd87805614bd6bb2cd5674cb78d13", + "m_Id": 0, + "m_DisplayName": "UV", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "UV", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0 + }, + "m_Labels": [], + "m_Channel": 0 +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicValueMaterialSlot", + "m_ObjectId": "537ac3a52c2746868e48f15018591a5c", + "m_Id": 0, + "m_DisplayName": "A", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "A", + "m_StageCapability": 3, + "m_Value": { + "e00": 0.0, + "e01": 0.0, + "e02": 0.0, + "e03": 0.0, + "e10": 0.0, + "e11": 0.0, + "e12": 0.0, + "e13": 0.0, + "e20": 0.0, + "e21": 0.0, + "e22": 0.0, + "e23": 0.0, + "e30": 0.0, + "e31": 0.0, + "e32": 0.0, + "e33": 0.0 + }, + "m_DefaultValue": { + "e00": 1.0, + "e01": 0.0, + "e02": 0.0, + "e03": 0.0, + "e10": 0.0, + "e11": 1.0, + "e12": 0.0, + "e13": 0.0, + "e20": 0.0, + "e21": 0.0, + "e22": 1.0, + "e23": 0.0, + "e30": 0.0, + "e31": 0.0, + "e32": 0.0, + "e33": 1.0 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "5431740a337c4f00863d1124e4bcd0be", + "m_Id": 0, + "m_DisplayName": "Smoothness", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.BlockNode", + "m_ObjectId": "547c3a6093244b539b47f013a879b43a", + "m_Group": { + "m_Id": "" + }, + "m_Name": "SurfaceDescription.NormalTS", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": 0.0, + "y": 0.0, + "width": 0.0, + "height": 0.0 + } + }, + "m_Slots": [ + { + "m_Id": "89193339fb5f4aa8ae1e5d4a9385e8ac" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_SerializedDescriptor": "SurfaceDescription.NormalTS" +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.NormalMaterialSlot", + "m_ObjectId": "58f71dd6e7b94c619ccf281e00723d3d", + "m_Id": 0, + "m_DisplayName": "Normal", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "Normal", + "m_StageCapability": 1, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [], + "m_Space": 0 +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "59f499593ce549cdbfb6c359ff36b6cc", + "m_Id": 0, + "m_DisplayName": "Smoothness", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "Smoothness", + "m_StageCapability": 2, + "m_Value": 0.5, + "m_DefaultValue": 0.5, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.ColorRGBMaterialSlot", + "m_ObjectId": "5e169845faf04ef1a19dade797cadeed", + "m_Id": 0, + "m_DisplayName": "Base Color", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "BaseColor", + "m_StageCapability": 2, + "m_Value": { + "x": 0.5, + "y": 0.5, + "z": 0.5 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [], + "m_ColorMode": 0, + "m_DefaultColor": { + "r": 0.5, + "g": 0.5, + "b": 0.5, + "a": 1.0 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector2MaterialSlot", + "m_ObjectId": "649101757f0d46e8b214f02fa64ad916", + "m_Id": 0, + "m_DisplayName": "Tiling", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector2MaterialSlot", + "m_ObjectId": "6d50080048054afba4d078d72081b0a2", + "m_Id": 3, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", + "m_ObjectId": "6ea111b9abf147c6a3795f2eae8d8496", + "m_Id": 1, + "m_DisplayName": "True", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "True", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 1.0, + "z": 1.0, + "w": 1.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + } +} + +{ + "m_SGVersion": 1, + "m_Type": "UnityEditor.Rendering.Universal.ShaderGraph.UniversalTarget", + "m_ObjectId": "70351697015745fca15077ddec8afc89", + "m_ActiveSubTarget": { + "m_Id": "f89b1f7ace834b6ab17c8f38c907dca5" + }, + "m_AllowMaterialOverride": false, + "m_SurfaceType": 0, + "m_ZTestMode": 4, + "m_ZWriteControl": 0, + "m_AlphaMode": 0, + "m_RenderFace": 0, + "m_AlphaClip": true, + "m_CastShadows": true, + "m_ReceiveShadows": true, + "m_CustomEditorGUI": "", + "m_SupportVFX": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.PositionMaterialSlot", + "m_ObjectId": "79a8c2197a1843f58e31684f0ac49dcb", + "m_Id": 0, + "m_DisplayName": "Position", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "Position", + "m_StageCapability": 1, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [], + "m_Space": 0 +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.BlockNode", + "m_ObjectId": "7d896f4d35f540dfb9dacc35ddec6afa", + "m_Group": { + "m_Id": "" + }, + "m_Name": "SurfaceDescription.Metallic", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": 0.0, + "y": 0.0, + "width": 0.0, + "height": 0.0 + } + }, + "m_Slots": [ + { + "m_Id": "e34c98ea8e534dd09964fc90ab08bd91" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_SerializedDescriptor": "SurfaceDescription.Metallic" +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.BlockNode", + "m_ObjectId": "7f1e5a6638cc46108a2ef6f3335f7db6", + "m_Group": { + "m_Id": "" + }, + "m_Name": "SurfaceDescription.Emission", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": 0.0, + "y": 0.0, + "width": 0.0, + "height": 0.0 + } + }, + "m_Slots": [ + { + "m_Id": "30615abfe8e94f039230bb345e2dc291" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_SerializedDescriptor": "SurfaceDescription.Emission" +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "83b8eb9a889d43a684ef184301fd6e9e", + "m_Id": 4, + "m_DisplayName": "R", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "R", + "m_StageCapability": 2, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.PropertyNode", + "m_ObjectId": "85cc4ac9d59d4ff9a65f96c816207a3f", + "m_Group": { + "m_Id": "" + }, + "m_Name": "Property", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -956.7999877929688, + "y": 140.80003356933595, + "width": 105.5999755859375, + "height": 33.59999084472656 + } + }, + "m_Slots": [ + { + "m_Id": "99e14767e4d44dbbb5e5e436f5b1e92f" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_Property": { + "m_Id": "4ff00e04725b4223818808fa53a54254" + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.BranchNode", + "m_ObjectId": "85e4660eb18e4763bd4a2c7fca16df72", + "m_Group": { + "m_Id": "" + }, + "m_Name": "Branch", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -543.2000732421875, + "y": 572.800048828125, + "width": 169.60000610351563, + "height": 141.60003662109376 + } + }, + "m_Slots": [ + { + "m_Id": "c7e2c7aeb45840969d6d7a1b48f1079c" + }, + { + "m_Id": "6ea111b9abf147c6a3795f2eae8d8496" + }, + { + "m_Id": "e23d1fcbba0748deae4abff33d8460b2" + }, + { + "m_Id": "0b1293431328425da5ca8c5b3b333166" + } + ], + "synonyms": [ + "switch", + "if", + "else" + ], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.PropertyNode", + "m_ObjectId": "85fc068f71f9403e9b327a6076c0726d", + "m_Group": { + "m_Id": "" + }, + "m_Name": "Property", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -391.20001220703127, + "y": 360.8000183105469, + "width": 139.99996948242188, + "height": 33.5999755859375 + } + }, + "m_Slots": [ + { + "m_Id": "5431740a337c4f00863d1124e4bcd0be" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_Property": { + "m_Id": "4e56b0554c1541eebaad6914417685a2" + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.Rendering.HighDefinition.ShaderGraph.HDLitData", + "m_ObjectId": "87b9ee4fa41847a0864cbf738d5e88a4", + "m_RayTracing": false, + "m_MaterialType": 0, + "m_RefractionModel": 0, + "m_SSSTransmission": true, + "m_EnergyConservingSpecular": true, + "m_ClearCoat": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.Rendering.HighDefinition.ShaderGraph.HDTarget", + "m_ObjectId": "889230749e8b4e5b8ff8388a75e3e6f4", + "m_ActiveSubTarget": { + "m_Id": "adea60d545ad41fbb866b87a2d93d5b6" + }, + "m_Datas": [ + { + "m_Id": "87b9ee4fa41847a0864cbf738d5e88a4" + }, + { + "m_Id": "036dd76274464631a7d3a06d6e8483e7" + }, + { + "m_Id": "9c745f132bd54832a7b95cb8dbe12071" + }, + { + "m_Id": "37519b892be8480ab341c1c4f7f12ff1" + } + ], + "m_CustomEditorGUI": "", + "m_SupportVFX": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.SamplerStateMaterialSlot", + "m_ObjectId": "88b967de53c84f6499f2cca8003c4851", + "m_Id": 3, + "m_DisplayName": "Sampler", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "Sampler", + "m_StageCapability": 3, + "m_BareResource": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.NormalMaterialSlot", + "m_ObjectId": "89193339fb5f4aa8ae1e5d4a9385e8ac", + "m_Id": 0, + "m_DisplayName": "Normal (Tangent Space)", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "NormalTS", + "m_StageCapability": 2, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [], + "m_Space": 3 +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicValueMaterialSlot", + "m_ObjectId": "8f07f80a79804412a5c2bb689ad58241", + "m_Id": 1, + "m_DisplayName": "B", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "B", + "m_StageCapability": 3, + "m_Value": { + "e00": 2.0, + "e01": 2.0, + "e02": 2.0, + "e03": 2.0, + "e10": 2.0, + "e11": 2.0, + "e12": 2.0, + "e13": 2.0, + "e20": 2.0, + "e21": 2.0, + "e22": 2.0, + "e23": 2.0, + "e30": 2.0, + "e31": 2.0, + "e32": 2.0, + "e33": 2.0 + }, + "m_DefaultValue": { + "e00": 1.0, + "e01": 0.0, + "e02": 0.0, + "e03": 0.0, + "e10": 0.0, + "e11": 1.0, + "e12": 0.0, + "e13": 0.0, + "e20": 0.0, + "e21": 0.0, + "e22": 1.0, + "e23": 0.0, + "e30": 0.0, + "e31": 0.0, + "e32": 0.0, + "e33": 1.0 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "91a7d6a49b9e4cc4bd27f91c53781422", + "m_Id": 0, + "m_DisplayName": "Alpha", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "Alpha", + "m_StageCapability": 2, + "m_Value": 1.0, + "m_DefaultValue": 1.0, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector4MaterialSlot", + "m_ObjectId": "99e14767e4d44dbbb5e5e436f5b1e92f", + "m_Id": 0, + "m_DisplayName": "Color", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.Rendering.HighDefinition.ShaderGraph.LightingData", + "m_ObjectId": "9c745f132bd54832a7b95cb8dbe12071", + "m_NormalDropOffSpace": 0, + "m_BlendPreserveSpecular": true, + "m_ReceiveDecals": true, + "m_ReceiveSSR": true, + "m_ReceiveSSRTransparent": false, + "m_SpecularAA": false, + "m_SpecularOcclusionMode": 1, + "m_OverrideBakedGI": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicValueMaterialSlot", + "m_ObjectId": "9f6f0b738f2946c395d7094746087ee8", + "m_Id": 2, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_Value": { + "e00": 0.0, + "e01": 0.0, + "e02": 0.0, + "e03": 0.0, + "e10": 0.0, + "e11": 0.0, + "e12": 0.0, + "e13": 0.0, + "e20": 0.0, + "e21": 0.0, + "e22": 0.0, + "e23": 0.0, + "e30": 0.0, + "e31": 0.0, + "e32": 0.0, + "e33": 0.0 + }, + "m_DefaultValue": { + "e00": 1.0, + "e01": 0.0, + "e02": 0.0, + "e03": 0.0, + "e10": 0.0, + "e11": 1.0, + "e12": 0.0, + "e13": 0.0, + "e20": 0.0, + "e21": 0.0, + "e22": 1.0, + "e23": 0.0, + "e30": 0.0, + "e31": 0.0, + "e32": 0.0, + "e33": 1.0 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.BlockNode", + "m_ObjectId": "a3f302f80ed844ffbf44b99dd893415e", + "m_Group": { + "m_Id": "" + }, + "m_Name": "VertexDescription.Tangent", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": 0.0, + "y": 0.0, + "width": 0.0, + "height": 0.0 + } + }, + "m_Slots": [ + { + "m_Id": "3f29e230e3d24419aee114c671d1e1a2" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_SerializedDescriptor": "VertexDescription.Tangent" +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "a49108ec71074f20a0cf02b277733b3d", + "m_Id": 6, + "m_DisplayName": "B", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "B", + "m_StageCapability": 2, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "ab9406cddef148cba7c487de1453ce4d", + "m_Id": 0, + "m_DisplayName": "Alpha Clip Threshold", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "AlphaClipThreshold", + "m_StageCapability": 2, + "m_Value": 0.5, + "m_DefaultValue": 0.5, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.FlipNode", + "m_ObjectId": "ad74695cfc12453188fbb4d17b6c96c2", + "m_Group": { + "m_Id": "" + }, + "m_Name": "Flip", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -581.6859130859375, + "y": -123.50872039794922, + "width": 0.0, + "height": 0.0 + } + }, + "m_Slots": [ + { + "m_Id": "0a2d6e54a269462995058e94217b6f82" + }, + { + "m_Id": "fc09e91bae1849668bd70c5e6114e1d4" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_RedChannel": true, + "m_GreenChannel": true, + "m_BlueChannel": true, + "m_AlphaChannel": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.Rendering.HighDefinition.ShaderGraph.HDLitSubTarget", + "m_ObjectId": "adea60d545ad41fbb866b87a2d93d5b6" +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Texture2DInputMaterialSlot", + "m_ObjectId": "ae49a700327146e198ebe3d7cff9f16e", + "m_Id": 1, + "m_DisplayName": "Texture", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "Texture", + "m_StageCapability": 3, + "m_BareResource": false, + "m_Texture": { + "m_SerializedTexture": "{\"texture\":{\"instanceID\":0}}", + "m_Guid": "" + }, + "m_DefaultType": 0 +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.Rendering.Universal.ShaderGraph.UniversalLitSubTarget", + "m_ObjectId": "af49c364ed4a41e0ba8119d8d4b81eb7", + "m_WorkflowMode": 1, + "m_NormalDropOffSpace": 0, + "m_ClearCoat": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector4MaterialSlot", + "m_ObjectId": "b013472d231248eb9e4a9ee2821e973a", + "m_Id": 0, + "m_DisplayName": "RGBA", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "RGBA", + "m_StageCapability": 2, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.BlockNode", + "m_ObjectId": "b3a7b8c6105d4a9d99f2c0e475229395", + "m_Group": { + "m_Id": "" + }, + "m_Name": "SurfaceDescription.Smoothness", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": 0.0, + "y": 0.0, + "width": 0.0, + "height": 0.0 + } + }, + "m_Slots": [ + { + "m_Id": "59f499593ce549cdbfb6c359ff36b6cc" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_SerializedDescriptor": "SurfaceDescription.Smoothness" +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.TilingAndOffsetNode", + "m_ObjectId": "b75bfd40495a47c687573a825b006ec3", + "m_Group": { + "m_Id": "" + }, + "m_Name": "Tiling And Offset", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -1207.2000732421875, + "y": 247.20001220703126, + "width": 208.0, + "height": 325.60003662109377 + } + }, + "m_Slots": [ + { + "m_Id": "502dd87805614bd6bb2cd5674cb78d13" + }, + { + "m_Id": "bc751ddf1dc145dbbd262d1daa1dac42" + }, + { + "m_Id": "1cb440ca7c114bc7bbf5c85750d2a3b1" + }, + { + "m_Id": "6d50080048054afba4d078d72081b0a2" + } + ], + "synonyms": [ + "pan", + "scale" + ], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.IsFrontFaceNode", + "m_ObjectId": "b91e9b998964417096174d43beedd509", + "m_Group": { + "m_Id": "" + }, + "m_Name": "Is Front Face", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -784.8001098632813, + "y": 572.800048828125, + "width": 121.60003662109375, + "height": 76.800048828125 + } + }, + "m_Slots": [ + { + "m_Id": "0067ec270e2b4a6c8186ff77a4d24e90" + } + ], + "synonyms": [ + "face", + "side" + ], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.PropertyNode", + "m_ObjectId": "baceccda18a146aabc489ed8fe66e00e", + "m_Group": { + "m_Id": "" + }, + "m_Name": "Property", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -1479.2000732421875, + "y": 317.6000061035156, + "width": 104.800048828125, + "height": 33.600006103515628 + } + }, + "m_Slots": [ + { + "m_Id": "649101757f0d46e8b214f02fa64ad916" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_Property": { + "m_Id": "f82b9f46e40e431fae1d5ec7c3707e42" + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector2MaterialSlot", + "m_ObjectId": "bc751ddf1dc145dbbd262d1daa1dac42", + "m_Id": 1, + "m_DisplayName": "Tiling", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "Tiling", + "m_StageCapability": 3, + "m_Value": { + "x": 1.0, + "y": 1.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.Rendering.BuiltIn.ShaderGraph.BuiltInLitSubTarget", + "m_ObjectId": "be4795b19cdd4426bcdabf79f1c24b0a", + "m_WorkflowMode": 1, + "m_NormalDropOffSpace": 0 +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.BlockNode", + "m_ObjectId": "c3fae475af5f494782e2283aab0b42e4", + "m_Group": { + "m_Id": "" + }, + "m_Name": "SurfaceDescription.BentNormal", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": 0.0, + "y": 0.0, + "width": 0.0, + "height": 0.0 + } + }, + "m_Slots": [ + { + "m_Id": "f522747d6ff14b7d88ec8c4f780408c9" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_SerializedDescriptor": "SurfaceDescription.BentNormal" +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.BooleanMaterialSlot", + "m_ObjectId": "c7e2c7aeb45840969d6d7a1b48f1079c", + "m_Id": 0, + "m_DisplayName": "Predicate", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "Predicate", + "m_StageCapability": 3, + "m_Value": false, + "m_DefaultValue": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.UVMaterialSlot", + "m_ObjectId": "c84e98391374467b949f3a300d8addbc", + "m_Id": 2, + "m_DisplayName": "UV", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "UV", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0 + }, + "m_Labels": [], + "m_Channel": 0 +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "d62d1c4bb772482a93392ab836e9a3d9", + "m_Id": 0, + "m_DisplayName": "Ambient Occlusion", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "Occlusion", + "m_StageCapability": 2, + "m_Value": 1.0, + "m_DefaultValue": 1.0, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.BlockNode", + "m_ObjectId": "d8cd689a35ac40ccb7fc9fa38bfedb1b", + "m_Group": { + "m_Id": "" + }, + "m_Name": "VertexDescription.Normal", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": 0.0, + "y": 0.0, + "width": 0.0, + "height": 0.0 + } + }, + "m_Slots": [ + { + "m_Id": "58f71dd6e7b94c619ccf281e00723d3d" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_SerializedDescriptor": "VertexDescription.Normal" +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.BlockNode", + "m_ObjectId": "dad6f28cdb54429b9ec2c4474304b92c", + "m_Group": { + "m_Id": "" + }, + "m_Name": "SurfaceDescription.Alpha", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": 0.0, + "y": 0.0, + "width": 0.0, + "height": 0.0 + } + }, + "m_Slots": [ + { + "m_Id": "91a7d6a49b9e4cc4bd27f91c53781422" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_SerializedDescriptor": "SurfaceDescription.Alpha" +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.BlockNode", + "m_ObjectId": "dcc961838b80405199d4e7d4c1f4fd7d", + "m_Group": { + "m_Id": "" + }, + "m_Name": "SurfaceDescription.BaseColor", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": 0.0, + "y": 0.0, + "width": 0.0, + "height": 0.0 + } + }, + "m_Slots": [ + { + "m_Id": "5e169845faf04ef1a19dade797cadeed" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_SerializedDescriptor": "SurfaceDescription.BaseColor" +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Internal.Texture2DShaderProperty", + "m_ObjectId": "ddfd2e0ff3934cee81c59223a6aff2c9", + "m_Guid": { + "m_GuidSerialized": "102ebb54-4113-4289-b8e8-e63ef7917ce0" + }, + "m_Name": "Main", + "m_DefaultRefNameVersion": 1, + "m_RefNameGeneratedByDisplayName": "Main", + "m_DefaultReferenceName": "_Main", + "m_OverrideReferenceName": "", + "m_GeneratePropertyBlock": true, + "m_UseCustomSlotLabel": false, + "m_CustomSlotLabel": "", + "m_Precision": 0, + "overrideHLSLDeclaration": false, + "hlslDeclarationOverride": 0, + "m_Hidden": false, + "m_Value": { + "m_SerializedTexture": "{\"texture\":{\"instanceID\":0}}", + "m_Guid": "" + }, + "isMainTexture": false, + "useTilingAndOffset": false, + "m_Modifiable": true, + "m_DefaultType": 0 +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", + "m_ObjectId": "e23d1fcbba0748deae4abff33d8460b2", + "m_Id": 2, + "m_DisplayName": "False", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "False", + "m_StageCapability": 3, + "m_Value": { + "x": 1.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "e34c98ea8e534dd09964fc90ab08bd91", + "m_Id": 0, + "m_DisplayName": "Metallic", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "Metallic", + "m_StageCapability": 2, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.NormalMaterialSlot", + "m_ObjectId": "f522747d6ff14b7d88ec8c4f780408c9", + "m_Id": 0, + "m_DisplayName": "Bent Normal", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "BentNormal", + "m_StageCapability": 2, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [], + "m_Space": 3 +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.PropertyNode", + "m_ObjectId": "f538dbc91a2f4d8d8f4b21556d67960b", + "m_Group": { + "m_Id": "" + }, + "m_Name": "Property", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -970.3999633789063, + "y": 225.60003662109376, + "width": 109.5999755859375, + "height": 33.600006103515628 + } + }, + "m_Slots": [ + { + "m_Id": "0e30156cfe4e4283a0dde082768d533e" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_Property": { + "m_Id": "ddfd2e0ff3934cee81c59223a6aff2c9" + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.MultiplyNode", + "m_ObjectId": "f5609f11baf94d889ab3f8bf42aa2131", + "m_Group": { + "m_Id": "" + }, + "m_Name": "Multiply", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -543.2000122070313, + "y": 200.0, + "width": 130.40005493164063, + "height": 117.60000610351563 + } + }, + "m_Slots": [ + { + "m_Id": "537ac3a52c2746868e48f15018591a5c" + }, + { + "m_Id": "8f07f80a79804412a5c2bb689ad58241" + }, + { + "m_Id": "9f6f0b738f2946c395d7094746087ee8" + } + ], + "synonyms": [ + "multiplication", + "times", + "x" + ], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + } +} + +{ + "m_SGVersion": 1, + "m_Type": "UnityEditor.ShaderGraph.Internal.Vector2ShaderProperty", + "m_ObjectId": "f82b9f46e40e431fae1d5ec7c3707e42", + "m_Guid": { + "m_GuidSerialized": "263a3129-1f2d-4f0f-bdf1-7ec3b3b8f8d7" + }, + "m_Name": "Tiling", + "m_DefaultRefNameVersion": 1, + "m_RefNameGeneratedByDisplayName": "Tiling", + "m_DefaultReferenceName": "_Tiling", + "m_OverrideReferenceName": "", + "m_GeneratePropertyBlock": true, + "m_UseCustomSlotLabel": false, + "m_CustomSlotLabel": "", + "m_Precision": 0, + "overrideHLSLDeclaration": false, + "hlslDeclarationOverride": 0, + "m_Hidden": false, + "m_Value": { + "x": 1.0, + "y": 1.0, + "z": 0.0, + "w": 0.0 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.Rendering.Universal.ShaderGraph.UniversalLitSubTarget", + "m_ObjectId": "f89b1f7ace834b6ab17c8f38c907dca5", + "m_WorkflowMode": 1, + "m_NormalDropOffSpace": 0, + "m_ClearCoat": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.SampleTexture2DNode", + "m_ObjectId": "f8ebcdc66077436288a397d204bbd8cd", + "m_Group": { + "m_Id": "" + }, + "m_Name": "Sample Texture 2D", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -823.2000122070313, + "y": 226.4000244140625, + "width": 183.20001220703126, + "height": 247.99996948242188 + } + }, + "m_Slots": [ + { + "m_Id": "b013472d231248eb9e4a9ee2821e973a" + }, + { + "m_Id": "83b8eb9a889d43a684ef184301fd6e9e" + }, + { + "m_Id": "27a353a5cc96432fa692fdda747d8c67" + }, + { + "m_Id": "a49108ec71074f20a0cf02b277733b3d" + }, + { + "m_Id": "1c6b14984c74490d9e22845b989d3c38" + }, + { + "m_Id": "ae49a700327146e198ebe3d7cff9f16e" + }, + { + "m_Id": "c84e98391374467b949f3a300d8addbc" + }, + { + "m_Id": "88b967de53c84f6499f2cca8003c4851" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_TextureType": 0, + "m_NormalMapSpace": 0, + "m_EnableGlobalMipBias": true +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", + "m_ObjectId": "fc09e91bae1849668bd70c5e6114e1d4", + "m_Id": 1, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + } +} + diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/Common/Shaders/MC2_Common_Lit_Back.shadergraph.meta b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Shaders/MC2_Common_Lit_Back.shadergraph.meta new file mode 100644 index 00000000..fb8787b3 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Shaders/MC2_Common_Lit_Back.shadergraph.meta @@ -0,0 +1,17 @@ +fileFormatVersion: 2 +guid: b969454d26657854a8fe82c813fb0876 +ScriptedImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 2 + userData: + assetBundleName: + assetBundleVariant: + script: {fileID: 11500000, guid: 625f186215c104763be7675aa2d941aa, type: 3} +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/Common/Shaders/MC2_Common_Lit_Back.shadergraph + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/Common/Shaders/MC2_Common_Lit_Front.shadergraph b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Shaders/MC2_Common_Lit_Front.shadergraph new file mode 100644 index 00000000..80c75659 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Shaders/MC2_Common_Lit_Front.shadergraph @@ -0,0 +1,1889 @@ +{ + "m_SGVersion": 3, + "m_Type": "UnityEditor.ShaderGraph.GraphData", + "m_ObjectId": "f41d4d9b57ae4b59b26678b1f6073750", + "m_Properties": [ + { + "m_Id": "4ff00e04725b4223818808fa53a54254" + }, + { + "m_Id": "ddfd2e0ff3934cee81c59223a6aff2c9" + }, + { + "m_Id": "4e56b0554c1541eebaad6914417685a2" + }, + { + "m_Id": "a26b59565ef346af91775e92f420b09c" + } + ], + "m_Keywords": [], + "m_Dropdowns": [], + "m_CategoryData": [ + { + "m_Id": "4b4d7767a3c04b13992378fe6f0758c1" + } + ], + "m_Nodes": [ + { + "m_Id": "10be29e472174f9bac547bf66ae09a6e" + }, + { + "m_Id": "d8cd689a35ac40ccb7fc9fa38bfedb1b" + }, + { + "m_Id": "a3f302f80ed844ffbf44b99dd893415e" + }, + { + "m_Id": "dcc961838b80405199d4e7d4c1f4fd7d" + }, + { + "m_Id": "547c3a6093244b539b47f013a879b43a" + }, + { + "m_Id": "7d896f4d35f540dfb9dacc35ddec6afa" + }, + { + "m_Id": "b3a7b8c6105d4a9d99f2c0e475229395" + }, + { + "m_Id": "7f1e5a6638cc46108a2ef6f3335f7db6" + }, + { + "m_Id": "3e52a198523e4e8089a6a40a3969a3b7" + }, + { + "m_Id": "85cc4ac9d59d4ff9a65f96c816207a3f" + }, + { + "m_Id": "f538dbc91a2f4d8d8f4b21556d67960b" + }, + { + "m_Id": "f8ebcdc66077436288a397d204bbd8cd" + }, + { + "m_Id": "f5609f11baf94d889ab3f8bf42aa2131" + }, + { + "m_Id": "85fc068f71f9403e9b327a6076c0726d" + }, + { + "m_Id": "5c8b10ffa49c42de8989474a7c932e46" + }, + { + "m_Id": "a1bab1c7bfa0439ca12ea9ded5e1e9ff" + }, + { + "m_Id": "bb1de797d6b24fdd8548d1fa61c25fea" + }, + { + "m_Id": "25560879eb42491d9ea4f694cac78636" + } + ], + "m_GroupDatas": [], + "m_StickyNoteDatas": [], + "m_Edges": [ + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "5c8b10ffa49c42de8989474a7c932e46" + }, + "m_SlotId": 3 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "f8ebcdc66077436288a397d204bbd8cd" + }, + "m_SlotId": 2 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "85cc4ac9d59d4ff9a65f96c816207a3f" + }, + "m_SlotId": 0 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "f5609f11baf94d889ab3f8bf42aa2131" + }, + "m_SlotId": 0 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "85fc068f71f9403e9b327a6076c0726d" + }, + "m_SlotId": 0 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "b3a7b8c6105d4a9d99f2c0e475229395" + }, + "m_SlotId": 0 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "a1bab1c7bfa0439ca12ea9ded5e1e9ff" + }, + "m_SlotId": 0 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "5c8b10ffa49c42de8989474a7c932e46" + }, + "m_SlotId": 1 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "f538dbc91a2f4d8d8f4b21556d67960b" + }, + "m_SlotId": 0 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "f8ebcdc66077436288a397d204bbd8cd" + }, + "m_SlotId": 1 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "f5609f11baf94d889ab3f8bf42aa2131" + }, + "m_SlotId": 2 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "dcc961838b80405199d4e7d4c1f4fd7d" + }, + "m_SlotId": 0 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "f8ebcdc66077436288a397d204bbd8cd" + }, + "m_SlotId": 0 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "f5609f11baf94d889ab3f8bf42aa2131" + }, + "m_SlotId": 1 + } + } + ], + "m_VertexContext": { + "m_Position": { + "x": 0.0, + "y": 0.0 + }, + "m_Blocks": [ + { + "m_Id": "10be29e472174f9bac547bf66ae09a6e" + }, + { + "m_Id": "d8cd689a35ac40ccb7fc9fa38bfedb1b" + }, + { + "m_Id": "a3f302f80ed844ffbf44b99dd893415e" + } + ] + }, + "m_FragmentContext": { + "m_Position": { + "x": 0.0, + "y": 200.0 + }, + "m_Blocks": [ + { + "m_Id": "dcc961838b80405199d4e7d4c1f4fd7d" + }, + { + "m_Id": "547c3a6093244b539b47f013a879b43a" + }, + { + "m_Id": "7d896f4d35f540dfb9dacc35ddec6afa" + }, + { + "m_Id": "b3a7b8c6105d4a9d99f2c0e475229395" + }, + { + "m_Id": "7f1e5a6638cc46108a2ef6f3335f7db6" + }, + { + "m_Id": "3e52a198523e4e8089a6a40a3969a3b7" + }, + { + "m_Id": "bb1de797d6b24fdd8548d1fa61c25fea" + }, + { + "m_Id": "25560879eb42491d9ea4f694cac78636" + } + ] + }, + "m_PreviewData": { + "serializedMesh": { + "m_SerializedMesh": "{\"mesh\":{\"instanceID\":0}}", + "m_Guid": "" + }, + "preventRotation": false + }, + "m_Path": "Shader Graphs", + "m_GraphPrecision": 1, + "m_PreviewMode": 2, + "m_OutputNode": { + "m_Id": "" + }, + "m_ActiveTargets": [ + { + "m_Id": "1cefe9920a694056a32d6044c91eb117" + }, + { + "m_Id": "2bf6d014c6c1480c9cdd391006bd273a" + }, + { + "m_Id": "dd93478797c54e378dce24d430828d35" + } + ] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Texture2DMaterialSlot", + "m_ObjectId": "0e30156cfe4e4283a0dde082768d533e", + "m_Id": 0, + "m_DisplayName": "Main", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_BareResource": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.BlockNode", + "m_ObjectId": "10be29e472174f9bac547bf66ae09a6e", + "m_Group": { + "m_Id": "" + }, + "m_Name": "VertexDescription.Position", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": 0.0, + "y": 0.0, + "width": 0.0, + "height": 0.0 + } + }, + "m_Slots": [ + { + "m_Id": "79a8c2197a1843f58e31684f0ac49dcb" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_SerializedDescriptor": "VertexDescription.Position" +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "1c6b14984c74490d9e22845b989d3c38", + "m_Id": 7, + "m_DisplayName": "A", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "A", + "m_StageCapability": 2, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [] +} + +{ + "m_SGVersion": 2, + "m_Type": "UnityEditor.Rendering.BuiltIn.ShaderGraph.BuiltInTarget", + "m_ObjectId": "1cefe9920a694056a32d6044c91eb117", + "m_ActiveSubTarget": { + "m_Id": "be4795b19cdd4426bcdabf79f1c24b0a" + }, + "m_AllowMaterialOverride": false, + "m_SurfaceType": 0, + "m_ZWriteControl": 0, + "m_ZTestMode": 4, + "m_AlphaMode": 0, + "m_RenderFace": 2, + "m_AlphaClip": false, + "m_CustomEditorGUI": "" +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.BlockNode", + "m_ObjectId": "25560879eb42491d9ea4f694cac78636", + "m_Group": { + "m_Id": "" + }, + "m_Name": "SurfaceDescription.BentNormal", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": 0.0, + "y": 0.0, + "width": 0.0, + "height": 0.0 + } + }, + "m_Slots": [ + { + "m_Id": "f52a98485db2455db11f6cdede9bae95" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_SerializedDescriptor": "SurfaceDescription.BentNormal" +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "27a353a5cc96432fa692fdda747d8c67", + "m_Id": 5, + "m_DisplayName": "G", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "G", + "m_StageCapability": 2, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.Rendering.HighDefinition.ShaderGraph.HDTarget", + "m_ObjectId": "2bf6d014c6c1480c9cdd391006bd273a", + "m_ActiveSubTarget": { + "m_Id": "a2b1c60a1f4e4d958112b90537480711" + }, + "m_Datas": [ + { + "m_Id": "34dbdb9f2f834fa99a6c1210b056dac1" + }, + { + "m_Id": "d8fb147345fe44deb67b06184c7aaf52" + }, + { + "m_Id": "e2857615bb264191854f0ddf6a91ee00" + }, + { + "m_Id": "521ef9d583b34a8fa6c639d38a592d88" + } + ], + "m_CustomEditorGUI": "", + "m_SupportVFX": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.ColorRGBMaterialSlot", + "m_ObjectId": "30615abfe8e94f039230bb345e2dc291", + "m_Id": 0, + "m_DisplayName": "Emission", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "Emission", + "m_StageCapability": 2, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [], + "m_ColorMode": 1, + "m_DefaultColor": { + "r": 0.0, + "g": 0.0, + "b": 0.0, + "a": 1.0 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.Rendering.HighDefinition.ShaderGraph.HDLitData", + "m_ObjectId": "34dbdb9f2f834fa99a6c1210b056dac1", + "m_RayTracing": false, + "m_MaterialType": 0, + "m_RefractionModel": 0, + "m_SSSTransmission": true, + "m_EnergyConservingSpecular": true, + "m_ClearCoat": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.BlockNode", + "m_ObjectId": "3e52a198523e4e8089a6a40a3969a3b7", + "m_Group": { + "m_Id": "" + }, + "m_Name": "SurfaceDescription.Occlusion", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": 0.0, + "y": 0.0, + "width": 0.0, + "height": 0.0 + } + }, + "m_Slots": [ + { + "m_Id": "d62d1c4bb772482a93392ab836e9a3d9" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_SerializedDescriptor": "SurfaceDescription.Occlusion" +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.TangentMaterialSlot", + "m_ObjectId": "3f29e230e3d24419aee114c671d1e1a2", + "m_Id": 0, + "m_DisplayName": "Tangent", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "Tangent", + "m_StageCapability": 1, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [], + "m_Space": 0 +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "48bfc27e7f46426d98a47ecf41075042", + "m_Id": 0, + "m_DisplayName": "Alpha", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "Alpha", + "m_StageCapability": 2, + "m_Value": 1.0, + "m_DefaultValue": 1.0, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.CategoryData", + "m_ObjectId": "4b4d7767a3c04b13992378fe6f0758c1", + "m_Name": "", + "m_ChildObjectList": [ + { + "m_Id": "4ff00e04725b4223818808fa53a54254" + }, + { + "m_Id": "ddfd2e0ff3934cee81c59223a6aff2c9" + }, + { + "m_Id": "4e56b0554c1541eebaad6914417685a2" + }, + { + "m_Id": "a26b59565ef346af91775e92f420b09c" + } + ] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector2MaterialSlot", + "m_ObjectId": "4ba45cb2affc4a64a6fcfc68e4e4469b", + "m_Id": 3, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 1, + "m_Type": "UnityEditor.ShaderGraph.Internal.Vector1ShaderProperty", + "m_ObjectId": "4e56b0554c1541eebaad6914417685a2", + "m_Guid": { + "m_GuidSerialized": "291c9d7d-b925-4410-9719-cbd950781678" + }, + "m_Name": "Smoothness", + "m_DefaultRefNameVersion": 1, + "m_RefNameGeneratedByDisplayName": "Smoothness", + "m_DefaultReferenceName": "_Smoothness", + "m_OverrideReferenceName": "", + "m_GeneratePropertyBlock": true, + "m_UseCustomSlotLabel": false, + "m_CustomSlotLabel": "", + "m_Precision": 0, + "overrideHLSLDeclaration": false, + "hlslDeclarationOverride": 0, + "m_Hidden": false, + "m_Value": 0.0, + "m_FloatType": 1, + "m_RangeValues": { + "x": 0.0, + "y": 1.0 + } +} + +{ + "m_SGVersion": 3, + "m_Type": "UnityEditor.ShaderGraph.Internal.ColorShaderProperty", + "m_ObjectId": "4ff00e04725b4223818808fa53a54254", + "m_Guid": { + "m_GuidSerialized": "2b85b46b-4c2e-4207-b64c-9ea0d9e7fe37" + }, + "m_Name": "Color", + "m_DefaultRefNameVersion": 1, + "m_RefNameGeneratedByDisplayName": "Color", + "m_DefaultReferenceName": "_Color", + "m_OverrideReferenceName": "", + "m_GeneratePropertyBlock": true, + "m_UseCustomSlotLabel": false, + "m_CustomSlotLabel": "", + "m_Precision": 0, + "overrideHLSLDeclaration": false, + "hlslDeclarationOverride": 0, + "m_Hidden": false, + "m_Value": { + "r": 1.0, + "g": 1.0, + "b": 1.0, + "a": 1.0 + }, + "isMainColor": false, + "m_ColorMode": 0 +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.Rendering.HighDefinition.ShaderGraph.SystemData", + "m_ObjectId": "521ef9d583b34a8fa6c639d38a592d88", + "m_MaterialNeedsUpdateHash": 529, + "m_SurfaceType": 0, + "m_RenderingPass": 1, + "m_BlendMode": 0, + "m_ZTest": 4, + "m_ZWrite": false, + "m_TransparentCullMode": 2, + "m_OpaqueCullMode": 2, + "m_SortPriority": 0, + "m_AlphaTest": false, + "m_TransparentDepthPrepass": false, + "m_TransparentDepthPostpass": false, + "m_SupportLodCrossFade": false, + "m_DoubleSidedMode": 0, + "m_DOTSInstancing": false, + "m_CustomVelocity": false, + "m_Tessellation": false, + "m_TessellationMode": 0, + "m_TessellationFactorMinDistance": 20.0, + "m_TessellationFactorMaxDistance": 50.0, + "m_TessellationFactorTriangleSize": 100.0, + "m_TessellationShapeFactor": 0.75, + "m_TessellationBackFaceCullEpsilon": -0.25, + "m_TessellationMaxDisplacement": 0.009999999776482582, + "m_Version": 1, + "inspectorFoldoutMask": 1 +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicValueMaterialSlot", + "m_ObjectId": "537ac3a52c2746868e48f15018591a5c", + "m_Id": 0, + "m_DisplayName": "A", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "A", + "m_StageCapability": 3, + "m_Value": { + "e00": 0.0, + "e01": 0.0, + "e02": 0.0, + "e03": 0.0, + "e10": 0.0, + "e11": 0.0, + "e12": 0.0, + "e13": 0.0, + "e20": 0.0, + "e21": 0.0, + "e22": 0.0, + "e23": 0.0, + "e30": 0.0, + "e31": 0.0, + "e32": 0.0, + "e33": 0.0 + }, + "m_DefaultValue": { + "e00": 1.0, + "e01": 0.0, + "e02": 0.0, + "e03": 0.0, + "e10": 0.0, + "e11": 1.0, + "e12": 0.0, + "e13": 0.0, + "e20": 0.0, + "e21": 0.0, + "e22": 1.0, + "e23": 0.0, + "e30": 0.0, + "e31": 0.0, + "e32": 0.0, + "e33": 1.0 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "5431740a337c4f00863d1124e4bcd0be", + "m_Id": 0, + "m_DisplayName": "Smoothness", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.BlockNode", + "m_ObjectId": "547c3a6093244b539b47f013a879b43a", + "m_Group": { + "m_Id": "" + }, + "m_Name": "SurfaceDescription.NormalTS", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": 0.0, + "y": 0.0, + "width": 0.0, + "height": 0.0 + } + }, + "m_Slots": [ + { + "m_Id": "89193339fb5f4aa8ae1e5d4a9385e8ac" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_SerializedDescriptor": "SurfaceDescription.NormalTS" +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.NormalMaterialSlot", + "m_ObjectId": "58f71dd6e7b94c619ccf281e00723d3d", + "m_Id": 0, + "m_DisplayName": "Normal", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "Normal", + "m_StageCapability": 1, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [], + "m_Space": 0 +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "59f499593ce549cdbfb6c359ff36b6cc", + "m_Id": 0, + "m_DisplayName": "Smoothness", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "Smoothness", + "m_StageCapability": 2, + "m_Value": 0.5, + "m_DefaultValue": 0.5, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.TilingAndOffsetNode", + "m_ObjectId": "5c8b10ffa49c42de8989474a7c932e46", + "m_Group": { + "m_Id": "" + }, + "m_Name": "Tiling And Offset", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -1164.800048828125, + "y": 259.20001220703127, + "width": 207.99993896484376, + "height": 325.5999755859375 + } + }, + "m_Slots": [ + { + "m_Id": "5df0959b90a842269f9e687ac72571c1" + }, + { + "m_Id": "e85243155cd34b7d945bc4b2d2cab6b3" + }, + { + "m_Id": "fe52d187880e4a4781987f545692006d" + }, + { + "m_Id": "4ba45cb2affc4a64a6fcfc68e4e4469b" + } + ], + "synonyms": [ + "pan", + "scale" + ], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.UVMaterialSlot", + "m_ObjectId": "5df0959b90a842269f9e687ac72571c1", + "m_Id": 0, + "m_DisplayName": "UV", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "UV", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0 + }, + "m_Labels": [], + "m_Channel": 0 +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.ColorRGBMaterialSlot", + "m_ObjectId": "5e169845faf04ef1a19dade797cadeed", + "m_Id": 0, + "m_DisplayName": "Base Color", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "BaseColor", + "m_StageCapability": 2, + "m_Value": { + "x": 0.5, + "y": 0.5, + "z": 0.5 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [], + "m_ColorMode": 0, + "m_DefaultColor": { + "r": 0.5, + "g": 0.5, + "b": 0.5, + "a": 1.0 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.PositionMaterialSlot", + "m_ObjectId": "79a8c2197a1843f58e31684f0ac49dcb", + "m_Id": 0, + "m_DisplayName": "Position", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "Position", + "m_StageCapability": 1, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [], + "m_Space": 0 +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.BlockNode", + "m_ObjectId": "7d896f4d35f540dfb9dacc35ddec6afa", + "m_Group": { + "m_Id": "" + }, + "m_Name": "SurfaceDescription.Metallic", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": 0.0, + "y": 0.0, + "width": 0.0, + "height": 0.0 + } + }, + "m_Slots": [ + { + "m_Id": "e34c98ea8e534dd09964fc90ab08bd91" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_SerializedDescriptor": "SurfaceDescription.Metallic" +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.BlockNode", + "m_ObjectId": "7f1e5a6638cc46108a2ef6f3335f7db6", + "m_Group": { + "m_Id": "" + }, + "m_Name": "SurfaceDescription.Emission", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": 0.0, + "y": 0.0, + "width": 0.0, + "height": 0.0 + } + }, + "m_Slots": [ + { + "m_Id": "30615abfe8e94f039230bb345e2dc291" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_SerializedDescriptor": "SurfaceDescription.Emission" +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "83b8eb9a889d43a684ef184301fd6e9e", + "m_Id": 4, + "m_DisplayName": "R", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "R", + "m_StageCapability": 2, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.PropertyNode", + "m_ObjectId": "85cc4ac9d59d4ff9a65f96c816207a3f", + "m_Group": { + "m_Id": "" + }, + "m_Name": "Property", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -956.7999877929688, + "y": 140.80003356933595, + "width": 105.5999755859375, + "height": 33.59999084472656 + } + }, + "m_Slots": [ + { + "m_Id": "99e14767e4d44dbbb5e5e436f5b1e92f" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_Property": { + "m_Id": "4ff00e04725b4223818808fa53a54254" + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.PropertyNode", + "m_ObjectId": "85fc068f71f9403e9b327a6076c0726d", + "m_Group": { + "m_Id": "" + }, + "m_Name": "Property", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -391.20001220703127, + "y": 360.8000183105469, + "width": 139.99996948242188, + "height": 33.5999755859375 + } + }, + "m_Slots": [ + { + "m_Id": "5431740a337c4f00863d1124e4bcd0be" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_Property": { + "m_Id": "4e56b0554c1541eebaad6914417685a2" + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.SamplerStateMaterialSlot", + "m_ObjectId": "88b967de53c84f6499f2cca8003c4851", + "m_Id": 3, + "m_DisplayName": "Sampler", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "Sampler", + "m_StageCapability": 3, + "m_BareResource": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.NormalMaterialSlot", + "m_ObjectId": "89193339fb5f4aa8ae1e5d4a9385e8ac", + "m_Id": 0, + "m_DisplayName": "Normal (Tangent Space)", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "NormalTS", + "m_StageCapability": 2, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [], + "m_Space": 3 +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicValueMaterialSlot", + "m_ObjectId": "8f07f80a79804412a5c2bb689ad58241", + "m_Id": 1, + "m_DisplayName": "B", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "B", + "m_StageCapability": 3, + "m_Value": { + "e00": 2.0, + "e01": 2.0, + "e02": 2.0, + "e03": 2.0, + "e10": 2.0, + "e11": 2.0, + "e12": 2.0, + "e13": 2.0, + "e20": 2.0, + "e21": 2.0, + "e22": 2.0, + "e23": 2.0, + "e30": 2.0, + "e31": 2.0, + "e32": 2.0, + "e33": 2.0 + }, + "m_DefaultValue": { + "e00": 1.0, + "e01": 0.0, + "e02": 0.0, + "e03": 0.0, + "e10": 0.0, + "e11": 1.0, + "e12": 0.0, + "e13": 0.0, + "e20": 0.0, + "e21": 0.0, + "e22": 1.0, + "e23": 0.0, + "e30": 0.0, + "e31": 0.0, + "e32": 0.0, + "e33": 1.0 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector4MaterialSlot", + "m_ObjectId": "99e14767e4d44dbbb5e5e436f5b1e92f", + "m_Id": 0, + "m_DisplayName": "Color", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicValueMaterialSlot", + "m_ObjectId": "9f6f0b738f2946c395d7094746087ee8", + "m_Id": 2, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_Value": { + "e00": 0.0, + "e01": 0.0, + "e02": 0.0, + "e03": 0.0, + "e10": 0.0, + "e11": 0.0, + "e12": 0.0, + "e13": 0.0, + "e20": 0.0, + "e21": 0.0, + "e22": 0.0, + "e23": 0.0, + "e30": 0.0, + "e31": 0.0, + "e32": 0.0, + "e33": 0.0 + }, + "m_DefaultValue": { + "e00": 1.0, + "e01": 0.0, + "e02": 0.0, + "e03": 0.0, + "e10": 0.0, + "e11": 1.0, + "e12": 0.0, + "e13": 0.0, + "e20": 0.0, + "e21": 0.0, + "e22": 1.0, + "e23": 0.0, + "e30": 0.0, + "e31": 0.0, + "e32": 0.0, + "e33": 1.0 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector2MaterialSlot", + "m_ObjectId": "a0603a6937e446e8a883475a9b0f69b2", + "m_Id": 0, + "m_DisplayName": "Tiling", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.PropertyNode", + "m_ObjectId": "a1bab1c7bfa0439ca12ea9ded5e1e9ff", + "m_Group": { + "m_Id": "" + }, + "m_Name": "Property", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -1449.60009765625, + "y": 327.20001220703127, + "width": 104.800048828125, + "height": 33.5999755859375 + } + }, + "m_Slots": [ + { + "m_Id": "a0603a6937e446e8a883475a9b0f69b2" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_Property": { + "m_Id": "a26b59565ef346af91775e92f420b09c" + } +} + +{ + "m_SGVersion": 1, + "m_Type": "UnityEditor.ShaderGraph.Internal.Vector2ShaderProperty", + "m_ObjectId": "a26b59565ef346af91775e92f420b09c", + "m_Guid": { + "m_GuidSerialized": "557f4917-de3d-4160-8fdd-6b016172ce32" + }, + "m_Name": "Tiling", + "m_DefaultRefNameVersion": 1, + "m_RefNameGeneratedByDisplayName": "Tiling", + "m_DefaultReferenceName": "_Tiling", + "m_OverrideReferenceName": "", + "m_GeneratePropertyBlock": true, + "m_UseCustomSlotLabel": false, + "m_CustomSlotLabel": "", + "m_Precision": 0, + "overrideHLSLDeclaration": false, + "hlslDeclarationOverride": 0, + "m_Hidden": false, + "m_Value": { + "x": 1.0, + "y": 1.0, + "z": 0.0, + "w": 0.0 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.Rendering.HighDefinition.ShaderGraph.HDLitSubTarget", + "m_ObjectId": "a2b1c60a1f4e4d958112b90537480711" +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.BlockNode", + "m_ObjectId": "a3f302f80ed844ffbf44b99dd893415e", + "m_Group": { + "m_Id": "" + }, + "m_Name": "VertexDescription.Tangent", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": 0.0, + "y": 0.0, + "width": 0.0, + "height": 0.0 + } + }, + "m_Slots": [ + { + "m_Id": "3f29e230e3d24419aee114c671d1e1a2" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_SerializedDescriptor": "VertexDescription.Tangent" +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "a49108ec71074f20a0cf02b277733b3d", + "m_Id": 6, + "m_DisplayName": "B", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "B", + "m_StageCapability": 2, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Texture2DInputMaterialSlot", + "m_ObjectId": "ae49a700327146e198ebe3d7cff9f16e", + "m_Id": 1, + "m_DisplayName": "Texture", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "Texture", + "m_StageCapability": 3, + "m_BareResource": false, + "m_Texture": { + "m_SerializedTexture": "{\"texture\":{\"instanceID\":0}}", + "m_Guid": "" + }, + "m_DefaultType": 0 +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.Rendering.Universal.ShaderGraph.UniversalLitSubTarget", + "m_ObjectId": "af49c364ed4a41e0ba8119d8d4b81eb7", + "m_WorkflowMode": 1, + "m_NormalDropOffSpace": 0, + "m_ClearCoat": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector4MaterialSlot", + "m_ObjectId": "b013472d231248eb9e4a9ee2821e973a", + "m_Id": 0, + "m_DisplayName": "RGBA", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "RGBA", + "m_StageCapability": 2, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.BlockNode", + "m_ObjectId": "b3a7b8c6105d4a9d99f2c0e475229395", + "m_Group": { + "m_Id": "" + }, + "m_Name": "SurfaceDescription.Smoothness", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": 0.0, + "y": 0.0, + "width": 0.0, + "height": 0.0 + } + }, + "m_Slots": [ + { + "m_Id": "59f499593ce549cdbfb6c359ff36b6cc" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_SerializedDescriptor": "SurfaceDescription.Smoothness" +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.BlockNode", + "m_ObjectId": "bb1de797d6b24fdd8548d1fa61c25fea", + "m_Group": { + "m_Id": "" + }, + "m_Name": "SurfaceDescription.Alpha", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": 0.0, + "y": 0.0, + "width": 0.0, + "height": 0.0 + } + }, + "m_Slots": [ + { + "m_Id": "48bfc27e7f46426d98a47ecf41075042" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_SerializedDescriptor": "SurfaceDescription.Alpha" +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.Rendering.BuiltIn.ShaderGraph.BuiltInLitSubTarget", + "m_ObjectId": "be4795b19cdd4426bcdabf79f1c24b0a", + "m_WorkflowMode": 1, + "m_NormalDropOffSpace": 0 +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.UVMaterialSlot", + "m_ObjectId": "c84e98391374467b949f3a300d8addbc", + "m_Id": 2, + "m_DisplayName": "UV", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "UV", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0 + }, + "m_Labels": [], + "m_Channel": 0 +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "d62d1c4bb772482a93392ab836e9a3d9", + "m_Id": 0, + "m_DisplayName": "Ambient Occlusion", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "Occlusion", + "m_StageCapability": 2, + "m_Value": 1.0, + "m_DefaultValue": 1.0, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.BlockNode", + "m_ObjectId": "d8cd689a35ac40ccb7fc9fa38bfedb1b", + "m_Group": { + "m_Id": "" + }, + "m_Name": "VertexDescription.Normal", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": 0.0, + "y": 0.0, + "width": 0.0, + "height": 0.0 + } + }, + "m_Slots": [ + { + "m_Id": "58f71dd6e7b94c619ccf281e00723d3d" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_SerializedDescriptor": "VertexDescription.Normal" +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.Rendering.HighDefinition.ShaderGraph.BuiltinData", + "m_ObjectId": "d8fb147345fe44deb67b06184c7aaf52", + "m_Distortion": false, + "m_DistortionMode": 0, + "m_DistortionDepthTest": true, + "m_AddPrecomputedVelocity": false, + "m_TransparentWritesMotionVec": false, + "m_AlphaToMask": false, + "m_DepthOffset": false, + "m_ConservativeDepthOffset": false, + "m_TransparencyFog": true, + "m_AlphaTestShadow": false, + "m_BackThenFrontRendering": false, + "m_TransparentDepthPrepass": false, + "m_TransparentDepthPostpass": false, + "m_SupportLodCrossFade": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.BlockNode", + "m_ObjectId": "dcc961838b80405199d4e7d4c1f4fd7d", + "m_Group": { + "m_Id": "" + }, + "m_Name": "SurfaceDescription.BaseColor", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": 0.0, + "y": 0.0, + "width": 0.0, + "height": 0.0 + } + }, + "m_Slots": [ + { + "m_Id": "5e169845faf04ef1a19dade797cadeed" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_SerializedDescriptor": "SurfaceDescription.BaseColor" +} + +{ + "m_SGVersion": 1, + "m_Type": "UnityEditor.Rendering.Universal.ShaderGraph.UniversalTarget", + "m_ObjectId": "dd93478797c54e378dce24d430828d35", + "m_ActiveSubTarget": { + "m_Id": "af49c364ed4a41e0ba8119d8d4b81eb7" + }, + "m_AllowMaterialOverride": false, + "m_SurfaceType": 0, + "m_ZTestMode": 4, + "m_ZWriteControl": 0, + "m_AlphaMode": 0, + "m_RenderFace": 2, + "m_AlphaClip": false, + "m_CastShadows": true, + "m_ReceiveShadows": true, + "m_CustomEditorGUI": "", + "m_SupportVFX": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Internal.Texture2DShaderProperty", + "m_ObjectId": "ddfd2e0ff3934cee81c59223a6aff2c9", + "m_Guid": { + "m_GuidSerialized": "102ebb54-4113-4289-b8e8-e63ef7917ce0" + }, + "m_Name": "Main", + "m_DefaultRefNameVersion": 1, + "m_RefNameGeneratedByDisplayName": "Main", + "m_DefaultReferenceName": "_Main", + "m_OverrideReferenceName": "", + "m_GeneratePropertyBlock": true, + "m_UseCustomSlotLabel": false, + "m_CustomSlotLabel": "", + "m_Precision": 0, + "overrideHLSLDeclaration": false, + "hlslDeclarationOverride": 0, + "m_Hidden": false, + "m_Value": { + "m_SerializedTexture": "{\"texture\":{\"instanceID\":0}}", + "m_Guid": "" + }, + "isMainTexture": false, + "useTilingAndOffset": false, + "m_Modifiable": true, + "m_DefaultType": 0 +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.Rendering.HighDefinition.ShaderGraph.LightingData", + "m_ObjectId": "e2857615bb264191854f0ddf6a91ee00", + "m_NormalDropOffSpace": 0, + "m_BlendPreserveSpecular": true, + "m_ReceiveDecals": true, + "m_ReceiveSSR": true, + "m_ReceiveSSRTransparent": false, + "m_SpecularAA": false, + "m_SpecularOcclusionMode": 1, + "m_OverrideBakedGI": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "e34c98ea8e534dd09964fc90ab08bd91", + "m_Id": 0, + "m_DisplayName": "Metallic", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "Metallic", + "m_StageCapability": 2, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector2MaterialSlot", + "m_ObjectId": "e85243155cd34b7d945bc4b2d2cab6b3", + "m_Id": 1, + "m_DisplayName": "Tiling", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "Tiling", + "m_StageCapability": 3, + "m_Value": { + "x": 1.0, + "y": 1.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.NormalMaterialSlot", + "m_ObjectId": "f52a98485db2455db11f6cdede9bae95", + "m_Id": 0, + "m_DisplayName": "Bent Normal", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "BentNormal", + "m_StageCapability": 2, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [], + "m_Space": 3 +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.PropertyNode", + "m_ObjectId": "f538dbc91a2f4d8d8f4b21556d67960b", + "m_Group": { + "m_Id": "" + }, + "m_Name": "Property", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -970.3999633789063, + "y": 225.60003662109376, + "width": 109.5999755859375, + "height": 33.600006103515628 + } + }, + "m_Slots": [ + { + "m_Id": "0e30156cfe4e4283a0dde082768d533e" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_Property": { + "m_Id": "ddfd2e0ff3934cee81c59223a6aff2c9" + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.MultiplyNode", + "m_ObjectId": "f5609f11baf94d889ab3f8bf42aa2131", + "m_Group": { + "m_Id": "" + }, + "m_Name": "Multiply", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -543.2000122070313, + "y": 200.0, + "width": 130.40005493164063, + "height": 117.60000610351563 + } + }, + "m_Slots": [ + { + "m_Id": "537ac3a52c2746868e48f15018591a5c" + }, + { + "m_Id": "8f07f80a79804412a5c2bb689ad58241" + }, + { + "m_Id": "9f6f0b738f2946c395d7094746087ee8" + } + ], + "synonyms": [ + "multiplication", + "times", + "x" + ], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.Rendering.Universal.ShaderGraph.UniversalLitSubTarget", + "m_ObjectId": "f89b1f7ace834b6ab17c8f38c907dca5", + "m_WorkflowMode": 1, + "m_NormalDropOffSpace": 0, + "m_ClearCoat": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.SampleTexture2DNode", + "m_ObjectId": "f8ebcdc66077436288a397d204bbd8cd", + "m_Group": { + "m_Id": "" + }, + "m_Name": "Sample Texture 2D", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -823.2000122070313, + "y": 226.4000244140625, + "width": 183.20001220703126, + "height": 247.99996948242188 + } + }, + "m_Slots": [ + { + "m_Id": "b013472d231248eb9e4a9ee2821e973a" + }, + { + "m_Id": "83b8eb9a889d43a684ef184301fd6e9e" + }, + { + "m_Id": "27a353a5cc96432fa692fdda747d8c67" + }, + { + "m_Id": "a49108ec71074f20a0cf02b277733b3d" + }, + { + "m_Id": "1c6b14984c74490d9e22845b989d3c38" + }, + { + "m_Id": "ae49a700327146e198ebe3d7cff9f16e" + }, + { + "m_Id": "c84e98391374467b949f3a300d8addbc" + }, + { + "m_Id": "88b967de53c84f6499f2cca8003c4851" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_TextureType": 0, + "m_NormalMapSpace": 0, + "m_EnableGlobalMipBias": true +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector2MaterialSlot", + "m_ObjectId": "fe52d187880e4a4781987f545692006d", + "m_Id": 2, + "m_DisplayName": "Offset", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "Offset", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0 + }, + "m_Labels": [] +} + diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/Common/Shaders/MC2_Common_Lit_Front.shadergraph.meta b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Shaders/MC2_Common_Lit_Front.shadergraph.meta new file mode 100644 index 00000000..2b3043a4 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Shaders/MC2_Common_Lit_Front.shadergraph.meta @@ -0,0 +1,17 @@ +fileFormatVersion: 2 +guid: e0b73429f84a56840ba17b216237f806 +ScriptedImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 2 + userData: + assetBundleName: + assetBundleVariant: + script: {fileID: 11500000, guid: 625f186215c104763be7675aa2d941aa, type: 3} +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/Common/Shaders/MC2_Common_Lit_Front.shadergraph + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/Common/Textures.meta b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Textures.meta new file mode 100644 index 00000000..33aeff4b --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Textures.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 2233c08f69efaa348b41487c7aece386 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/Common/Textures/SD_UnityChan_Skirt_PaintMap.png b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Textures/SD_UnityChan_Skirt_PaintMap.png new file mode 100644 index 00000000..1ede3f46 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Textures/SD_UnityChan_Skirt_PaintMap.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7b523a0fd463fba6d3398a9d7bf0b5540e2a2927f35f0e44d43975eef6d4f612 +size 4676 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/Common/Textures/SD_UnityChan_Skirt_PaintMap.png.meta b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Textures/SD_UnityChan_Skirt_PaintMap.png.meta new file mode 100644 index 00000000..6356f122 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/Common/Textures/SD_UnityChan_Skirt_PaintMap.png.meta @@ -0,0 +1,142 @@ +fileFormatVersion: 2 +guid: 00d6a209303f1804a81aee79794da3a4 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 12 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 1 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMasterTextureLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 0 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + cookieLightType: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 128 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Server + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Android + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/Common/Textures/SD_UnityChan_Skirt_PaintMap.png + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes.meta b/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes.meta new file mode 100644 index 00000000..08fe6db2 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: ec893c380aa139943a8cb29f3a934540 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/CoreRP.meta b/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/CoreRP.meta new file mode 100644 index 00000000..577cc500 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/CoreRP.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 34a0a79e78943c44b8e0dbdbb3f7ab58 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/CoreRP/RuntimeBuild_CoreRP.unity b/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/CoreRP/RuntimeBuild_CoreRP.unity new file mode 100644 index 00000000..ba7a7d5d --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/CoreRP/RuntimeBuild_CoreRP.unity @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:860b4833c5b666c3c0e8f7eedf41f0a72f5dd521ecc966ea4f0e4360ea1f0c36 +size 21524 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/CoreRP/RuntimeBuild_CoreRP.unity.meta b/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/CoreRP/RuntimeBuild_CoreRP.unity.meta new file mode 100644 index 00000000..2f7a8e89 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/CoreRP/RuntimeBuild_CoreRP.unity.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: 93948452698a73449bbea353e91d29c7 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/CoreRP/RuntimeBuild_CoreRP.unity + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/CoreRP/RuntimeDressUp_CoreRP.unity b/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/CoreRP/RuntimeDressUp_CoreRP.unity new file mode 100644 index 00000000..e90f237a --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/CoreRP/RuntimeDressUp_CoreRP.unity @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:afb28bb52e03d0d30504ec4dadf0d1a5dc422ceaa0b06bd6242e44a16bf788e1 +size 24859 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/CoreRP/RuntimeDressUp_CoreRP.unity.meta b/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/CoreRP/RuntimeDressUp_CoreRP.unity.meta new file mode 100644 index 00000000..cfdfc6e9 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/CoreRP/RuntimeDressUp_CoreRP.unity.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: f270683cd8624d64d8d14af230cc8463 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/CoreRP/RuntimeDressUp_CoreRP.unity + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/CoreRP/UnityChanKAGURA_CoreRP.unity b/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/CoreRP/UnityChanKAGURA_CoreRP.unity new file mode 100644 index 00000000..78a5aa64 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/CoreRP/UnityChanKAGURA_CoreRP.unity @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6fe3dc5720a8c5fad181a0d26496c40a37ac6d36d4adaa54682a75eaf87a33c9 +size 22305 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/CoreRP/UnityChanKAGURA_CoreRP.unity.meta b/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/CoreRP/UnityChanKAGURA_CoreRP.unity.meta new file mode 100644 index 00000000..c2c9de61 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/CoreRP/UnityChanKAGURA_CoreRP.unity.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: e4876628e0b615548a27a4e96ec1f4fe +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/CoreRP/UnityChanKAGURA_CoreRP.unity + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/CoreRP/Wind_CoreRP.unity b/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/CoreRP/Wind_CoreRP.unity new file mode 100644 index 00000000..488e5bdf --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/CoreRP/Wind_CoreRP.unity @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a0770ad95b644ffda1533781775e1c1fc885a33f5c3a564706f3ac38e145aec8 +size 32414 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/CoreRP/Wind_CoreRP.unity.meta b/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/CoreRP/Wind_CoreRP.unity.meta new file mode 100644 index 00000000..8463bcb8 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/CoreRP/Wind_CoreRP.unity.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: 267e0138a7a8ede409cd7c4e4381c7c8 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/CoreRP/Wind_CoreRP.unity + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/HDRP.meta b/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/HDRP.meta new file mode 100644 index 00000000..71114a88 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/HDRP.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 23d215c402a80c14bac570f542a2b396 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/HDRP/MC2_SkyandFogSettingsProfile.asset b/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/HDRP/MC2_SkyandFogSettingsProfile.asset new file mode 100644 index 00000000..da8b7981 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/HDRP/MC2_SkyandFogSettingsProfile.asset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:76065a65cfc41247023e102f0b33db175791727ec7cf7bc7fc7275f757a45898 +size 13446 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/HDRP/MC2_SkyandFogSettingsProfile.asset.meta b/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/HDRP/MC2_SkyandFogSettingsProfile.asset.meta new file mode 100644 index 00000000..2e3223a3 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/HDRP/MC2_SkyandFogSettingsProfile.asset.meta @@ -0,0 +1,15 @@ +fileFormatVersion: 2 +guid: b1b25245d5b864343a133fabb2dc80f7 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/HDRP/MC2_SkyandFogSettingsProfile.asset + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/HDRP/RuntimeBuild_HDRP.unity b/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/HDRP/RuntimeBuild_HDRP.unity new file mode 100644 index 00000000..d6ba10af --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/HDRP/RuntimeBuild_HDRP.unity @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7fea7725e8efb1b47c7a169ca2bab7c8e6e94b2f0212e92cabb97976ad0db966 +size 32248 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/HDRP/RuntimeBuild_HDRP.unity.meta b/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/HDRP/RuntimeBuild_HDRP.unity.meta new file mode 100644 index 00000000..b1e7c16f --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/HDRP/RuntimeBuild_HDRP.unity.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: 36ece2ce79b44ae45a27a708761e0f07 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/HDRP/RuntimeBuild_HDRP.unity + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/HDRP/RuntimeDressUp_HDRP.unity b/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/HDRP/RuntimeDressUp_HDRP.unity new file mode 100644 index 00000000..11155491 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/HDRP/RuntimeDressUp_HDRP.unity @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ec09c465c007e7870e26e30432253206ef5b9f32e7ea80f3f4dabf3956fce4bd +size 35251 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/HDRP/RuntimeDressUp_HDRP.unity.meta b/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/HDRP/RuntimeDressUp_HDRP.unity.meta new file mode 100644 index 00000000..f763c148 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/HDRP/RuntimeDressUp_HDRP.unity.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: 94497b725e0bd3c4f9c615f7162394ce +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/HDRP/RuntimeDressUp_HDRP.unity + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/HDRP/UnityChanKAGURA_HDRP.unity b/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/HDRP/UnityChanKAGURA_HDRP.unity new file mode 100644 index 00000000..0e1620b4 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/HDRP/UnityChanKAGURA_HDRP.unity @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7a4bb6799f0716f2084e18d45ccea9d4863cd0005e0a2e38dd9d886609fb4059 +size 31077 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/HDRP/UnityChanKAGURA_HDRP.unity.meta b/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/HDRP/UnityChanKAGURA_HDRP.unity.meta new file mode 100644 index 00000000..ab7f3a4d --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/HDRP/UnityChanKAGURA_HDRP.unity.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: bf9e8cbc74c20384b9a7d2a354ddde18 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/HDRP/UnityChanKAGURA_HDRP.unity + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/HDRP/Wind_HDRP.unity b/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/HDRP/Wind_HDRP.unity new file mode 100644 index 00000000..9e1c1035 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/HDRP/Wind_HDRP.unity @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:99cce3af172187c84045b975c0b30a2f58a206250d982ec647d0277c3d83f27d +size 42992 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/HDRP/Wind_HDRP.unity.meta b/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/HDRP/Wind_HDRP.unity.meta new file mode 100644 index 00000000..76601cfa --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/HDRP/Wind_HDRP.unity.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: cceffaba687d4f54c9223904abae4103 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/HDRP/Wind_HDRP.unity + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/URP.meta b/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/URP.meta new file mode 100644 index 00000000..291f9cdb --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/URP.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 47028f8811dde3346914715fcf46e622 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/URP/RuntimeBuild_URP.unity b/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/URP/RuntimeBuild_URP.unity new file mode 100644 index 00000000..6e3554d7 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/URP/RuntimeBuild_URP.unity @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ce17c28cce82a3330d1a68ef3ddbd31c1a0d41f5e0d80e22d26cd200565e7fca +size 24160 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/URP/RuntimeBuild_URP.unity.meta b/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/URP/RuntimeBuild_URP.unity.meta new file mode 100644 index 00000000..d971f531 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/URP/RuntimeBuild_URP.unity.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: 92dcb0677c9b85043b57cf704d41960b +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/URP/RuntimeBuild_URP.unity + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/URP/RuntimeDressUp_URP.unity b/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/URP/RuntimeDressUp_URP.unity new file mode 100644 index 00000000..71a87d60 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/URP/RuntimeDressUp_URP.unity @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:091135f278c3d1a33b2674c4dc57076599bb9b882c71bb03cf5dad6cfec09dd6 +size 27146 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/URP/RuntimeDressUp_URP.unity.meta b/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/URP/RuntimeDressUp_URP.unity.meta new file mode 100644 index 00000000..6ccc4f06 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/URP/RuntimeDressUp_URP.unity.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: f4b046e16bdc56641bf93aa9cb3bb0f1 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/URP/RuntimeDressUp_URP.unity + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/URP/UnityChanKAGURA_URP.unity b/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/URP/UnityChanKAGURA_URP.unity new file mode 100644 index 00000000..ea99b0d2 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/URP/UnityChanKAGURA_URP.unity @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:af0e36ae0b62065438bd0cb146c47337c36c77875c4677b602ac9dff422a71dc +size 21908 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/URP/UnityChanKAGURA_URP.unity.meta b/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/URP/UnityChanKAGURA_URP.unity.meta new file mode 100644 index 00000000..7d451bed --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/URP/UnityChanKAGURA_URP.unity.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: 4912343a4ca12104c85e528a3f53cf36 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/URP/UnityChanKAGURA_URP.unity + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/URP/Wind_URP.unity b/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/URP/Wind_URP.unity new file mode 100644 index 00000000..b8808ac8 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/URP/Wind_URP.unity @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e04238994ca5748524d1d0145a243edbb8b478215317eed413b665398967b485 +size 33251 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/URP/Wind_URP.unity.meta b/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/URP/Wind_URP.unity.meta new file mode 100644 index 00000000..e595de53 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/URP/Wind_URP.unity.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: c9634d62ab15660448216ecd2d46d7a7 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes/URP/Wind_URP.unity + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher.meta b/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher.meta new file mode 100644 index 00000000..74824a62 --- /dev/null +++ b/Assets/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/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/HighDefinition3D.meta b/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/HighDefinition3D.meta new file mode 100644 index 00000000..a52c053f --- /dev/null +++ b/Assets/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/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/HighDefinition3D/RuntimeBuild_HighDefinition3D.unity b/Assets/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/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/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/HighDefinition3D/RuntimeBuild_HighDefinition3D.unity.meta b/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/HighDefinition3D/RuntimeBuild_HighDefinition3D.unity.meta new file mode 100644 index 00000000..37dcbc40 --- /dev/null +++ b/Assets/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.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/HighDefinition3D/RuntimeBuild_HighDefinition3D.unity + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/HighDefinition3D/RuntimeDressUp_HighDefinition3D.unity b/Assets/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/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/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/HighDefinition3D/RuntimeDressUp_HighDefinition3D.unity.meta b/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/HighDefinition3D/RuntimeDressUp_HighDefinition3D.unity.meta new file mode 100644 index 00000000..bdf79c55 --- /dev/null +++ b/Assets/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.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/HighDefinition3D/RuntimeDressUp_HighDefinition3D.unity + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/HighDefinition3D/UnityChanKAGURA_HighDefinition3D.unity b/Assets/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/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/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/HighDefinition3D/UnityChanKAGURA_HighDefinition3D.unity.meta b/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/HighDefinition3D/UnityChanKAGURA_HighDefinition3D.unity.meta new file mode 100644 index 00000000..687ccdee --- /dev/null +++ b/Assets/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.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/HighDefinition3D/UnityChanKAGURA_HighDefinition3D.unity + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/HighDefinition3D/Wind_HighDefinition3D.unity b/Assets/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/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/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/HighDefinition3D/Wind_HighDefinition3D.unity.meta b/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/HighDefinition3D/Wind_HighDefinition3D.unity.meta new file mode 100644 index 00000000..efd8ad59 --- /dev/null +++ b/Assets/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.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/HighDefinition3D/Wind_HighDefinition3D.unity + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/Universal3D.meta b/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/Universal3D.meta new file mode 100644 index 00000000..c51f6ec4 --- /dev/null +++ b/Assets/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/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/Universal3D/RuntimeBuild_Universal3D.unity b/Assets/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/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/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/Universal3D/RuntimeBuild_Universal3D.unity.meta b/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/Universal3D/RuntimeBuild_Universal3D.unity.meta new file mode 100644 index 00000000..7136957d --- /dev/null +++ b/Assets/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.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/Universal3D/RuntimeBuild_Universal3D.unity + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/Universal3D/RuntimeDressUp_Universal3D.unity b/Assets/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/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/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/Universal3D/RuntimeDressUp_Universal3D.unity.meta b/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/Universal3D/RuntimeDressUp_Universal3D.unity.meta new file mode 100644 index 00000000..2b793885 --- /dev/null +++ b/Assets/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.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/Universal3D/RuntimeDressUp_Universal3D.unity + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/Universal3D/UnityChanKAGURA_Universal3D.unity b/Assets/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/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/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/Universal3D/UnityChanKAGURA_Universal3D.unity.meta b/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/Universal3D/UnityChanKAGURA_Universal3D.unity.meta new file mode 100644 index 00000000..a08e6a26 --- /dev/null +++ b/Assets/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.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/Universal3D/UnityChanKAGURA_Universal3D.unity + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/Universal3D/Wind_Universal3D.unity b/Assets/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/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/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/Universal3D/Wind_Universal3D.unity.meta b/Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/Universal3D/Wind_Universal3D.unity.meta new file mode 100644 index 00000000..5f6e7665 --- /dev/null +++ b/Assets/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.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/Universal3D/Wind_Universal3D.unity + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan.meta new file mode 100644 index 00000000..5650d751 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 9a72e6cc61880e442925c90b4d716ed9 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/Logo.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/Logo.meta new file mode 100644 index 00000000..ffaa2b3a --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/Logo.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 363d8d90514d2954fb7650c0d002a4c9 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/Logo/Dark_Silhouette.png b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/Logo/Dark_Silhouette.png new file mode 100644 index 00000000..55314890 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/Logo/Dark_Silhouette.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d5d7e2941aeec38349c36dfdac07022cdcbb09ff6925c6195f819dacd956df19 +size 45873 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/Logo/Dark_Silhouette.png.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/Logo/Dark_Silhouette.png.meta new file mode 100644 index 00000000..e3a07935 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/Logo/Dark_Silhouette.png.meta @@ -0,0 +1,142 @@ +fileFormatVersion: 2 +guid: 3563c26f39220f4409514929be083788 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 12 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMasterTextureLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 1 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 8 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + cookieLightType: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 1024 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Server + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Android + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: 5e97eb03825dee720800000000000000 + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/Logo/Dark_Silhouette.png + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz.meta new file mode 100644 index 00000000..33390cc9 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: d33cde9a16d475d45a6eb80526380702 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials.meta new file mode 100644 index 00000000..192e7613 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 4191a0e9ba79553429f9c9409c0326b0 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/SB_def_mat.mat b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/SB_def_mat.mat new file mode 100644 index 00000000..7a170d6e --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/SB_def_mat.mat @@ -0,0 +1,133 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &-9142388720324707925 +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: Unity.RenderPipelines.Universal.Editor::UnityEditor.Rendering.Universal.AssetVersion + version: 10 +--- !u!114 &-5755898939291106094 +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: 639247ca83abc874e893eb93af2b5e44, type: 3} + m_Name: + m_EditorClassIdentifier: + version: 0 +--- !u!21 &2100000 +Material: + serializedVersion: 8 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: SB_def_mat + m_Shader: {fileID: -6465566751694194690, guid: e0b73429f84a56840ba17b216237f806, type: 3} + m_Parent: {fileID: 0} + m_ModifiedSerializedProperties: 0 + m_ValidKeywords: [] + m_InvalidKeywords: [] + m_LightmapFlags: 4 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: -1 + stringTagMap: {} + disabledShaderPasses: + - MOTIONVECTORS + m_LockedProperties: + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailAlbedoMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main: + m_Texture: {fileID: 2800000, guid: 27570a5ee19caed4d9a04e5b88b3fb55, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OcclusionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_Lightmaps: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_LightmapsInd: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_ShadowMasks: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Ints: [] + m_Floats: + - _BUILTIN_QueueControl: 0 + - _BUILTIN_QueueOffset: 0 + - _BumpScale: 1 + - _Cutoff: 0.5 + - _DetailNormalMapScale: 1 + - _DstBlend: 10 + - _GlossMapScale: 1 + - _Glossiness: 0 + - _GlossyReflections: 1 + - _Metallic: 0 + - _Mode: 3 + - _OcclusionStrength: 1 + - _Parallax: 0.02 + - _QueueControl: 0 + - _QueueOffset: 0 + - _Smoothness: 0 + - _SmoothnessTextureChannel: 0 + - _SpecularHighlights: 1 + - _SrcBlend: 1 + - _UVSec: 0 + - _ZWrite: 0 + m_Colors: + - _Color: {r: 0.9056604, g: 0.9056604, b: 0.9056604, a: 1} + - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} + - _Tiling: {r: 1, g: 1, b: 0, a: 0} + m_BuildTextureStacks: [] + m_AllowLocking: 1 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/SB_def_mat.mat.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/SB_def_mat.mat.meta new file mode 100644 index 00000000..fe3cdb7d --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/SB_def_mat.mat.meta @@ -0,0 +1,15 @@ +fileFormatVersion: 2 +guid: 59f12daf366f95d4984b921d3b5fb893 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/SB_def_mat.mat + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/SB_nol_mat.mat b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/SB_nol_mat.mat new file mode 100644 index 00000000..ab4d0dff --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/SB_nol_mat.mat @@ -0,0 +1,133 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &-199350739714699963 +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: Unity.RenderPipelines.Universal.Editor::UnityEditor.Rendering.Universal.AssetVersion + version: 10 +--- !u!21 &2100000 +Material: + serializedVersion: 8 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: SB_nol_mat + m_Shader: {fileID: -6465566751694194690, guid: e0b73429f84a56840ba17b216237f806, type: 3} + m_Parent: {fileID: 0} + m_ModifiedSerializedProperties: 0 + m_ValidKeywords: [] + m_InvalidKeywords: [] + m_LightmapFlags: 4 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: -1 + stringTagMap: {} + disabledShaderPasses: + - MOTIONVECTORS + m_LockedProperties: + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailAlbedoMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main: + m_Texture: {fileID: 2800000, guid: 27570a5ee19caed4d9a04e5b88b3fb55, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OcclusionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_Lightmaps: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_LightmapsInd: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_ShadowMasks: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Ints: [] + m_Floats: + - _BUILTIN_QueueControl: 0 + - _BUILTIN_QueueOffset: 0 + - _BumpScale: 1 + - _Cutoff: 0.5 + - _DetailNormalMapScale: 1 + - _DstBlend: 10 + - _GlossMapScale: 1 + - _Glossiness: 0 + - _GlossyReflections: 1 + - _Metallic: 0 + - _Mode: 3 + - _OcclusionStrength: 1 + - _Parallax: 0.02 + - _QueueControl: 0 + - _QueueOffset: 0 + - _Smoothness: 0 + - _SmoothnessTextureChannel: 0 + - _SpecularHighlights: 1 + - _SrcBlend: 1 + - _UVSec: 0 + - _ZWrite: 0 + m_Colors: + - _Color: {r: 0.9056604, g: 0.9056604, b: 0.9056604, a: 1} + - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} + - _Tiling: {r: 1, g: 1, b: 0, a: 0} + m_BuildTextureStacks: [] + m_AllowLocking: 1 +--- !u!114 &5988364977265673585 +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: 639247ca83abc874e893eb93af2b5e44, type: 3} + m_Name: + m_EditorClassIdentifier: + version: 0 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/SB_nol_mat.mat.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/SB_nol_mat.mat.meta new file mode 100644 index 00000000..ea928749 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/SB_nol_mat.mat.meta @@ -0,0 +1,15 @@ +fileFormatVersion: 2 +guid: bbcadcb4bdd67154bbd0f71cc5a89cb1 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/SB_nol_mat.mat + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/SB_skin_mat.mat b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/SB_skin_mat.mat new file mode 100644 index 00000000..d25afd99 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/SB_skin_mat.mat @@ -0,0 +1,133 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &-8280027471669481933 +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: Unity.RenderPipelines.Universal.Editor::UnityEditor.Rendering.Universal.AssetVersion + version: 10 +--- !u!114 &-4086932747498456647 +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: 639247ca83abc874e893eb93af2b5e44, type: 3} + m_Name: + m_EditorClassIdentifier: + version: 0 +--- !u!21 &2100000 +Material: + serializedVersion: 8 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: SB_skin_mat + m_Shader: {fileID: -6465566751694194690, guid: e0b73429f84a56840ba17b216237f806, type: 3} + m_Parent: {fileID: 0} + m_ModifiedSerializedProperties: 0 + m_ValidKeywords: [] + m_InvalidKeywords: [] + m_LightmapFlags: 4 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: -1 + stringTagMap: {} + disabledShaderPasses: + - MOTIONVECTORS + m_LockedProperties: + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailAlbedoMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main: + m_Texture: {fileID: 2800000, guid: 27570a5ee19caed4d9a04e5b88b3fb55, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OcclusionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_Lightmaps: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_LightmapsInd: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_ShadowMasks: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Ints: [] + m_Floats: + - _BUILTIN_QueueControl: 0 + - _BUILTIN_QueueOffset: 0 + - _BumpScale: 1 + - _Cutoff: 0.5 + - _DetailNormalMapScale: 1 + - _DstBlend: 10 + - _GlossMapScale: 1 + - _Glossiness: 0 + - _GlossyReflections: 1 + - _Metallic: 0 + - _Mode: 3 + - _OcclusionStrength: 1 + - _Parallax: 0.02 + - _QueueControl: 0 + - _QueueOffset: 0 + - _Smoothness: 0 + - _SmoothnessTextureChannel: 0 + - _SpecularHighlights: 1 + - _SrcBlend: 1 + - _UVSec: 0 + - _ZWrite: 0 + m_Colors: + - _Color: {r: 0.9056604, g: 0.9056604, b: 0.9056604, a: 1} + - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} + - _Tiling: {r: 1, g: 1, b: 0, a: 0} + m_BuildTextureStacks: [] + m_AllowLocking: 1 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/SB_skin_mat.mat.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/SB_skin_mat.mat.meta new file mode 100644 index 00000000..1d68f6ed --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/SB_skin_mat.mat.meta @@ -0,0 +1,15 @@ +fileFormatVersion: 2 +guid: cdced10803944d84ca8836a329489c09 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/SB_skin_mat.mat + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/def_mat.mat b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/def_mat.mat new file mode 100644 index 00000000..638bf621 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/def_mat.mat @@ -0,0 +1,133 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &-1839986918002453301 +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: 639247ca83abc874e893eb93af2b5e44, type: 3} + m_Name: + m_EditorClassIdentifier: + version: 0 +--- !u!21 &2100000 +Material: + serializedVersion: 8 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: def_mat + m_Shader: {fileID: -6465566751694194690, guid: e0b73429f84a56840ba17b216237f806, type: 3} + m_Parent: {fileID: 0} + m_ModifiedSerializedProperties: 0 + m_ValidKeywords: [] + m_InvalidKeywords: [] + m_LightmapFlags: 4 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: -1 + stringTagMap: {} + disabledShaderPasses: + - MOTIONVECTORS + m_LockedProperties: + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailAlbedoMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main: + m_Texture: {fileID: 2800000, guid: e3db91f76893de24ca17abe2afcd3672, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OcclusionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_Lightmaps: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_LightmapsInd: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_ShadowMasks: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Ints: [] + m_Floats: + - _BUILTIN_QueueControl: 0 + - _BUILTIN_QueueOffset: 0 + - _BumpScale: 1 + - _Cutoff: 0.5 + - _DetailNormalMapScale: 1 + - _DstBlend: 10 + - _GlossMapScale: 1 + - _Glossiness: 0 + - _GlossyReflections: 1 + - _Metallic: 0 + - _Mode: 3 + - _OcclusionStrength: 1 + - _Parallax: 0.02 + - _QueueControl: 0 + - _QueueOffset: 0 + - _Smoothness: 0 + - _SmoothnessTextureChannel: 0 + - _SpecularHighlights: 1 + - _SrcBlend: 1 + - _UVSec: 0 + - _ZWrite: 0 + m_Colors: + - _Color: {r: 0.9056604, g: 0.9056604, b: 0.9056604, a: 1} + - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} + - _Tiling: {r: 1, g: 1, b: 0, a: 0} + m_BuildTextureStacks: [] + m_AllowLocking: 1 +--- !u!114 &5919757528438359737 +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: Unity.RenderPipelines.Universal.Editor::UnityEditor.Rendering.Universal.AssetVersion + version: 10 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/def_mat.mat.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/def_mat.mat.meta new file mode 100644 index 00000000..87780e4c --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/def_mat.mat.meta @@ -0,0 +1,15 @@ +fileFormatVersion: 2 +guid: 163929bef874a5a47b9eeaa1af0d9409 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/def_mat.mat + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/hair_mat.mat b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/hair_mat.mat new file mode 100644 index 00000000..a7a9bcf6 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/hair_mat.mat @@ -0,0 +1,133 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &-3408648073975475262 +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: 639247ca83abc874e893eb93af2b5e44, type: 3} + m_Name: + m_EditorClassIdentifier: + version: 0 +--- !u!21 &2100000 +Material: + serializedVersion: 8 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: hair_mat + m_Shader: {fileID: -6465566751694194690, guid: e0b73429f84a56840ba17b216237f806, type: 3} + m_Parent: {fileID: 0} + m_ModifiedSerializedProperties: 0 + m_ValidKeywords: [] + m_InvalidKeywords: [] + m_LightmapFlags: 4 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: -1 + stringTagMap: {} + disabledShaderPasses: + - MOTIONVECTORS + m_LockedProperties: + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailAlbedoMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main: + m_Texture: {fileID: 2800000, guid: e3db91f76893de24ca17abe2afcd3672, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OcclusionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_Lightmaps: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_LightmapsInd: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_ShadowMasks: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Ints: [] + m_Floats: + - _BUILTIN_QueueControl: 0 + - _BUILTIN_QueueOffset: 0 + - _BumpScale: 1 + - _Cutoff: 0.5 + - _DetailNormalMapScale: 1 + - _DstBlend: 10 + - _GlossMapScale: 1 + - _Glossiness: 0 + - _GlossyReflections: 1 + - _Metallic: 0 + - _Mode: 3 + - _OcclusionStrength: 1 + - _Parallax: 0.02 + - _QueueControl: 0 + - _QueueOffset: 0 + - _Smoothness: 0 + - _SmoothnessTextureChannel: 0 + - _SpecularHighlights: 1 + - _SrcBlend: 1 + - _UVSec: 0 + - _ZWrite: 0 + m_Colors: + - _Color: {r: 0.9056604, g: 0.9056604, b: 0.9056604, a: 1} + - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} + - _Tiling: {r: 1, g: 1, b: 0, a: 0} + m_BuildTextureStacks: [] + m_AllowLocking: 1 +--- !u!114 &8780273825324758544 +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: Unity.RenderPipelines.Universal.Editor::UnityEditor.Rendering.Universal.AssetVersion + version: 10 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/hair_mat.mat.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/hair_mat.mat.meta new file mode 100644 index 00000000..0ae00a24 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/hair_mat.mat.meta @@ -0,0 +1,15 @@ +fileFormatVersion: 2 +guid: 4a800f51326d0df4a89423faffd109e6 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/hair_mat.mat + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/mouth_mat.mat b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/mouth_mat.mat new file mode 100644 index 00000000..35213f98 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/mouth_mat.mat @@ -0,0 +1,133 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &-6329500939640827849 +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: Unity.RenderPipelines.Universal.Editor::UnityEditor.Rendering.Universal.AssetVersion + version: 10 +--- !u!21 &2100000 +Material: + serializedVersion: 8 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: mouth_mat + m_Shader: {fileID: -6465566751694194690, guid: e0b73429f84a56840ba17b216237f806, type: 3} + m_Parent: {fileID: 0} + m_ModifiedSerializedProperties: 0 + m_ValidKeywords: [] + m_InvalidKeywords: [] + m_LightmapFlags: 4 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: -1 + stringTagMap: {} + disabledShaderPasses: + - MOTIONVECTORS + m_LockedProperties: + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailAlbedoMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main: + m_Texture: {fileID: 2800000, guid: e3db91f76893de24ca17abe2afcd3672, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OcclusionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_Lightmaps: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_LightmapsInd: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_ShadowMasks: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Ints: [] + m_Floats: + - _BUILTIN_QueueControl: 0 + - _BUILTIN_QueueOffset: 0 + - _BumpScale: 1 + - _Cutoff: 0.5 + - _DetailNormalMapScale: 1 + - _DstBlend: 10 + - _GlossMapScale: 1 + - _Glossiness: 0 + - _GlossyReflections: 1 + - _Metallic: 0 + - _Mode: 3 + - _OcclusionStrength: 1 + - _Parallax: 0.02 + - _QueueControl: 0 + - _QueueOffset: 0 + - _Smoothness: 0 + - _SmoothnessTextureChannel: 0 + - _SpecularHighlights: 1 + - _SrcBlend: 1 + - _UVSec: 0 + - _ZWrite: 0 + m_Colors: + - _Color: {r: 0.9056604, g: 0.9056604, b: 0.9056604, a: 1} + - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} + - _Tiling: {r: 1, g: 1, b: 0, a: 0} + m_BuildTextureStacks: [] + m_AllowLocking: 1 +--- !u!114 &121759418820508836 +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: 639247ca83abc874e893eb93af2b5e44, type: 3} + m_Name: + m_EditorClassIdentifier: + version: 0 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/mouth_mat.mat.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/mouth_mat.mat.meta new file mode 100644 index 00000000..100d8b3c --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/mouth_mat.mat.meta @@ -0,0 +1,15 @@ +fileFormatVersion: 2 +guid: 463c6f29901dda148bc86247837ca2b7 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/mouth_mat.mat + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/nol_mat.mat b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/nol_mat.mat new file mode 100644 index 00000000..f7895ab3 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/nol_mat.mat @@ -0,0 +1,133 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &-6991097911196341467 +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: Unity.RenderPipelines.Universal.Editor::UnityEditor.Rendering.Universal.AssetVersion + version: 10 +--- !u!21 &2100000 +Material: + serializedVersion: 8 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: nol_mat + m_Shader: {fileID: -6465566751694194690, guid: e0b73429f84a56840ba17b216237f806, type: 3} + m_Parent: {fileID: 0} + m_ModifiedSerializedProperties: 0 + m_ValidKeywords: [] + m_InvalidKeywords: [] + m_LightmapFlags: 4 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: -1 + stringTagMap: {} + disabledShaderPasses: + - MOTIONVECTORS + m_LockedProperties: + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailAlbedoMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main: + m_Texture: {fileID: 2800000, guid: e3db91f76893de24ca17abe2afcd3672, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OcclusionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_Lightmaps: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_LightmapsInd: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_ShadowMasks: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Ints: [] + m_Floats: + - _BUILTIN_QueueControl: 0 + - _BUILTIN_QueueOffset: 0 + - _BumpScale: 1 + - _Cutoff: 0.5 + - _DetailNormalMapScale: 1 + - _DstBlend: 10 + - _GlossMapScale: 1 + - _Glossiness: 0 + - _GlossyReflections: 1 + - _Metallic: 0 + - _Mode: 3 + - _OcclusionStrength: 1 + - _Parallax: 0.02 + - _QueueControl: 0 + - _QueueOffset: 0 + - _Smoothness: 0 + - _SmoothnessTextureChannel: 0 + - _SpecularHighlights: 1 + - _SrcBlend: 1 + - _UVSec: 0 + - _ZWrite: 0 + m_Colors: + - _Color: {r: 0.9056604, g: 0.9056604, b: 0.9056604, a: 1} + - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} + - _Tiling: {r: 1, g: 1, b: 0, a: 0} + m_BuildTextureStacks: [] + m_AllowLocking: 1 +--- !u!114 &6265247899772061283 +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: 639247ca83abc874e893eb93af2b5e44, type: 3} + m_Name: + m_EditorClassIdentifier: + version: 0 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/nol_mat.mat.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/nol_mat.mat.meta new file mode 100644 index 00000000..d5211912 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/nol_mat.mat.meta @@ -0,0 +1,15 @@ +fileFormatVersion: 2 +guid: 7f9e816ced8528d49a5302b7c88ad155 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/nol_mat.mat + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/skin_mat.mat b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/skin_mat.mat new file mode 100644 index 00000000..2b3f8782 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/skin_mat.mat @@ -0,0 +1,133 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 8 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: skin_mat + m_Shader: {fileID: -6465566751694194690, guid: e0b73429f84a56840ba17b216237f806, type: 3} + m_Parent: {fileID: 0} + m_ModifiedSerializedProperties: 0 + m_ValidKeywords: [] + m_InvalidKeywords: [] + m_LightmapFlags: 4 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: -1 + stringTagMap: {} + disabledShaderPasses: + - MOTIONVECTORS + m_LockedProperties: + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailAlbedoMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main: + m_Texture: {fileID: 2800000, guid: e3db91f76893de24ca17abe2afcd3672, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OcclusionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_Lightmaps: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_LightmapsInd: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_ShadowMasks: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Ints: [] + m_Floats: + - _BUILTIN_QueueControl: 0 + - _BUILTIN_QueueOffset: 0 + - _BumpScale: 1 + - _Cutoff: 0.5 + - _DetailNormalMapScale: 1 + - _DstBlend: 10 + - _GlossMapScale: 1 + - _Glossiness: 0 + - _GlossyReflections: 1 + - _Metallic: 0 + - _Mode: 3 + - _OcclusionStrength: 1 + - _Parallax: 0.02 + - _QueueControl: 0 + - _QueueOffset: 0 + - _Smoothness: 0 + - _SmoothnessTextureChannel: 0 + - _SpecularHighlights: 1 + - _SrcBlend: 1 + - _UVSec: 0 + - _ZWrite: 0 + m_Colors: + - _Color: {r: 0.9056604, g: 0.9056604, b: 0.9056604, a: 1} + - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} + - _Tiling: {r: 1, g: 1, b: 0, a: 0} + m_BuildTextureStacks: [] + m_AllowLocking: 1 +--- !u!114 &5046530880951960719 +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: 639247ca83abc874e893eb93af2b5e44, type: 3} + m_Name: + m_EditorClassIdentifier: + version: 0 +--- !u!114 &7950376295448117369 +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: Unity.RenderPipelines.Universal.Editor::UnityEditor.Rendering.Universal.AssetVersion + version: 10 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/skin_mat.mat.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/skin_mat.mat.meta new file mode 100644 index 00000000..e8c4368c --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/skin_mat.mat.meta @@ -0,0 +1,15 @@ +fileFormatVersion: 2 +guid: b2196d7da1a53294aae46258e3d23d51 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/skin_mat.mat + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/SD_UnityChan.controller b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/SD_UnityChan.controller new file mode 100644 index 00000000..aa605901 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/SD_UnityChan.controller @@ -0,0 +1,159 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1102 &-7982639091996884250 +AnimatorState: + serializedVersion: 6 + m_ObjectHideFlags: 1 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: WALK00_F + m_Speed: 1 + m_CycleOffset: 0 + m_Transitions: [] + m_StateMachineBehaviours: [] + m_Position: {x: 50, y: 50, z: 0} + m_IKOnFeet: 1 + m_WriteDefaultValues: 1 + m_Mirror: 0 + m_SpeedParameterActive: 0 + m_MirrorParameterActive: 0 + m_CycleOffsetParameterActive: 0 + m_TimeParameterActive: 0 + m_Motion: {fileID: 7400000, guid: be35c3e99cdcca3439901f433aab54b2, type: 2} + m_Tag: + m_SpeedParameter: + m_MirrorParameter: + m_CycleOffsetParameter: + m_TimeParameter: +--- !u!1102 &-6546539397642646782 +AnimatorState: + serializedVersion: 6 + m_ObjectHideFlags: 1 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: WAIT04 + m_Speed: 1 + m_CycleOffset: 0 + m_Transitions: [] + m_StateMachineBehaviours: [] + m_Position: {x: 50, y: 50, z: 0} + m_IKOnFeet: 0 + m_WriteDefaultValues: 1 + m_Mirror: 0 + m_SpeedParameterActive: 0 + m_MirrorParameterActive: 0 + m_CycleOffsetParameterActive: 0 + m_TimeParameterActive: 0 + m_Motion: {fileID: 7400000, guid: 3a954c05a2f94004eaff3df94a45c3ed, type: 2} + m_Tag: + m_SpeedParameter: + m_MirrorParameter: + m_CycleOffsetParameter: + m_TimeParameter: +--- !u!1102 &-5063388297046124761 +AnimatorState: + serializedVersion: 6 + m_ObjectHideFlags: 1 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: RUN00_F + m_Speed: 1 + m_CycleOffset: 0 + m_Transitions: [] + m_StateMachineBehaviours: [] + m_Position: {x: 50, y: 50, z: 0} + m_IKOnFeet: 1 + m_WriteDefaultValues: 1 + m_Mirror: 0 + m_SpeedParameterActive: 0 + m_MirrorParameterActive: 0 + m_CycleOffsetParameterActive: 0 + m_TimeParameterActive: 0 + m_Motion: {fileID: 7400000, guid: d57512b99bc2cc84f92c873f858d9714, type: 2} + m_Tag: + m_SpeedParameter: + m_MirrorParameter: + m_CycleOffsetParameter: + m_TimeParameter: +--- !u!91 &9100000 +AnimatorController: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: SD_UnityChan + serializedVersion: 5 + m_AnimatorParameters: [] + m_AnimatorLayers: + - serializedVersion: 5 + m_Name: Base Layer + m_StateMachine: {fileID: 558329607340261005} + m_Mask: {fileID: 0} + m_Motions: [] + m_Behaviours: [] + m_BlendingMode: 0 + m_SyncedLayerIndex: -1 + m_DefaultWeight: 0 + m_IKPass: 0 + m_SyncedLayerAffectsTiming: 0 + m_Controller: {fileID: 9100000} +--- !u!1107 &558329607340261005 +AnimatorStateMachine: + serializedVersion: 6 + m_ObjectHideFlags: 1 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: Base Layer + m_ChildStates: + - serializedVersion: 1 + m_State: {fileID: 6978213238113248026} + m_Position: {x: 50, y: 220, z: 0} + - serializedVersion: 1 + m_State: {fileID: -5063388297046124761} + m_Position: {x: 290, y: 220, z: 0} + - serializedVersion: 1 + m_State: {fileID: -6546539397642646782} + m_Position: {x: 530, y: 220, z: 0} + - serializedVersion: 1 + m_State: {fileID: -7982639091996884250} + m_Position: {x: 70, y: 300, z: 0} + m_ChildStateMachines: [] + m_AnyStateTransitions: [] + m_EntryTransitions: [] + m_StateMachineTransitions: {} + m_StateMachineBehaviours: [] + m_AnyStatePosition: {x: 50, y: 20, z: 0} + m_EntryPosition: {x: 50, y: 120, z: 0} + m_ExitPosition: {x: 800, y: 120, z: 0} + m_ParentStateMachinePosition: {x: 800, y: 20, z: 0} + m_DefaultState: {fileID: -6546539397642646782} +--- !u!1102 &6978213238113248026 +AnimatorState: + serializedVersion: 6 + m_ObjectHideFlags: 1 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: WAIT02 + m_Speed: 1 + m_CycleOffset: 0 + m_Transitions: [] + m_StateMachineBehaviours: [] + m_Position: {x: 50, y: 50, z: 0} + m_IKOnFeet: 1 + m_WriteDefaultValues: 1 + m_Mirror: 0 + m_SpeedParameterActive: 0 + m_MirrorParameterActive: 0 + m_CycleOffsetParameterActive: 0 + m_TimeParameterActive: 0 + m_Motion: {fileID: 7400000, guid: 2a7cc8d66d3c2fc46a54cbf3d95e3b2d, type: 2} + m_Tag: + m_SpeedParameter: + m_MirrorParameter: + m_CycleOffsetParameter: + m_TimeParameter: diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/SD_UnityChan.controller.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/SD_UnityChan.controller.meta new file mode 100644 index 00000000..b1a50035 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/SD_UnityChan.controller.meta @@ -0,0 +1,15 @@ +fileFormatVersion: 2 +guid: 4ba06a656e1b0f94f996f86d809f5362 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 9100000 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/SD_UnityChan.controller + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Textures.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Textures.meta new file mode 100644 index 00000000..122137e3 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Textures.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: a8ab178aa3b1f574c95414d151171d2c +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Textures/body_sum.png b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Textures/body_sum.png new file mode 100644 index 00000000..77d344da --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Textures/body_sum.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ed4b4f7765ea8e9dbde76eef051ff7c9c1e0cd4c263e76a1532e8be77f181d27 +size 217430 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Textures/body_sum.png.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Textures/body_sum.png.meta new file mode 100644 index 00000000..6593d530 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Textures/body_sum.png.meta @@ -0,0 +1,142 @@ +fileFormatVersion: 2 +guid: 27570a5ee19caed4d9a04e5b88b3fb55 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 12 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMasterTextureLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + cookieLightType: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Server + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Android + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Textures/body_sum.png + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Textures/body_win.png b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Textures/body_win.png new file mode 100644 index 00000000..eab1d0be --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Textures/body_win.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:65c3797b70c6d0109d2457811e305c2753fba7ddd4298cc7bbc70409cfae543b +size 209966 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Textures/body_win.png.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Textures/body_win.png.meta new file mode 100644 index 00000000..07cc09bc --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Textures/body_win.png.meta @@ -0,0 +1,142 @@ +fileFormatVersion: 2 +guid: 6e7b3359dea6deb4591905e4c01daaaa +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 12 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMasterTextureLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + cookieLightType: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Server + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Android + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Textures/body_win.png + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Textures/misaki_head.png b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Textures/misaki_head.png new file mode 100644 index 00000000..f592edd7 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Textures/misaki_head.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f3283df0153df1c612a03f707570414d59549ed9db2edc218f7953133e68d3ba +size 214354 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Textures/misaki_head.png.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Textures/misaki_head.png.meta new file mode 100644 index 00000000..5443b7f6 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Textures/misaki_head.png.meta @@ -0,0 +1,142 @@ +fileFormatVersion: 2 +guid: f3b3d2d3302bfcd429625b8601f356ae +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 12 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMasterTextureLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + cookieLightType: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Server + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Android + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Textures/misaki_head.png + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Textures/utc_all2.png b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Textures/utc_all2.png new file mode 100644 index 00000000..9bc3901a --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Textures/utc_all2.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b01c21a0e020d09b752499ceaa94e1ae8a5a06a55cf1b113f9ec77d86b824c4b +size 338399 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Textures/utc_all2.png.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Textures/utc_all2.png.meta new file mode 100644 index 00000000..39a3c4e9 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Textures/utc_all2.png.meta @@ -0,0 +1,142 @@ +fileFormatVersion: 2 +guid: e3db91f76893de24ca17abe2afcd3672 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 12 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMasterTextureLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + cookieLightType: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Server + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Android + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Textures/utc_all2.png + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Textures/yuko_head.png b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Textures/yuko_head.png new file mode 100644 index 00000000..f2b52086 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Textures/yuko_head.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b0eeeacc934ffc4667276f4eb0e50b84388da940b0c3562ee180f79aa85becc8 +size 211031 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Textures/yuko_head.png.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Textures/yuko_head.png.meta new file mode 100644 index 00000000..c616c752 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Textures/yuko_head.png.meta @@ -0,0 +1,142 @@ +fileFormatVersion: 2 +guid: 683728d077857944cbe122f32302a197 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 12 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMasterTextureLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + cookieLightType: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Server + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Android + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Textures/yuko_head.png + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Utc_sum_humanoid (Body).prefab b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Utc_sum_humanoid (Body).prefab new file mode 100644 index 00000000..2e175432 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Utc_sum_humanoid (Body).prefab @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:65425706988a58d5797e6383be3c3c3f073e26decefa6e16acd3474a16477045 +size 230271 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Utc_sum_humanoid (Body).prefab.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Utc_sum_humanoid (Body).prefab.meta new file mode 100644 index 00000000..0a8aeea7 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Utc_sum_humanoid (Body).prefab.meta @@ -0,0 +1,15 @@ +fileFormatVersion: 2 +guid: f7b297d5cbbb2ae49a5b986f90674b9e +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Utc_sum_humanoid + (Body).prefab + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Utc_sum_humanoid (Hair).prefab b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Utc_sum_humanoid (Hair).prefab new file mode 100644 index 00000000..7f8d6581 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Utc_sum_humanoid (Hair).prefab @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f1d1e9c1b01e53284c9e76f151987e27c12bd36e7fcadb114ea5b7b69a379bd4 +size 185523 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Utc_sum_humanoid (Hair).prefab.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Utc_sum_humanoid (Hair).prefab.meta new file mode 100644 index 00000000..17b29844 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Utc_sum_humanoid (Hair).prefab.meta @@ -0,0 +1,15 @@ +fileFormatVersion: 2 +guid: 0769e110b29a40b4fa617aadaa1e2ea6 +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Utc_sum_humanoid + (Hair).prefab + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Utc_sum_humanoid (Skeleton).prefab b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Utc_sum_humanoid (Skeleton).prefab new file mode 100644 index 00000000..66880eb6 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Utc_sum_humanoid (Skeleton).prefab @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c27f2b3acc151f1a180ec201a41716983749c0a480b80462757faf38b0e0aa95 +size 122005 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Utc_sum_humanoid (Skeleton).prefab.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Utc_sum_humanoid (Skeleton).prefab.meta new file mode 100644 index 00000000..a968327f --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Utc_sum_humanoid (Skeleton).prefab.meta @@ -0,0 +1,15 @@ +fileFormatVersion: 2 +guid: 4e3c7d56d063a904c9dad4bf2ccea5ad +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Utc_sum_humanoid + (Skeleton).prefab + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Utc_sum_humanoid Variant.prefab b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Utc_sum_humanoid Variant.prefab new file mode 100644 index 00000000..4902faf5 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Utc_sum_humanoid Variant.prefab @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:258752548dc2cb31bd7c86b5fd03f00f28c4d57b22c0c09d99520d93fa8b9878 +size 14985 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Utc_sum_humanoid Variant.prefab.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Utc_sum_humanoid Variant.prefab.meta new file mode 100644 index 00000000..25184abe --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Utc_sum_humanoid Variant.prefab.meta @@ -0,0 +1,15 @@ +fileFormatVersion: 2 +guid: 2e7240c8003a64b478effd2a812f4d31 +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Utc_sum_humanoid + Variant.prefab + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Utc_sum_humanoid.fbx b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Utc_sum_humanoid.fbx new file mode 100644 index 00000000..8fe527f7 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Utc_sum_humanoid.fbx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c7f9d4d3d86ae5f7e903ba2c8e1a3a687d105d5d36b91adfd48412136cce31c4 +size 822048 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Utc_sum_humanoid.fbx.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Utc_sum_humanoid.fbx.meta new file mode 100644 index 00000000..1527d1e8 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Utc_sum_humanoid.fbx.meta @@ -0,0 +1,1107 @@ +fileFormatVersion: 2 +guid: 5c78fba67bb448b42b8dc9ef978170e0 +ModelImporter: + serializedVersion: 21300 + internalIDToNameTable: [] + externalObjects: {} + materials: + materialImportMode: 2 + materialName: 0 + materialSearch: 1 + materialLocation: 1 + animations: + legacyGenerateAnimations: 4 + bakeSimulation: 0 + resampleCurves: 1 + optimizeGameObjects: 0 + removeConstantScaleCurves: 1 + motionNodeName: + rigImportErrors: + rigImportWarnings: + animationImportErrors: + animationImportWarnings: + animationRetargetingWarnings: + animationDoRetargetingWarnings: 0 + importAnimatedCustomProperties: 0 + importConstraints: 0 + animationCompression: 3 + animationRotationError: 0.5 + animationPositionError: 0.5 + animationScaleError: 0.5 + animationWrapMode: 0 + extraExposedTransformPaths: [] + extraUserProperties: [] + clipAnimations: [] + isReadable: 1 + meshes: + lODScreenPercentages: [] + globalScale: 1 + meshCompression: 0 + addColliders: 0 + useSRGBMaterialColor: 1 + sortHierarchyByName: 1 + importVisibility: 0 + importBlendShapes: 0 + importCameras: 0 + importLights: 0 + nodeNameCollisionStrategy: 1 + fileIdsGeneration: 2 + swapUVChannels: 0 + generateSecondaryUV: 0 + useFileUnits: 1 + keepQuads: 0 + weldVertices: 1 + bakeAxisConversion: 0 + preserveHierarchy: 0 + skinWeightsMode: 0 + maxBonesPerVertex: 4 + minBoneWeight: 0.001 + optimizeBones: 1 + meshOptimizationFlags: 1 + indexFormat: 0 + secondaryUVAngleDistortion: 8 + secondaryUVAreaDistortion: 15.000001 + secondaryUVHardAngle: 88 + secondaryUVMarginMethod: 1 + secondaryUVMinLightmapResolution: 40 + secondaryUVMinObjectScale: 1 + secondaryUVPackMargin: 4 + useFileScale: 1 + strictVertexDataChecks: 0 + tangentSpace: + normalSmoothAngle: 60 + normalImportMode: 0 + tangentImportMode: 3 + normalCalculationMode: 4 + legacyComputeAllNormalsFromSmoothingGroupsWhenMeshHasBlendShapes: 0 + blendShapeNormalImportMode: 1 + normalSmoothingSource: 0 + referencedClips: [] + importAnimation: 1 + humanDescription: + serializedVersion: 3 + human: + - boneName: Character1_Hips + humanName: Hips + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: Character1_LeftUpLeg + humanName: LeftUpperLeg + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: Character1_RightUpLeg + humanName: RightUpperLeg + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: Character1_LeftLeg + humanName: LeftLowerLeg + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: Character1_RightLeg + humanName: RightLowerLeg + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: Character1_LeftFoot + humanName: LeftFoot + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: Character1_RightFoot + humanName: RightFoot + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: Character1_Spine1 + humanName: Spine + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: Character1_Neck + humanName: Neck + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: Character1_Head + humanName: Head + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: Character1_LeftShoulder + humanName: LeftShoulder + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: Character1_RightShoulder + humanName: RightShoulder + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: Character1_LeftArm + humanName: LeftUpperArm + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: Character1_RightArm + humanName: RightUpperArm + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: Character1_LeftForeArm + humanName: LeftLowerArm + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: Character1_RightForeArm + humanName: RightLowerArm + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: Character1_LeftHand + humanName: LeftHand + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: Character1_RightHand + humanName: RightHand + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: bone_eye_L + humanName: LeftEye + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: bone_eye_R + humanName: RightEye + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: Character1_LeftHandThumb1 + humanName: Left Thumb Proximal + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: Character1_LeftHandThumb2 + humanName: Left Thumb Intermediate + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: Character1_LeftHandThumb3 + humanName: Left Thumb Distal + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: Character1_LeftHandIndex1 + humanName: Left Index Proximal + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: Character1_LeftHandIndex2 + humanName: Left Index Intermediate + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: Character1_LeftHandMiddle1 + humanName: Left Middle Proximal + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: Character1_LeftHandMiddle2 + humanName: Left Middle Intermediate + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: Character1_LeftHandRing1 + humanName: Left Ring Proximal + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: Character1_LeftHandRing2 + humanName: Left Ring Intermediate + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: Character1_LeftHandPinky1 + humanName: Left Little Proximal + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: Character1_LeftHandPinky2 + humanName: Left Little Intermediate + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: Character1_RightHandThumb1 + humanName: Right Thumb Proximal + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: Character1_RightHandThumb2 + humanName: Right Thumb Intermediate + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: Character1_RightHandThumb3 + humanName: Right Thumb Distal + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: Character1_RightHandIndex1 + humanName: Right Index Proximal + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: Character1_RightHandIndex2 + humanName: Right Index Intermediate + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: Character1_RightHandMiddle1 + humanName: Right Middle Proximal + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: Character1_RightHandMiddle2 + humanName: Right Middle Intermediate + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: Character1_RightHandRing1 + humanName: Right Ring Proximal + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: Character1_RightHandRing2 + humanName: Right Ring Intermediate + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: Character1_RightHandPinky1 + humanName: Right Little Proximal + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: Character1_RightHandPinky2 + humanName: Right Little Intermediate + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: Character1_Spine2 + humanName: Chest + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: Character1_LeftToeBase + humanName: LeftToes + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: Character1_RightToeBase + humanName: RightToes + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + skeleton: + - name: Utc_sum_humanoid(Clone) + parentName: + position: {x: 0, y: 0, z: 0} + rotation: {x: 0, y: 0, z: 0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: Character1_Reference + parentName: Utc_sum_humanoid(Clone) + position: {x: -0, y: 0, z: -0.000000002661807} + rotation: {x: -0.7071068, y: 0, z: -0, w: 0.7071068} + scale: {x: 1, y: 1, z: 1} + - name: Character1_Hips + parentName: Character1_Reference + position: {x: -0, y: -0.049120344, z: 0.41803354} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: Character1_Spine + parentName: Character1_Hips + position: {x: -0, y: -0.00017591476, z: 0.001539917} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: Character1_Spine1 + parentName: Character1_Spine + position: {x: -0, y: 0.000000009536743, z: 0.04283531} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: Character1_Spine2 + parentName: Character1_Spine1 + position: {x: -0, y: 0.00015314102, z: 0.041275635} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: Character1_LeftShoulder + parentName: Character1_Spine2 + position: {x: -0.026731491, y: 0.046953294, z: 0.10265426} + rotation: {x: 6.416709e-10, y: -0.14720343, z: -0.012063365, w: 0.9890327} + scale: {x: 0.99999994, y: 1.0000001, z: 1.0000001} + - name: Character1_LeftArm + parentName: Character1_LeftShoulder + position: {x: -0.046947505, y: -0.0003006166, z: 0.0036682128} + rotation: {x: 0.025138553, y: 0.12145908, z: 0.00800092, w: 0.99224585} + scale: {x: 1.0000001, y: 1.0000001, z: 0.9999998} + - name: J_L_Arm_00_tw + parentName: Character1_LeftArm + position: {x: 0.00061920163, y: 0.0000003504753, z: 0.000030059813} + rotation: {x: -0.019484477, y: -0.000087756256, z: -0.0000014493895, w: 0.99981016} + scale: {x: 0.99999994, y: 0.9999999, z: 1.0000002} + - name: Character1_LeftForeArm + parentName: Character1_LeftArm + position: {x: -0.11878532, y: 0.000000009536743, z: 0.000000076293944} + rotation: {x: 0.012962691, y: 0.0029668726, z: 0.0336384, w: 0.99934566} + scale: {x: 0.99999994, y: 0.99999994, z: 1.0000002} + - name: Character1_LeftHand + parentName: Character1_LeftForeArm + position: {x: -0.112707324, y: -0.0000000047683715, z: -0.000000038146972} + rotation: {x: -0.025144951, y: 0.0009263517, z: -0.000049031725, w: 0.9996834} + scale: {x: 1.0000001, y: 0.9999999, z: 1.0000001} + - name: Character1_LeftHandRing1 + parentName: Character1_LeftHand + position: {x: -0.049339905, y: 0.008889142, z: 0.0041249082} + rotation: {x: -0.0031778018, y: -0.008010217, z: 0.014246811, w: 0.9998614} + scale: {x: 1, y: 1, z: 0.9999999} + - name: Character1_LeftHandRing2 + parentName: Character1_LeftHandRing1 + position: {x: -0.013061695, y: 0.000000007152557, z: -0.000000038146972} + rotation: {x: -0.005074419, y: -0.01721808, z: -0.011732383, w: 0.99977005} + scale: {x: 0.99999976, y: 0.9999999, z: 0.9999999} + - name: Character1_LeftHandRing3 + parentName: Character1_LeftHandRing2 + position: {x: -0.010001297, y: 0.0000000017881393, z: 0} + rotation: {x: 6.765418e-17, y: -0.000000044703473, z: 0.0000000015133989, w: 1} + scale: {x: 1.0000002, y: 1.0000001, z: 1} + - name: Character1_LeftHandPinky1 + parentName: Character1_LeftHand + position: {x: -0.046355017, y: 0.022602014, z: 0.0009494018} + rotation: {x: 0.0022179454, y: -0.017407462, z: 0.05259034, w: 0.998462} + scale: {x: 1, y: 1.0000001, z: 0.99999994} + - name: Character1_LeftHandPinky2 + parentName: Character1_LeftHandPinky1 + position: {x: -0.009598923, y: 0.000000007152557, z: 0.000000076293944} + rotation: {x: -0.0041052187, y: -0.02118038, z: -0.00477994, w: 0.99975586} + scale: {x: 1, y: 0.9999999, z: 0.99999994} + - 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} + scale: {x: 0.9999999, y: 1, z: 0.99999994} + - name: Character1_LeftHandIndex1 + parentName: Character1_LeftHand + position: {x: -0.046978243, y: -0.022182073, z: 0.0025979613} + rotation: {x: 0.0048259627, y: -0.018998887, z: 0.045703307, w: 0.99876267} + scale: {x: 0.99999994, y: 1.0000001, z: 1} + - name: Character1_LeftHandIndex2 + parentName: Character1_LeftHandIndex1 + position: {x: -0.014227028, y: -0.00000000834465, z: 0.000000076293944} + rotation: {x: 0.0058518304, y: 0.04137672, z: 0.0068952497, w: 0.9991027} + scale: {x: 0.9999998, y: 0.9999998, z: 0.99999964} + - 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} + scale: {x: 1.0000004, y: 0.9999999, z: 1.0000004} + - name: Character1_LeftHandThumb1 + parentName: Character1_LeftHand + position: {x: -0.016437054, y: -0.01568381, z: -0.017473105} + rotation: {x: 0.6827791, y: 0.28976816, z: 0.23807746, w: 0.6270297} + scale: {x: 0.9999999, y: 0.9999999, z: 1} + - name: Character1_LeftHandThumb2 + parentName: Character1_LeftHandThumb1 + position: {x: -0.017500991, y: 0, z: -0.000000076293944} + rotation: {x: -0.007327673, y: -0.020293944, z: 0.030798841, w: 0.99929273} + scale: {x: 1, y: 0.9999998, z: 0.99999994} + - name: Character1_LeftHandThumb3 + parentName: Character1_LeftHandThumb2 + position: {x: -0.010315971, y: 0, z: 0.00000007152557} + rotation: {x: -0.01386693, y: -0.019060507, z: -0.00015807952, w: 0.9997222} + scale: {x: 0.99999994, y: 0.9999999, z: 1} + - 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} + scale: {x: 1.0000001, y: 0.99999946, z: 0.9999998} + - name: Character1_LeftHandMiddle1 + parentName: Character1_LeftHand + position: {x: -0.05140888, y: -0.0063463617, z: 0.006106071} + rotation: {x: 0.0023525557, y: -0.018158944, z: 0.040574767, w: 0.9990088} + scale: {x: 1, y: 1.0000001, z: 0.99999976} + - name: Character1_LeftHandMiddle2 + parentName: Character1_LeftHandMiddle1 + position: {x: -0.016781254, y: 0.000000019073486, z: 0} + rotation: {x: -0.0038751021, y: 0.017281516, z: -0.010274473, w: 0.9997904} + scale: {x: 1.0000002, y: 1, z: 1.0000001} + - 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} + scale: {x: 1, y: 1.0000001, z: 0.99999994} + - name: J_L_Elbow + parentName: Character1_LeftForeArm + position: {x: 0.00022022247, y: 0.0046890355, z: -0.00008010864} + rotation: {x: -0.006511218, y: -0.0007156488, z: -0.017952144, w: 0.9998174} + scale: {x: 1.0000001, y: 0.99999964, z: 0.9999998} + - name: J_L_ForeArm_00_tw + parentName: Character1_LeftForeArm + position: {x: -0.10891037, y: 0.00009298801, z: -0.00038040162} + rotation: {x: -0.012573468, y: 0.00046314506, z: -0.00002451689, w: 0.99992085} + scale: {x: 1.0000002, y: 0.9999999, z: 1} + - name: Character1_Neck + parentName: Character1_Spine2 + position: {x: -0, y: 0.047267172, z: 0.1330844} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: Character1_Head + parentName: Character1_Neck + position: {x: 2.5015806e-10, y: -0.00804217, z: 0.030468559} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: utc_face + parentName: Character1_Head + position: {x: -0, y: 0.009918099, z: -0.6672374} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: J_L_HairSide2_00 + parentName: Character1_Head + position: {x: -0.13977991, y: -0.032653578, z: 0.14276138} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: J_L_HairSide2_01 + parentName: J_L_HairSide2_00 + position: {x: -0, y: 0, z: -0.07184112} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: J_L_HairTail_00 + parentName: Character1_Head + position: {x: -0.08453446, y: 0.12091128, z: 0.07472458} + rotation: {x: 0.27495223, y: 0.14915642, z: 0.13304274, w: 0.94045377} + scale: {x: 1.0000001, y: 1, z: 1} + - 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} + 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} + 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} + scale: {x: 1, y: 1, z: 1} + - name: J_L_HeadRibbon_00 + parentName: Character1_Head + position: {x: -0.079515405, y: -0.068754226, z: 0.3136406} + rotation: {x: -0.2504739, y: -0.2833735, z: -0.049994256, w: 0.9243716} + scale: {x: 0.99999994, y: 0.99999964, z: 0.99999976} + - name: J_L_HeadRibbon_01 + parentName: J_L_HeadRibbon_00 + position: {x: 0.000000076293944, y: -0.000000114440915, z: 0.2478369} + rotation: {x: -0.8290727, y: -0.12707953, z: 0.09669092, w: 0.5358546} + scale: {x: 1, y: 1.0000001, z: 1.0000004} + - name: J_L_HeadRibbon_02 + parentName: J_L_HeadRibbon_01 + position: {x: -0, y: 0.00000022888183, z: 0.13667938} + rotation: {x: 0.68807155, y: -0.053607468, z: -0.044375025, w: 0.7222982} + scale: {x: 1, y: 0.9999997, z: 0.99999994} + - 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} + scale: {x: 1, y: 0.9999999, z: 1.0000001} + - name: J_R_HairSide2_00 + parentName: Character1_Head + position: {x: 0.13977984, y: -0.032653518, z: 0.14276077} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: J_R_HairSide2_01 + parentName: J_R_HairSide2_00 + position: {x: -0, y: 0, z: -0.07184112} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: J_R_HairTail_00 + parentName: Character1_Head + position: {x: 0.08453457, y: 0.12091121, z: 0.074723355} + rotation: {x: 0.27495188, y: -0.14915672, z: -0.13304274, w: 0.9404538} + scale: {x: 1, y: 1, z: 1} + - 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} + 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} + 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} + scale: {x: 1.0000001, y: 1.0000001, z: 1.0000001} + - name: J_R_HeadRibbon_00 + parentName: Character1_Head + position: {x: 0.0795154, y: -0.06875421, z: 0.31363952} + rotation: {x: -0.25047436, y: 0.28337345, z: 0.04999436, w: 0.92437154} + scale: {x: 0.9999998, y: 1, z: 1} + - name: J_R_HeadRibbon_01 + parentName: J_R_HeadRibbon_00 + position: {x: -0.0000011062622, y: -0.0000010299682, z: 0.24783768} + rotation: {x: -0.82907134, y: 0.12707938, z: -0.096691504, w: 0.5358566} + scale: {x: 1.0000002, y: 1.0000001, z: 0.99999994} + - name: J_R_HeadRibbon_02 + parentName: J_R_HeadRibbon_01 + position: {x: 0.0000008010864, y: 0.000001335144, z: 0.13668053} + rotation: {x: 0.68807024, y: 0.05360729, z: 0.0443758, w: 0.7222994} + scale: {x: 1.0000002, y: 0.9999999, z: 1.0000001} + - name: J_R_HeadRibbon_03 + parentName: J_R_HeadRibbon_02 + position: {x: -0.0000009536743, y: -0.0000010681152, z: 0.16675788} + rotation: {x: 0.0000007748599, y: -0.00000043213427, z: -0.00000084936573, w: 1} + scale: {x: 1.0000001, y: 1, z: 0.9999997} + - name: J_L_HairSide_00 + parentName: Character1_Head + position: {x: -0.07298515, y: -0.0934125, z: 0.27946135} + rotation: {x: 0.032767124, y: -0.43403226, z: -0.092962936, w: 0.89548886} + scale: {x: 1, y: 0.9999999, z: 0.99999994} + - name: J_L_HairSide_01 + parentName: J_L_HairSide_00 + position: {x: -0.124109186, y: 0.000000047683713, z: -0.00000030517577} + rotation: {x: 0.029233634, y: -0.33951724, z: -0.06338306, w: 0.93800646} + scale: {x: 0.99999976, y: 1.0000002, z: 1.0000001} + - 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} + scale: {x: 1.0000002, y: 1, z: 0.9999998} + - name: J_R_HairSide_00 + parentName: Character1_Head + position: {x: 0.072985135, y: -0.09341254, z: 0.27946243} + rotation: {x: 0.03276742, y: 0.4340327, z: 0.09296258, w: 0.8954887} + scale: {x: 1, y: 1, z: 0.99999994} + - name: J_R_HairSide_01 + parentName: J_R_HairSide_00 + position: {x: 0.124110945, y: -0.00000016212464, z: -0.0000010681152} + rotation: {x: 0.029233143, y: 0.33951682, z: 0.063383006, w: 0.9380066} + scale: {x: 1.0000001, y: 1, z: 1.0000002} + - 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} + scale: {x: 0.9999999, y: 1.0000001, z: 0.9999996} + - name: bone_eye_L + parentName: Character1_Head + position: {x: -0.026893321, y: 0.04649828, z: 0.102056116} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: bone_eye_R + parentName: Character1_Head + position: {x: 0.026893293, y: 0.046498314, z: 0.10205597} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: J_L_HairFront_00 + parentName: Character1_Head + position: {x: 0.00047761618, y: -0.102207325, z: 0.28018036} + rotation: {x: -0.032923594, y: 0.012465945, z: 0.003332434, w: 0.99937457} + scale: {x: 1, y: 0.99999994, z: 0.9999999} + - name: J_L_HairFront_01 + parentName: J_L_HairFront_00 + position: {x: 0.0000000023841857, y: 0, z: -0.18115325} + rotation: {x: 0.14653109, y: -0.012764544, z: -0.0018909584, w: 0.9891219} + scale: {x: 0.99999994, y: 1.0000001, z: 1.0000001} + - name: J_R_HairFront_00 + parentName: Character1_Head + position: {x: 0.014399265, y: -0.09940759, z: 0.28018036} + rotation: {x: -0.06683042, y: -0.07431372, z: 0.0030237695, w: 0.9949885} + scale: {x: 1, y: 0.99999994, z: 0.9999999} + - name: J_R_HairFront_01 + parentName: J_R_HairFront_00 + position: {x: -0.000000028610229, y: 0.000000019073486, z: -0.18115318} + rotation: {x: 0.14653113, y: -0.012764582, z: -0.0018909615, w: 0.9891219} + scale: {x: 1, y: 1.0000002, z: 1.0000002} + - name: Collar + parentName: Character1_Spine2 + position: {x: -0, y: 0.08650589, z: 0.12216255} + rotation: {x: 0.000000014901161, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: Ribbon_L + parentName: Character1_Spine2 + position: {x: -0.004597386, y: -0.05966402, z: 0.048371542} + rotation: {x: 0.000000014901161, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: Character1_RightShoulder + parentName: Character1_Spine2 + position: {x: 0.02673147, y: 0.046953294, z: 0.1026548} + rotation: {x: 0.000000017829457, y: 0.14720337, z: 0.012063239, w: 0.9890327} + scale: {x: 1, y: 0.99999994, z: 0.99999994} + - name: Character1_RightArm + parentName: Character1_RightShoulder + position: {x: 0.04694744, y: -0.0003006053, z: 0.0036683274} + rotation: {x: 0.025114838, y: -0.12146138, z: -0.008003939, w: 0.9922461} + scale: {x: 1.0000001, y: 1.0000001, z: 1} + - name: J_R_Arm_00_tw + parentName: Character1_RightArm + position: {x: -0.0006183624, y: 0.00000034093856, z: 0.000029029845} + rotation: {x: -0.019467765, y: 0.0000867438, z: 0.0000013984002, w: 0.9998105} + scale: {x: 0.99999994, y: 0.9999999, z: 1.0000001} + - name: Character1_RightForeArm + parentName: Character1_RightArm + position: {x: 0.11878662, y: -0.0000000023841857, z: -0.0000005340576} + rotation: {x: 0.012962643, y: -0.0029668876, z: -0.03363779, w: 0.9993456} + scale: {x: 1, y: 0.9999999, z: 1} + - name: Character1_RightHand + parentName: Character1_RightForeArm + position: {x: 0.11270626, y: -0.00000007152557, z: -0.0000009536743} + rotation: {x: -0.024933074, y: -0.0007821354, z: 0.000042964955, w: 0.9996888} + scale: {x: 0.99999994, y: 1, z: 1.0000004} + - name: Character1_RightHandThumb1 + parentName: Character1_RightHand + position: {x: 0.016436901, y: -0.015683817, z: -0.017472915} + rotation: {x: 0.68275243, y: -0.28985518, z: -0.23803082, w: 0.6270362} + scale: {x: 0.9999999, y: 1, z: 1.0000001} + - name: Character1_RightHandThumb2 + parentName: Character1_RightHandThumb1 + position: {x: 0.017501583, y: 0.000000114440915, z: -0.00000050544736} + rotation: {x: -0.0073244264, y: 0.020301742, z: -0.030826923, w: 0.9992917} + scale: {x: 1.0000001, y: 0.9999997, z: 0.99999994} + - name: Character1_RightHandThumb3 + parentName: Character1_RightHandThumb2 + position: {x: 0.010316124, y: 0.0000005340576, z: -0.00000010967254} + rotation: {x: -0.01386646, y: 0.019060291, z: 0.00015806762, w: 0.9997222} + scale: {x: 1.0000001, y: 1.0000004, z: 1.0000002} + - name: Character1_RightHandThumb4 + parentName: Character1_RightHandThumb3 + position: {x: 0.012428941, y: -0.0000006866455, z: 0.00000018596648} + rotation: {x: 0.00000030919912, y: 0.000000108033525, z: 0.00000022351746, w: 1} + scale: {x: 0.99999964, y: 0.9999999, z: 0.9999998} + - name: Character1_RightHandPinky1 + parentName: Character1_RightHand + position: {x: 0.046354044, y: 0.022601992, z: 0.00095024105} + rotation: {x: 0.00222267, y: 0.017453691, z: -0.052590676, w: 0.9984611} + scale: {x: 0.9999998, y: 1.0000001, z: 1} + - name: Character1_RightHandPinky2 + parentName: Character1_RightHandPinky1 + position: {x: 0.009599628, y: 0.00000007390976, z: 0.0000011444091} + rotation: {x: -0.0041054687, y: 0.021180103, z: 0.004780198, w: 0.99975586} + scale: {x: 1.0000004, y: 1, z: 1.0000001} + - 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} + scale: {x: 0.99999964, y: 1.0000001, z: 1} + - name: Character1_RightHandRing1 + parentName: Character1_RightHand + position: {x: 0.049340207, y: 0.008889168, z: 0.0041255187} + rotation: {x: -0.0031775192, y: 0.008009321, z: -0.014247004, w: 0.9998615} + scale: {x: 1, y: 1.0000001, z: 0.99999994} + - name: Character1_RightHandRing2 + parentName: Character1_RightHandRing1 + position: {x: 0.013061752, y: 0.000000005960464, z: 0.00000015258789} + rotation: {x: -0.0050746724, y: 0.017218595, z: 0.01173241, w: 0.99977005} + scale: {x: 0.99999994, y: 0.9999998, z: 0.9999997} + - 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} + scale: {x: 1.0000004, y: 1.0000001, z: 1.0000001} + - name: Character1_RightHandIndex1 + parentName: Character1_RightHand + position: {x: 0.046977613, y: -0.02218206, z: 0.002598419} + rotation: {x: 0.0048251827, y: 0.018980803, z: -0.045706283, w: 0.9987629} + scale: {x: 1.0000001, y: 1.0000001, z: 0.99999994} + - name: Character1_RightHandIndex2 + parentName: Character1_RightHandIndex1 + position: {x: 0.014227294, y: 0.00000006437301, z: -0.00000015258789} + rotation: {x: 0.0058521065, y: -0.04137672, z: -0.0068952506, w: 0.9991027} + scale: {x: 0.99999994, y: 0.9999998, z: 0.99999976} + - 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} + scale: {x: 0.9999998, y: 0.9999999, z: 1.0000004} + - name: Character1_RightHandMiddle1 + parentName: Character1_RightHand + position: {x: 0.051409397, y: -0.006346327, z: 0.006106949} + rotation: {x: 0.002352232, y: 0.018152952, z: -0.040573914, w: 0.9990089} + scale: {x: 1.0000001, y: 1.0000002, z: 0.99999994} + - name: Character1_RightHandMiddle2 + parentName: Character1_RightHandMiddle1 + position: {x: 0.01678072, y: -0.000000042915342, z: 0.000000076293944} + rotation: {x: -0.0038748826, y: -0.017280553, z: 0.010274474, w: 0.9997904} + scale: {x: 0.9999999, y: 0.99999994, z: 1.0000001} + - 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} + scale: {x: 1.0000001, y: 1, z: 0.9999999} + - name: J_R_ForeArm_00_tw + parentName: Character1_RightForeArm + position: {x: 0.1089093, y: 0.00009293079, z: -0.00038059233} + rotation: {x: -0.012467529, y: -0.0003910812, z: 0.000021479957, w: 0.9999222} + scale: {x: 0.9999999, y: 1, z: 1.0000004} + - name: J_R_Elbow + parentName: Character1_RightForeArm + position: {x: -0.00022066115, y: 0.0046890113, z: -0.000079879756} + rotation: {x: -0.0065112305, y: 0.00071536575, z: 0.017952092, w: 0.9998174} + scale: {x: 1.0000001, y: 1.0000001, z: 1.0000005} + - name: Ribbon_R + parentName: Character1_Spine2 + position: {x: 0.00459739, y: -0.059663896, z: 0.04837158} + rotation: {x: 0.000000014901184, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: Skirt11_L + parentName: Character1_Hips + position: {x: -0.08134019, y: -0.07278677, z: 0.017924575} + rotation: {x: -0.08120375, y: 0.06756295, z: -0.00025305356, w: 0.9944049} + scale: {x: 1, y: 1, z: 1} + - name: Skirt12_L + parentName: Skirt11_L + position: {x: -0, y: 0, z: -0.06362396} + rotation: {x: 0, y: 0.000000007450581, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: Skirt13_L + parentName: Skirt12_L + position: {x: -0, y: 0, z: -0.071057506} + rotation: {x: 0, y: 0.000000007450581, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: Skirt11_R + parentName: Character1_Hips + position: {x: 0.081340194, y: -0.07278665, z: 0.017924422} + rotation: {x: -0.08120376, y: -0.06756316, z: 0.00025289616, w: 0.9944049} + scale: {x: 1, y: 1, z: 1} + - name: Skirt12_R + parentName: Skirt11_R + position: {x: -0.000000019073486, y: -0.00000020980835, z: -0.06362419} + rotation: {x: 0.00000006705523, y: -0.000000014901163, z: 9.992008e-16, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: Skirt13_R + parentName: Skirt12_R + position: {x: -0.000000019073486, y: 0.000000057220458, z: -0.07105742} + rotation: {x: -0.000000007450581, y: -0.000000014901163, z: 9.313225e-10, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: Skirt20_L + parentName: Character1_Hips + position: {x: -0.11579351, y: 0.002001705, z: 0.025276184} + rotation: {x: 0, y: 0.2754431, z: -0, w: 0.96131736} + scale: {x: 1, y: 1, z: 1} + - name: Skirt21_L + parentName: Skirt20_L + position: {x: -0.000000038146972, y: 0, z: -0.07196762} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: Skirt22_L + parentName: Skirt21_L + position: {x: 0.000000038146972, y: 0, z: -0.079026185} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: Skirt30_L + parentName: Character1_Hips + position: {x: -0.068905, y: 0.06840348, z: 0.025949707} + rotation: {x: 0.16488287, y: 0.07006175, z: -0.008561788, w: 0.9837844} + scale: {x: 1.0000001, y: 0.9999999, z: 0.99999994} + - name: Skirt31_L + parentName: Skirt30_L + position: {x: -0, y: 0, z: -0.06441368} + rotation: {x: 0, y: -0.0000000074505815, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: Skirt32_L + parentName: Skirt31_L + position: {x: -0, y: 0, z: -0.070049495} + rotation: {x: 0, y: -0.0000000074505815, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: Skirt30_R + parentName: Character1_Hips + position: {x: 0.068904996, y: 0.06840344, z: 0.025949402} + rotation: {x: 0.16488269, y: -0.07006178, z: 0.008561828, w: 0.98378444} + scale: {x: 1, y: 1, z: 1} + - name: Skirt31_R + parentName: Skirt30_R + position: {x: 0.000000038146972, y: 0.00000020980835, z: -0.06441322} + rotation: {x: 0.000000014901163, y: -5.551116e-17, z: -0.0000000037252903, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: Skirt32_R + parentName: Skirt31_R + position: {x: 0.000000057220458, y: 0.000000047683713, z: -0.07004946} + rotation: {x: 0.000000014901163, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: Skirt20_R + parentName: Character1_Hips + position: {x: 0.115793996, y: 0.0020017338, z: 0.02527649} + rotation: {x: 0, y: -0.27544278, z: -0, w: 0.9613175} + scale: {x: 1, y: 1, z: 1} + - name: Skirt21_R + parentName: Skirt20_R + position: {x: -0.00000057220456, y: 0, z: -0.071967945} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: Skirt22_R + parentName: Skirt21_R + position: {x: 0.000000038146972, y: 0, z: -0.0790262} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: Character1_LeftUpLeg + parentName: Character1_Hips + position: {x: -0.09838927, y: 0.0002046585, z: -0.06464721} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: Character1_LeftLeg + parentName: Character1_LeftUpLeg + position: {x: -0, y: 0.021834202, z: -0.15186352} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: Character1_LeftFoot + parentName: Character1_LeftLeg + position: {x: -0, y: 0.03391635, z: -0.16433224} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: Character1_LeftToeBase + parentName: Character1_LeftFoot + position: {x: -0.00009206772, y: -0.044022497, z: -0.041161656} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: J_L_knee + parentName: Character1_LeftLeg + position: {x: -0, y: 0.00028729916, z: -0.0016981125} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: Character1_RightUpLeg + parentName: Character1_Hips + position: {x: 0.09838916, y: 0.0002045536, z: -0.06464706} + rotation: {x: 0.0000000050956612, y: -0.00002997581, z: 0.00016999245, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: Character1_RightLeg + parentName: Character1_RightUpLeg + position: {x: -0, y: 0.02183431, z: -0.1518638} + rotation: {x: 8.881784e-16, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: Character1_RightFoot + parentName: Character1_RightLeg + position: {x: -0, y: 0.033916343, z: -0.16433214} + rotation: {x: -0.00000000509566, y: 0.000029975812, z: -0.00016999245, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: Character1_RightToeBase + parentName: Character1_RightFoot + position: {x: 0.00009202957, y: -0.044022463, z: -0.041161664} + rotation: {x: 0, y: 0, z: 6.1098625e-13, w: 1} + scale: {x: 1, y: 1, z: 1} + - 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} + scale: {x: 1, y: 1, z: 1} + - name: utc_head + parentName: Utc_sum_humanoid(Clone) + position: {x: -0, y: 0, z: 0} + rotation: {x: -0.7071068, y: 0, z: -0, w: 0.7071068} + scale: {x: 1, y: 1, z: 1} + - name: utc_Fhair + parentName: Utc_sum_humanoid(Clone) + position: {x: -0, y: 0, z: 0} + rotation: {x: -0.7071068, y: 0, z: -0, w: 0.7071068} + scale: {x: 1, y: 1, z: 1} + - name: utc_eye + parentName: Utc_sum_humanoid(Clone) + position: {x: -0, y: 0, z: 0} + rotation: {x: -0.7071068, y: 0, z: -0, w: 0.7071068} + scale: {x: 1, y: 1, z: 1} + - name: utc_Fhair2 + parentName: Utc_sum_humanoid(Clone) + position: {x: -0, y: 0, z: 0} + rotation: {x: -0.7071068, y: 0, z: -0, w: 0.7071068} + scale: {x: 1, y: 1, z: 1} + - name: _body_summer + parentName: Utc_sum_humanoid(Clone) + position: {x: -0, y: 0, z: 0} + rotation: {x: -0.7071068, y: 0, z: -0, w: 0.7071068} + scale: {x: 1, y: 1, z: 1} + armTwist: 0.5 + foreArmTwist: 0.5 + upperLegTwist: 0.5 + legTwist: 0.5 + armStretch: 0.05 + legStretch: 0.05 + feetSpacing: 0 + globalScale: 1 + rootMotionBoneName: + hasTranslationDoF: 0 + hasExtraRoot: 1 + skeletonHasParents: 1 + lastHumanDescriptionAvatarSource: {instanceID: 0} + autoGenerateAvatarMappingIfUnspecified: 1 + animationType: 3 + humanoidOversampling: 1 + avatarSetup: 1 + addHumanoidExtraRootOnlyWhenUsingAvatar: 1 + remapMaterialsIfMaterialImportModeIsNone: 0 + additionalBone: 0 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Utc_sum_humanoid.fbx + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0.meta new file mode 100644 index 00000000..0299acde --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 47c03d36119db17499adc298abd98858 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/English.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/English.meta new file mode 100644 index 00000000..1932952b --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/English.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 8c8a0c5fda6952146b147b03cd881920 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/English/01Unity-Chan License Terms and Condition_EN_UCL2.0.pdf b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/English/01Unity-Chan License Terms and Condition_EN_UCL2.0.pdf new file mode 100644 index 00000000..ba976875 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/English/01Unity-Chan License Terms and Condition_EN_UCL2.0.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cddf37e09b03fefb43f659932b6035078cadc2b38c52ea08f3b15fcd25b929e6 +size 80324 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/English/01Unity-Chan License Terms and Condition_EN_UCL2.0.pdf.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/English/01Unity-Chan License Terms and Condition_EN_UCL2.0.pdf.meta new file mode 100644 index 00000000..f8d2dca7 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/English/01Unity-Chan License Terms and Condition_EN_UCL2.0.pdf.meta @@ -0,0 +1,15 @@ +fileFormatVersion: 2 +guid: e1a0622442b06c949aaca91bb8151c74 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/English/01Unity-Chan + License Terms and Condition_EN_UCL2.0.pdf + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/English/02Unity-Chan License Terms and Condition_Summary_EN_UCL2.0.pdf b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/English/02Unity-Chan License Terms and Condition_Summary_EN_UCL2.0.pdf new file mode 100644 index 00000000..3506e235 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/English/02Unity-Chan License Terms and Condition_Summary_EN_UCL2.0.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4d36e4b0b89737f22153f66dda501c589f0fe4c9e0071146059f129563bb77f5 +size 136809 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/English/02Unity-Chan License Terms and Condition_Summary_EN_UCL2.0.pdf.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/English/02Unity-Chan License Terms and Condition_Summary_EN_UCL2.0.pdf.meta new file mode 100644 index 00000000..44d0c157 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/English/02Unity-Chan License Terms and Condition_Summary_EN_UCL2.0.pdf.meta @@ -0,0 +1,15 @@ +fileFormatVersion: 2 +guid: e534652dc977c9848b6c4c54586507c4 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/English/02Unity-Chan + License Terms and Condition_Summary_EN_UCL2.0.pdf + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/English/03Indication of License_EN_UCL2.0.pdf b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/English/03Indication of License_EN_UCL2.0.pdf new file mode 100644 index 00000000..36cc6296 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/English/03Indication of License_EN_UCL2.0.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8979542ada869149067e2452c964931f56a34929659b5a2ac7c42e40f09226ac +size 138089 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/English/03Indication of License_EN_UCL2.0.pdf.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/English/03Indication of License_EN_UCL2.0.pdf.meta new file mode 100644 index 00000000..9225482e --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/English/03Indication of License_EN_UCL2.0.pdf.meta @@ -0,0 +1,15 @@ +fileFormatVersion: 2 +guid: a6382741dc950ac40a8170412014620a +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/English/03Indication + of License_EN_UCL2.0.pdf + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/Japanese.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/Japanese.meta new file mode 100644 index 00000000..94a6656a --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/Japanese.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: a8dc8df451dda2c47ba136a8f8c09e11 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/Japanese/01Unity-Chan License Terms and Condition_JP_UCL2.0.pdf b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/Japanese/01Unity-Chan License Terms and Condition_JP_UCL2.0.pdf new file mode 100644 index 00000000..8e207e09 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/Japanese/01Unity-Chan License Terms and Condition_JP_UCL2.0.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8f0005b9e84c73e803f7d32b216d5318970fd32e8545183a9b13c9afb4303d8e +size 130507 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/Japanese/01Unity-Chan License Terms and Condition_JP_UCL2.0.pdf.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/Japanese/01Unity-Chan License Terms and Condition_JP_UCL2.0.pdf.meta new file mode 100644 index 00000000..e31c0e48 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/Japanese/01Unity-Chan License Terms and Condition_JP_UCL2.0.pdf.meta @@ -0,0 +1,15 @@ +fileFormatVersion: 2 +guid: 8dc3224c2a02525478fb6fe5cc1a4b56 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/Japanese/01Unity-Chan + License Terms and Condition_JP_UCL2.0.pdf + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/Japanese/02Unity-Chan License Terms and Condition_Summary_JP_UCL2.0.pdf b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/Japanese/02Unity-Chan License Terms and Condition_Summary_JP_UCL2.0.pdf new file mode 100644 index 00000000..8fcf5e6f --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/Japanese/02Unity-Chan License Terms and Condition_Summary_JP_UCL2.0.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b384fd009be74be506bd44c7c9cde335cdab775ed41641011b4cf827b4746ef3 +size 162142 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/Japanese/02Unity-Chan License Terms and Condition_Summary_JP_UCL2.0.pdf.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/Japanese/02Unity-Chan License Terms and Condition_Summary_JP_UCL2.0.pdf.meta new file mode 100644 index 00000000..001bb8ed --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/Japanese/02Unity-Chan License Terms and Condition_Summary_JP_UCL2.0.pdf.meta @@ -0,0 +1,15 @@ +fileFormatVersion: 2 +guid: 5cd0c7ea8d999e94e916266891ae8e1b +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/Japanese/02Unity-Chan + License Terms and Condition_Summary_JP_UCL2.0.pdf + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/Japanese/03Indication of License_JP_UCL2.0.pdf b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/Japanese/03Indication of License_JP_UCL2.0.pdf new file mode 100644 index 00000000..2d3e9d81 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/Japanese/03Indication of License_JP_UCL2.0.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:aae2bb2fb1560166e6bd0dc3655844d6f9c19012dd62a8aea2cc67372ac81703 +size 139414 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/Japanese/03Indication of License_JP_UCL2.0.pdf.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/Japanese/03Indication of License_JP_UCL2.0.pdf.meta new file mode 100644 index 00000000..74b3925d --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/Japanese/03Indication of License_JP_UCL2.0.pdf.meta @@ -0,0 +1,15 @@ +fileFormatVersion: 2 +guid: e6d5edea9833d1f4d8b0ee91b8c75fca +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/Japanese/03Indication + of License_JP_UCL2.0.pdf + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo.meta new file mode 100644 index 00000000..43c02ac9 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 6312541dd95342f499d6cc3ab68a2a19 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/LUUL_LOGO_rules02.ai b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/LUUL_LOGO_rules02.ai new file mode 100644 index 00000000..7cebee47 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/LUUL_LOGO_rules02.ai @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:29e3496972cbf7427bb73f5aa29ad33ac76e145eab947f969f606ab2f0e5b1d3 +size 203502 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/LUUL_LOGO_rules02.ai.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/LUUL_LOGO_rules02.ai.meta new file mode 100644 index 00000000..561791a5 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/LUUL_LOGO_rules02.ai.meta @@ -0,0 +1,15 @@ +fileFormatVersion: 2 +guid: 1617c1395163ac64bae61a3ff56a3bcf +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License + Logo/LUUL_LOGO_rules02.ai + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/LUUL_LOGO_rules02.psd b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/LUUL_LOGO_rules02.psd new file mode 100644 index 00000000..87a5f3dc --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/LUUL_LOGO_rules02.psd @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:79bf93338777bcd70b3fe49367c8676626b651c300c98b7188a65ab29e51eced +size 390557 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/LUUL_LOGO_rules02.psd.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/LUUL_LOGO_rules02.psd.meta new file mode 100644 index 00000000..c0abdb4e --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/LUUL_LOGO_rules02.psd.meta @@ -0,0 +1,143 @@ +fileFormatVersion: 2 +guid: 06a4adb20e6561b4a9e89e59f9722b6b +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 12 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMasterTextureLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + cookieLightType: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Server + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Android + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License + Logo/LUUL_LOGO_rules02.psd + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/LUUL_logo-guideline.pdf b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/LUUL_logo-guideline.pdf new file mode 100644 index 00000000..f7ca742f --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/LUUL_logo-guideline.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3ff94c47d633f8b8b13ec34633c90570b014b2a25f32bef79449ebd6c04b24dd +size 2444810 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/LUUL_logo-guideline.pdf.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/LUUL_logo-guideline.pdf.meta new file mode 100644 index 00000000..f29705b6 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/LUUL_logo-guideline.pdf.meta @@ -0,0 +1,15 @@ +fileFormatVersion: 2 +guid: 12e168b41c4c4aa4f814e627039cf805 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License + Logo/LUUL_logo-guideline.pdf + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/LUUL_logo-guideline_en.pdf b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/LUUL_logo-guideline_en.pdf new file mode 100644 index 00000000..919e4844 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/LUUL_logo-guideline_en.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:670599e9287b3b325ae177e7b82f4d1a792dd239fb065c27acbb430222f96281 +size 3229950 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/LUUL_logo-guideline_en.pdf.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/LUUL_logo-guideline_en.pdf.meta new file mode 100644 index 00000000..a5a7c45d --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/LUUL_logo-guideline_en.pdf.meta @@ -0,0 +1,15 @@ +fileFormatVersion: 2 +guid: 8749e0bd2469ebf45b4b27bc3492eca5 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License + Logo/LUUL_logo-guideline_en.pdf + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/Others.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/Others.meta new file mode 100644 index 00000000..2306d963 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/Others.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 503574da3b90e8c49a6727c11d6ab22f +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/Others/jpg.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/Others/jpg.meta new file mode 100644 index 00000000..2371b4cd --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/Others/jpg.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: d829eb4a497a68c49a76e37c06e4ab72 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/Others/jpg/Dark_Silhouette.jpg b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/Others/jpg/Dark_Silhouette.jpg new file mode 100644 index 00000000..98333928 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/Others/jpg/Dark_Silhouette.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9d9dfccc7f5e239ce865ebd4a3b002696536af7ec0b6ad734084047f08a1c32f +size 13704 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/Others/jpg/Dark_Silhouette.jpg.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/Others/jpg/Dark_Silhouette.jpg.meta new file mode 100644 index 00000000..71810ebf --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/Others/jpg/Dark_Silhouette.jpg.meta @@ -0,0 +1,143 @@ +fileFormatVersion: 2 +guid: 497d11b1c639389469a4e171337e4c33 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 12 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMasterTextureLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + cookieLightType: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Server + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Android + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License + Logo/Others/jpg/Dark_Silhouette.jpg + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/Others/jpg/Light_Silhouette.jpg b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/Others/jpg/Light_Silhouette.jpg new file mode 100644 index 00000000..c995e594 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/Others/jpg/Light_Silhouette.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6e512059ffc94c07f8b6ade9ef17ee53308d558819679a9d4e39008d0e802f51 +size 13700 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/Others/jpg/Light_Silhouette.jpg.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/Others/jpg/Light_Silhouette.jpg.meta new file mode 100644 index 00000000..d866c24e --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/Others/jpg/Light_Silhouette.jpg.meta @@ -0,0 +1,143 @@ +fileFormatVersion: 2 +guid: bac27a6732cd46a4bb51a28a3419820b +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 12 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMasterTextureLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + cookieLightType: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Server + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Android + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License + Logo/Others/jpg/Light_Silhouette.jpg + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/Others/png.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/Others/png.meta new file mode 100644 index 00000000..6ba53431 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/Others/png.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: cf8a994e76d5df04e978a66a2a1c945a +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/Others/png/Dark_Silhouette.png b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/Others/png/Dark_Silhouette.png new file mode 100644 index 00000000..72dcbee6 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/Others/png/Dark_Silhouette.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a6553d5a928b34067f40a7775218c88c26d61df750974c165cac873599697b80 +size 9251 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/Others/png/Dark_Silhouette.png.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/Others/png/Dark_Silhouette.png.meta new file mode 100644 index 00000000..fcba3027 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/Others/png/Dark_Silhouette.png.meta @@ -0,0 +1,143 @@ +fileFormatVersion: 2 +guid: 6b5e4d02329861a47a0dc02fddd443fc +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 12 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMasterTextureLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + cookieLightType: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Server + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Android + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License + Logo/Others/png/Dark_Silhouette.png + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/Others/png/Light_Frame.png b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/Others/png/Light_Frame.png new file mode 100644 index 00000000..a60cca31 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/Others/png/Light_Frame.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e347a9f3d48a61a42a2b1d24da81cfe604a0595187c128f930ba1bc43618768d +size 12620 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/Others/png/Light_Frame.png.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/Others/png/Light_Frame.png.meta new file mode 100644 index 00000000..67bd29a1 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/Others/png/Light_Frame.png.meta @@ -0,0 +1,143 @@ +fileFormatVersion: 2 +guid: 76d945996802d79408a971d78e8b6769 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 12 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMasterTextureLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + cookieLightType: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Server + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Android + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License + Logo/Others/png/Light_Frame.png + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/Others/png/Light_Silhouette.png b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/Others/png/Light_Silhouette.png new file mode 100644 index 00000000..f2b3a630 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/Others/png/Light_Silhouette.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e8d36c6c34c264a14a4bef08580b363ef0b2a12f0c69d28f9081ca065629e00c +size 9102 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/Others/png/Light_Silhouette.png.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/Others/png/Light_Silhouette.png.meta new file mode 100644 index 00000000..eefc89f8 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/Others/png/Light_Silhouette.png.meta @@ -0,0 +1,143 @@ +fileFormatVersion: 2 +guid: 86eefddfd681aba4f8b1381d34f2d086 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 12 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMasterTextureLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + cookieLightType: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Server + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Android + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License + Logo/Others/png/Light_Silhouette.png + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/Others/svg.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/Others/svg.meta new file mode 100644 index 00000000..13da16f6 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/Others/svg.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 28c4ee9e1f450cb4689aa7de7a021340 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/Others/svg/Dark_Silhouette.svg b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/Others/svg/Dark_Silhouette.svg new file mode 100644 index 00000000..e6f2807c --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/Others/svg/Dark_Silhouette.svg @@ -0,0 +1,163 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/Others/svg/Dark_Silhouette.svg.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/Others/svg/Dark_Silhouette.svg.meta new file mode 100644 index 00000000..131fc157 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/Others/svg/Dark_Silhouette.svg.meta @@ -0,0 +1,61 @@ +fileFormatVersion: 2 +guid: 149180168381eb44d947d82ed4e54d91 +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License + Logo/Others/svg/Dark_Silhouette.svg + uploadId: 893596 +ScriptedImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 2 + userData: + assetBundleName: + assetBundleVariant: + script: {fileID: 12408, guid: 0000000000000000e000000000000000, type: 0} + svgType: 3 + texturedSpriteMeshType: 0 + svgPixelsPerUnit: 100 + gradientResolution: 64 + alignment: 0 + customPivot: {x: 0, y: 0} + generatePhysicsShape: 0 + viewportOptions: 0 + preserveViewport: 0 + advancedMode: 0 + tessellationMode: 1 + predefinedResolutionIndex: 1 + targetResolution: 1080 + resolutionMultiplier: 1 + stepDistance: 10 + samplingStepDistance: 100 + maxCordDeviationEnabled: 0 + maxCordDeviation: 1 + maxTangentAngleEnabled: 0 + maxTangentAngle: 5 + keepTextureAspectRatio: 1 + textureSize: 256 + textureWidth: 256 + textureHeight: 256 + wrapMode: 0 + filterMode: 1 + sampleCount: 4 + preserveSVGImageAspect: 0 + useSVGPixelsPerUnit: 0 + spriteData: + TessellationDetail: 0 + SpriteName: + SpritePivot: {x: 0, y: 0} + SpriteAlignment: 0 + SpriteBorder: {x: 0, y: 0, z: 0, w: 0} + SpriteRect: + serializedVersion: 2 + x: 0 + y: 0 + width: 0 + height: 0 + SpriteID: + PhysicsOutlines: [] diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/Others/svg/Light_Frame.svg b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/Others/svg/Light_Frame.svg new file mode 100644 index 00000000..51aa48f9 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/Others/svg/Light_Frame.svg @@ -0,0 +1,153 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/Others/svg/Light_Frame.svg.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/Others/svg/Light_Frame.svg.meta new file mode 100644 index 00000000..2212d309 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/Others/svg/Light_Frame.svg.meta @@ -0,0 +1,61 @@ +fileFormatVersion: 2 +guid: 62e7de5702ca2f34bbe1af809b3ba3c4 +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License + Logo/Others/svg/Light_Frame.svg + uploadId: 893596 +ScriptedImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 2 + userData: + assetBundleName: + assetBundleVariant: + script: {fileID: 12408, guid: 0000000000000000e000000000000000, type: 0} + svgType: 3 + texturedSpriteMeshType: 0 + svgPixelsPerUnit: 100 + gradientResolution: 64 + alignment: 0 + customPivot: {x: 0, y: 0} + generatePhysicsShape: 0 + viewportOptions: 0 + preserveViewport: 0 + advancedMode: 0 + tessellationMode: 1 + predefinedResolutionIndex: 1 + targetResolution: 1080 + resolutionMultiplier: 1 + stepDistance: 10 + samplingStepDistance: 100 + maxCordDeviationEnabled: 0 + maxCordDeviation: 1 + maxTangentAngleEnabled: 0 + maxTangentAngle: 5 + keepTextureAspectRatio: 1 + textureSize: 256 + textureWidth: 256 + textureHeight: 256 + wrapMode: 0 + filterMode: 1 + sampleCount: 4 + preserveSVGImageAspect: 0 + useSVGPixelsPerUnit: 0 + spriteData: + TessellationDetail: 0 + SpriteName: + SpritePivot: {x: 0, y: 0} + SpriteAlignment: 0 + SpriteBorder: {x: 0, y: 0, z: 0, w: 0} + SpriteRect: + serializedVersion: 2 + x: 0 + y: 0 + width: 0 + height: 0 + SpriteID: + PhysicsOutlines: [] diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/Others/svg/Light_Silhouette.svg b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/Others/svg/Light_Silhouette.svg new file mode 100644 index 00000000..7a4e5df1 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/Others/svg/Light_Silhouette.svg @@ -0,0 +1,145 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/Others/svg/Light_Silhouette.svg.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/Others/svg/Light_Silhouette.svg.meta new file mode 100644 index 00000000..9822f9ac --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/Others/svg/Light_Silhouette.svg.meta @@ -0,0 +1,61 @@ +fileFormatVersion: 2 +guid: cfdb094a636fe3d4499b2563b44b02cb +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License + Logo/Others/svg/Light_Silhouette.svg + uploadId: 893596 +ScriptedImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 2 + userData: + assetBundleName: + assetBundleVariant: + script: {fileID: 12408, guid: 0000000000000000e000000000000000, type: 0} + svgType: 3 + texturedSpriteMeshType: 0 + svgPixelsPerUnit: 100 + gradientResolution: 64 + alignment: 0 + customPivot: {x: 0, y: 0} + generatePhysicsShape: 0 + viewportOptions: 0 + preserveViewport: 0 + advancedMode: 0 + tessellationMode: 1 + predefinedResolutionIndex: 1 + targetResolution: 1080 + resolutionMultiplier: 1 + stepDistance: 10 + samplingStepDistance: 100 + maxCordDeviationEnabled: 0 + maxCordDeviation: 1 + maxTangentAngleEnabled: 0 + maxTangentAngle: 5 + keepTextureAspectRatio: 1 + textureSize: 256 + textureWidth: 256 + textureHeight: 256 + wrapMode: 0 + filterMode: 1 + sampleCount: 4 + preserveSVGImageAspect: 0 + useSVGPixelsPerUnit: 0 + spriteData: + TessellationDetail: 0 + SpriteName: + SpritePivot: {x: 0, y: 0} + SpriteAlignment: 0 + SpriteBorder: {x: 0, y: 0, z: 0, w: 0} + SpriteRect: + serializedVersion: 2 + x: 0 + y: 0 + width: 0 + height: 0 + SpriteID: + PhysicsOutlines: [] diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/Unity-Chan License.txt b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/Unity-Chan License.txt new file mode 100644 index 00000000..1fbf757b --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/Unity-Chan License.txt @@ -0,0 +1,18 @@ +- ユニティちゃんライセンスについて + +このアセットは、『ユニティちゃんライセンス』(https://unity-chan.com/contents/license_jp/)で提供されています。 +このアセットをご利用される場合は、『キャラクター利用のガイドライン』(https://unity-chan.com/contents/guideline/)も併せてご確認ください。 + + + +- "Unity-Chan" License Notice + +These contents are licensed under the "Unity-Chan" License Terms and Conditions (https://unity-chan.com/contents/license_en/). +You are allowed to use these contents only if you follow the Character Use Guidelines (https://unity-chan.com/contents/guideline_en/) +set by Unity Technologies Japan G.K, for the usage of its characters. + + + +© Unity Technologies Japan/UCL + + diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/Unity-Chan License.txt.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/Unity-Chan License.txt.meta new file mode 100644 index 00000000..d4abe977 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/Unity-Chan License.txt.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: d113a5a2048656542ac2af56b09ec186 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/Unity-Chan License.txt + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA.meta new file mode 100644 index 00000000..f9e34730 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: a80f50620f244964096eade0620fa59e +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Animation.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Animation.meta new file mode 100644 index 00000000..3fa6543c --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Animation.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 5e25e364af1d1754e9b3493961e9cc6f +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Animation/RUN00_F.anim b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Animation/RUN00_F.anim new file mode 100644 index 00000000..6ae33e45 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Animation/RUN00_F.anim @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ec5187d084d6cfaea06084cd27748ae750bbbda84527d5d07b7d53fd676c00aa +size 2721173 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Animation/RUN00_F.anim.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Animation/RUN00_F.anim.meta new file mode 100644 index 00000000..d21ca2d5 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Animation/RUN00_F.anim.meta @@ -0,0 +1,15 @@ +fileFormatVersion: 2 +guid: d57512b99bc2cc84f92c873f858d9714 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 7400000 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Animation/RUN00_F.anim + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Animation/UC01_001_UniteInTheSky -WA-.fbx b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Animation/UC01_001_UniteInTheSky -WA-.fbx new file mode 100644 index 00000000..5335153a --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Animation/UC01_001_UniteInTheSky -WA-.fbx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:587ae56d783c5e7b4e2957853d20f4a0e804c6c22d3e43dd39db52ed1f68ed46 +size 31696400 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Animation/UC01_001_UniteInTheSky -WA-.fbx.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Animation/UC01_001_UniteInTheSky -WA-.fbx.meta new file mode 100644 index 00000000..a7ff7699 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Animation/UC01_001_UniteInTheSky -WA-.fbx.meta @@ -0,0 +1,1149 @@ +fileFormatVersion: 2 +guid: 6f7e0371a1f07ea49b5d6fe4d634ae6c +ModelImporter: + serializedVersion: 21300 + internalIDToNameTable: + - first: + 1: 100000 + second: CH_Chest + - first: + 1: 100002 + second: CH_FingerIn0_L + - first: + 1: 100004 + second: CH_FingerIn0_R + - first: + 1: 100006 + second: CH_FingerIn1_L + - first: + 1: 100008 + second: CH_FingerIn1_R + - first: + 1: 100010 + second: CH_FingerIn2_L + - first: + 1: 100012 + second: CH_FingerIn2_R + - first: + 1: 100014 + second: CH_FingerMid0_L + - first: + 1: 100016 + second: CH_FingerMid0_R + - first: + 1: 100018 + second: CH_FingerMid1_L + - first: + 1: 100020 + second: CH_FingerMid1_R + - first: + 1: 100022 + second: CH_FingerMid2_L + - first: + 1: 100024 + second: CH_FingerMid2_R + - first: + 1: 100026 + second: CH_FingerP0_L + - first: + 1: 100028 + second: CH_FingerP0_R + - first: + 1: 100030 + second: CH_FingerP1_L + - first: + 1: 100032 + second: CH_FingerP1_R + - first: + 1: 100034 + second: CH_FingerP2_L + - first: + 1: 100036 + second: CH_FingerP2_R + - first: + 1: 100038 + second: CH_FingerR0_L + - first: + 1: 100040 + second: CH_FingerR0_R + - first: + 1: 100042 + second: CH_FingerR1_L + - first: + 1: 100044 + second: CH_FingerR1_R + - first: + 1: 100046 + second: CH_FingerR2_L + - first: + 1: 100048 + second: CH_FingerR2_R + - first: + 1: 100050 + second: CH_FingerTh0_L + - first: + 1: 100052 + second: CH_FingerTh0_R + - first: + 1: 100054 + second: CH_FingerTh1_L + - first: + 1: 100056 + second: CH_FingerTh1_R + - first: + 1: 100058 + second: CH_FingerTh2_L + - first: + 1: 100060 + second: CH_FingerTh2_R + - first: + 1: 100062 + second: CH_Foot_L + - first: + 1: 100064 + second: CH_Foot_R + - first: + 1: 100066 + second: CH_For_L + - first: + 1: 100068 + second: CH_For_R + - first: + 1: 100070 + second: CH_Hand_L + - first: + 1: 100072 + second: CH_Hand_R + - first: + 1: 100074 + second: CH_Head + - first: + 1: 100076 + second: CH_Hips + - first: + 1: 100078 + second: CH_Neck + - first: + 1: 100080 + second: CH_Shin_L + - first: + 1: 100082 + second: CH_Shin_R + - first: + 1: 100084 + second: CH_Shou_L + - first: + 1: 100086 + second: CH_Shou_R + - first: + 1: 100088 + second: CH_Spine + - first: + 1: 100090 + second: CH_Thigh_L + - first: + 1: 100092 + second: CH_Thigh_R + - first: + 1: 100094 + second: CH_Uppe_L + - first: + 1: 100096 + second: CH_Uppe_R + - first: + 1: 100098 + second: //RootNode + - first: + 4: 400000 + second: CH_Chest + - first: + 4: 400002 + second: CH_FingerIn0_L + - first: + 4: 400004 + second: CH_FingerIn0_R + - first: + 4: 400006 + second: CH_FingerIn1_L + - first: + 4: 400008 + second: CH_FingerIn1_R + - first: + 4: 400010 + second: CH_FingerIn2_L + - first: + 4: 400012 + second: CH_FingerIn2_R + - first: + 4: 400014 + second: CH_FingerMid0_L + - first: + 4: 400016 + second: CH_FingerMid0_R + - first: + 4: 400018 + second: CH_FingerMid1_L + - first: + 4: 400020 + second: CH_FingerMid1_R + - first: + 4: 400022 + second: CH_FingerMid2_L + - first: + 4: 400024 + second: CH_FingerMid2_R + - first: + 4: 400026 + second: CH_FingerP0_L + - first: + 4: 400028 + second: CH_FingerP0_R + - first: + 4: 400030 + second: CH_FingerP1_L + - first: + 4: 400032 + second: CH_FingerP1_R + - first: + 4: 400034 + second: CH_FingerP2_L + - first: + 4: 400036 + second: CH_FingerP2_R + - first: + 4: 400038 + second: CH_FingerR0_L + - first: + 4: 400040 + second: CH_FingerR0_R + - first: + 4: 400042 + second: CH_FingerR1_L + - first: + 4: 400044 + second: CH_FingerR1_R + - first: + 4: 400046 + second: CH_FingerR2_L + - first: + 4: 400048 + second: CH_FingerR2_R + - first: + 4: 400050 + second: CH_FingerTh0_L + - first: + 4: 400052 + second: CH_FingerTh0_R + - first: + 4: 400054 + second: CH_FingerTh1_L + - first: + 4: 400056 + second: CH_FingerTh1_R + - first: + 4: 400058 + second: CH_FingerTh2_L + - first: + 4: 400060 + second: CH_FingerTh2_R + - first: + 4: 400062 + second: CH_Foot_L + - first: + 4: 400064 + second: CH_Foot_R + - first: + 4: 400066 + second: CH_For_L + - first: + 4: 400068 + second: CH_For_R + - first: + 4: 400070 + second: CH_Hand_L + - first: + 4: 400072 + second: CH_Hand_R + - first: + 4: 400074 + second: CH_Head + - first: + 4: 400076 + second: CH_Hips + - first: + 4: 400078 + second: CH_Neck + - first: + 4: 400080 + second: CH_Shin_L + - first: + 4: 400082 + second: CH_Shin_R + - first: + 4: 400084 + second: CH_Shou_L + - first: + 4: 400086 + second: CH_Shou_R + - first: + 4: 400088 + second: CH_Spine + - first: + 4: 400090 + second: CH_Thigh_L + - first: + 4: 400092 + second: CH_Thigh_R + - first: + 4: 400094 + second: CH_Uppe_L + - first: + 4: 400096 + second: CH_Uppe_R + - first: + 4: 400098 + second: //RootNode + - first: + 74: 7400000 + second: UC01_001_JAK01_003 + - first: + 95: 9500000 + second: //RootNode + externalObjects: {} + materials: + materialImportMode: 1 + materialName: 0 + materialSearch: 1 + materialLocation: 1 + animations: + legacyGenerateAnimations: 4 + bakeSimulation: 0 + resampleCurves: 1 + optimizeGameObjects: 0 + removeConstantScaleCurves: 0 + motionNodeName: + rigImportErrors: + rigImportWarnings: + animationImportErrors: + animationImportWarnings: + animationRetargetingWarnings: + animationDoRetargetingWarnings: 0 + importAnimatedCustomProperties: 0 + importConstraints: 0 + animationCompression: 3 + animationRotationError: 0.5 + animationPositionError: 0.5 + animationScaleError: 0.5 + animationWrapMode: 0 + extraExposedTransformPaths: [] + extraUserProperties: [] + clipAnimations: + - serializedVersion: 16 + name: UC01_001_JAK01_003 + takeName: UC01_001_JAK01_003 + internalID: 0 + firstFrame: 0 + lastFrame: 8628 + wrapMode: 0 + orientationOffsetY: 0 + level: 0 + cycleOffset: 0 + loop: 0 + hasAdditiveReferencePose: 0 + loopTime: 1 + loopBlend: 0 + loopBlendOrientation: 1 + loopBlendPositionY: 1 + loopBlendPositionXZ: 1 + keepOriginalOrientation: 0 + keepOriginalPositionY: 1 + keepOriginalPositionXZ: 0 + heightFromFeet: 0 + mirror: 0 + bodyMask: 01000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000 + curves: [] + events: [] + transformMask: [] + maskType: 3 + maskSource: {instanceID: 0} + additiveReferencePoseFrame: 0 + - serializedVersion: 16 + name: UC01_001_JAK01_003 (short) + takeName: UC01_001_JAK01_003 + internalID: -6150270346426837497 + firstFrame: 904 + lastFrame: 6104 + wrapMode: 0 + orientationOffsetY: 0 + level: 0 + cycleOffset: 0 + loop: 0 + hasAdditiveReferencePose: 0 + loopTime: 1 + loopBlend: 0 + loopBlendOrientation: 1 + loopBlendPositionY: 1 + loopBlendPositionXZ: 0 + keepOriginalOrientation: 0 + keepOriginalPositionY: 1 + keepOriginalPositionXZ: 0 + heightFromFeet: 0 + mirror: 0 + bodyMask: 01000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000 + curves: [] + events: [] + transformMask: [] + maskType: 3 + maskSource: {instanceID: 0} + additiveReferencePoseFrame: 0 + - serializedVersion: 16 + name: UC01_001_INIT_POSE + takeName: UC01_001_JAK01_003 + internalID: 5322403403441133380 + firstFrame: 0 + lastFrame: 33 + wrapMode: 0 + orientationOffsetY: 0 + level: 0 + cycleOffset: 0 + loop: 0 + hasAdditiveReferencePose: 0 + loopTime: 1 + loopBlend: 1 + loopBlendOrientation: 1 + loopBlendPositionY: 1 + loopBlendPositionXZ: 0 + keepOriginalOrientation: 0 + keepOriginalPositionY: 1 + keepOriginalPositionXZ: 0 + heightFromFeet: 0 + mirror: 0 + bodyMask: 01000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000 + curves: [] + events: [] + transformMask: [] + maskType: 3 + maskSource: {instanceID: 0} + additiveReferencePoseFrame: 0 + isReadable: 1 + meshes: + lODScreenPercentages: [] + globalScale: 1 + meshCompression: 0 + addColliders: 0 + useSRGBMaterialColor: 1 + sortHierarchyByName: 1 + importVisibility: 1 + importBlendShapes: 1 + importCameras: 1 + importLights: 1 + nodeNameCollisionStrategy: 0 + fileIdsGeneration: 1 + swapUVChannels: 0 + generateSecondaryUV: 0 + useFileUnits: 1 + keepQuads: 0 + weldVertices: 1 + bakeAxisConversion: 0 + preserveHierarchy: 0 + skinWeightsMode: 0 + maxBonesPerVertex: 4 + minBoneWeight: 0.001 + optimizeBones: 1 + meshOptimizationFlags: -1 + indexFormat: 0 + secondaryUVAngleDistortion: 8 + secondaryUVAreaDistortion: 15.000001 + secondaryUVHardAngle: 88 + secondaryUVMarginMethod: 1 + secondaryUVMinLightmapResolution: 40 + secondaryUVMinObjectScale: 1 + secondaryUVPackMargin: 4 + useFileScale: 1 + tangentSpace: + normalSmoothAngle: 60 + normalImportMode: 0 + tangentImportMode: 3 + normalCalculationMode: 4 + legacyComputeAllNormalsFromSmoothingGroupsWhenMeshHasBlendShapes: 0 + blendShapeNormalImportMode: 1 + normalSmoothingSource: 0 + referencedClips: [] + importAnimation: 1 + humanDescription: + serializedVersion: 3 + human: + - boneName: CH_Hips + humanName: Hips + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_Thigh_L + humanName: LeftUpperLeg + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_Thigh_R + humanName: RightUpperLeg + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_Shin_L + humanName: LeftLowerLeg + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_Shin_R + humanName: RightLowerLeg + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_Foot_L + humanName: LeftFoot + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_Foot_R + humanName: RightFoot + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_Spine + humanName: Spine + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_Chest + humanName: Chest + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_Neck + humanName: Neck + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_Head + humanName: Head + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_Shou_L + humanName: LeftShoulder + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_Shou_R + humanName: RightShoulder + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_Uppe_L + humanName: LeftUpperArm + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_Uppe_R + humanName: RightUpperArm + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_For_L + humanName: LeftLowerArm + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_For_R + humanName: RightLowerArm + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_Hand_L + humanName: LeftHand + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_Hand_R + humanName: RightHand + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_FingerTh0_L + humanName: Left Thumb Proximal + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_FingerTh1_L + humanName: Left Thumb Intermediate + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_FingerTh2_L + humanName: Left Thumb Distal + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_FingerIn0_L + humanName: Left Index Proximal + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_FingerIn1_L + humanName: Left Index Intermediate + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_FingerIn2_L + humanName: Left Index Distal + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_FingerMid0_L + humanName: Left Middle Proximal + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_FingerMid1_L + humanName: Left Middle Intermediate + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_FingerMid2_L + humanName: Left Middle Distal + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_FingerR0_L + humanName: Left Ring Proximal + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_FingerR1_L + humanName: Left Ring Intermediate + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_FingerR2_L + humanName: Left Ring Distal + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_FingerP0_L + humanName: Left Little Proximal + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_FingerP1_L + humanName: Left Little Intermediate + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_FingerP2_L + humanName: Left Little Distal + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_FingerTh0_R + humanName: Right Thumb Proximal + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_FingerTh1_R + humanName: Right Thumb Intermediate + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_FingerTh2_R + humanName: Right Thumb Distal + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_FingerIn0_R + humanName: Right Index Proximal + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_FingerIn1_R + humanName: Right Index Intermediate + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_FingerIn2_R + humanName: Right Index Distal + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_FingerMid0_R + humanName: Right Middle Proximal + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_FingerMid1_R + humanName: Right Middle Intermediate + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_FingerMid2_R + humanName: Right Middle Distal + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_FingerR0_R + humanName: Right Ring Proximal + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_FingerR1_R + humanName: Right Ring Intermediate + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_FingerR2_R + humanName: Right Ring Distal + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_FingerP0_R + humanName: Right Little Proximal + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_FingerP1_R + humanName: Right Little Intermediate + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_FingerP2_R + humanName: Right Little Distal + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + skeleton: + - name: UC01_001_UniteInTheSky(Clone) + parentName: + position: {x: -0, y: 0, z: 0} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: CH_Hips + parentName: UC01_001_UniteInTheSky(Clone) + position: {x: -0.000072773546, y: 0.8797906, z: 0.070019096} + rotation: {x: 0.008795875, y: 0.02702195, z: 0.0010814383, w: 0.9995956} + scale: {x: 1, y: 1, z: 1} + - name: CH_Spine + parentName: CH_Hips + position: {x: 1.4901161e-10, y: 0.05238224, z: 0.003530197} + rotation: {x: -0.008975765, y: -0.0030821536, z: -0.0014939619, w: 0.99995387} + scale: {x: 1, y: 1.0000005, z: 1.0000005} + - name: CH_Chest + parentName: CH_Spine + position: {x: -1.862645e-10, y: 0.16491231, z: 0.006577148} + rotation: {x: 0.01025283, y: -0.00003700082, z: -0.009826875, w: 0.99989915} + scale: {x: 1, y: 0.99999976, z: 0.99999976} + - name: CH_Neck + parentName: CH_Chest + position: {x: -0.0000000013783574, y: 0.24534911, z: -0.035706326} + rotation: {x: -0.019598613, y: -0.0015617736, z: -0.0032422806, w: 0.99980146} + scale: {x: 1, y: 1.0000005, z: 1.0000005} + - name: CH_Head + parentName: CH_Neck + position: {x: -3.0527952e-10, y: 0.0970388, z: -0.0062348065} + rotation: {x: 0.04305692, y: -0.0057739904, z: 0.006471334, w: 0.999035} + scale: {x: 1, y: 0.99999994, z: 0.99999994} + - name: CH_Shou_L + parentName: CH_Chest + position: {x: -0.012281969, y: 0.23065636, z: -0.023482818} + rotation: {x: -0.058675427, y: -0.049061775, z: -0.14489128, w: 0.98648703} + scale: {x: 1, y: 1.0000002, z: 1.0000002} + - name: CH_Uppe_L + parentName: CH_Shou_L + position: {x: -0.10911131, y: -0.0052890014, z: -0.00843935} + rotation: {x: -0.091201335, y: -0.009756492, z: 0.13481009, w: 0.98661715} + scale: {x: 1.0000006, y: 1.0000001, z: 1.0000007} + - name: CH_For_L + parentName: CH_Uppe_L + position: {x: -0.24872932, y: -0.0068639717, z: 0.006644745} + rotation: {x: 0.06885329, y: 0.033358697, z: 0.067166924, w: 0.994804} + scale: {x: 0.9999993, y: 1.0000004, z: 0.99999905} + - name: CH_Hand_L + parentName: CH_For_L + position: {x: -0.21798706, y: 0.0024363708, z: -0.001611715} + rotation: {x: 0.055273533, y: 0.022377921, z: 0.00855618, w: 0.9981838} + scale: {x: 1.0000005, y: 0.9999999, z: 1.0000001} + - name: CH_FingerIn0_L + parentName: CH_Hand_L + position: {x: -0.06406102, y: 0.007037311, z: 0.030024793} + rotation: {x: -0.0721098, y: 0.058076605, z: -0.020419743, w: 0.995495} + scale: {x: 0.9999995, y: 1.0000002, z: 0.9999999} + - name: CH_FingerIn1_L + parentName: CH_FingerIn0_L + position: {x: -0.03864456, y: 0.001219635, z: 0.000000026226044} + rotation: {x: -0.00000030174837, y: -0.0000016391269, z: 0.029626999, w: 0.9995611} + scale: {x: 1, y: 1, z: 0.99999994} + - name: CH_FingerIn2_L + parentName: CH_FingerIn1_L + position: {x: -0.019831618, y: 0.00048400878, z: 0.00000009298324} + rotation: {x: 0, y: 0, z: 0.20096508, w: 0.9795984} + scale: {x: 1.0000001, y: 1, z: 1.0000001} + - name: CH_FingerMid0_L + parentName: CH_Hand_L + position: {x: -0.06557449, y: 0.011041107, z: 0.008100586} + rotation: {x: 0.004228337, y: 0.037817065, z: -0.025989868, w: 0.9989377} + scale: {x: 0.99999994, y: 1.0000002, z: 0.99999964} + - name: CH_FingerMid1_L + parentName: CH_FingerMid0_L + position: {x: -0.041185796, y: -0.0007038879, z: -0.00014655113} + rotation: {x: 0.0007604414, y: 0.00058571255, z: 0.052795976, w: 0.99860483} + scale: {x: 1.0000001, y: 1.0000001, z: 1.0000001} + - name: CH_FingerMid2_L + parentName: CH_FingerMid1_L + position: {x: -0.021683998, y: 0.00048583985, z: -0.00010738373} + rotation: {x: 0, y: 0, z: 0.22624305, w: 0.9740709} + scale: {x: 1, y: 0.9999997, z: 0.99999994} + - name: CH_FingerP0_L + parentName: CH_Hand_L + position: {x: -0.052998427, y: 0.004468918, z: -0.02733322} + rotation: {x: -0.01587042, y: 0.05055333, z: -0.03912815, w: 0.99782836} + scale: {x: 0.99999976, y: 0.9999999, z: 1.0000001} + - name: CH_FingerP1_L + parentName: CH_FingerP0_L + position: {x: -0.030735435, y: -0.0015520477, z: 0} + rotation: {x: -0.00000013969839, y: -0.0000012814999, z: 0.07282637, w: 0.99734473} + scale: {x: 1.0000006, y: 1.0000002, z: 1.0000005} + - name: CH_FingerP2_L + parentName: CH_FingerP1_L + position: {x: -0.016274987, y: 0.00048400878, z: 0} + rotation: {x: 0, y: 0, z: 0.25102088, w: 0.9679817} + scale: {x: 1.0000002, y: 1.0000002, z: 1.0000001} + - name: CH_FingerR0_L + parentName: CH_Hand_L + position: {x: -0.06365898, y: 0.01094162, z: -0.011445865} + rotation: {x: -0.0060580475, y: 0.043660592, z: -0.030851023, w: 0.99855167} + scale: {x: 0.99999994, y: 1.0000002, z: 1.0000002} + - name: CH_FingerR1_L + parentName: CH_FingerR0_L + position: {x: -0.037883833, y: -0.0011924744, z: -0.000000038146972} + rotation: {x: 0.0000004996544, y: 0.0000019446009, z: 0.04791813, w: 0.9988513} + scale: {x: 0.9999999, y: 1.0000001, z: 1.0000001} + - name: CH_FingerR2_L + parentName: CH_FingerR1_L + position: {x: -0.019339943, y: -0.00000015258789, z: -0.000000076293944} + rotation: {x: 0, y: 0, z: 0.23865104, w: 0.9711054} + scale: {x: 1, y: 1.0000001, z: 1} + - name: CH_FingerTh0_L + parentName: CH_Hand_L + position: {x: -0.0064083505, y: -0.012739102, z: 0.020647034} + rotation: {x: 0.6994364, y: 0.252594, z: -0.32049552, w: 0.58674324} + scale: {x: 0.9999998, y: 1.0000002, z: 1} + - name: CH_FingerTh1_L + parentName: CH_FingerTh0_L + position: {x: -0.04057995, y: -0.0009107208, z: 0.0018043518} + rotation: {x: -0.0037802155, y: 0.018734846, z: 0.062868975, w: 0.99783885} + scale: {x: 1.0000005, y: 0.99999994, z: 1.0000008} + - name: CH_FingerTh2_L + parentName: CH_FingerTh1_L + position: {x: -0.022210578, y: 0.0008297729, z: 0} + rotation: {x: 0, y: 0, z: 0.23422016, w: 0.9721836} + scale: {x: 0.99999994, y: 0.99999976, z: 1.0000005} + - name: CH_Shou_R + parentName: CH_Chest + position: {x: 0.012124489, y: 0.23065633, z: -0.0234831} + rotation: {x: -0.17077981, y: 0.98363066, z: -0.056415632, w: -0.011055562} + scale: {x: 1, y: 1.0000004, z: 1.0000004} + - name: CH_Uppe_R + parentName: CH_Shou_R + position: {x: -0.109111294, y: -0.0052891704, z: 0.008439026} + rotation: {x: 0.14516506, y: 0.04554295, z: 0.15130717, w: 0.9767083} + scale: {x: 0.99999976, y: 1.0000013, z: 1.0000002} + - name: CH_For_R + parentName: CH_Uppe_R + position: {x: -0.24872936, y: -0.006864166, z: -0.0066439817} + rotation: {x: -0.06835322, y: -0.014880213, z: 0.05765317, w: 0.9958828} + scale: {x: 0.99999994, y: 0.99999946, z: 0.9999995} + - name: CH_Hand_R + parentName: CH_For_R + position: {x: -0.21798724, y: 0.0024362183, z: 0.0016114789} + rotation: {x: -0.11417606, y: 0.015187072, z: -0.00067673635, w: 0.99334425} + scale: {x: 1.000001, y: 1.0000005, z: 1} + - name: CH_FingerIn0_R + parentName: CH_Hand_R + position: {x: -0.06406123, y: 0.0070372773, z: -0.030024713} + rotation: {x: 0.080078, y: -0.087642126, z: -0.015874794, w: 0.9928013} + scale: {x: 1, y: 1.0000002, z: 0.99999964} + - name: CH_FingerIn1_R + parentName: CH_FingerIn0_R + position: {x: -0.038644485, y: 0.0012197304, z: 0} + rotation: {x: 0.00000039488063, y: 0.0000023543826, z: 0.031828728, w: 0.99949336} + scale: {x: 0.99999976, y: 1.0000002, z: 1.0000001} + - name: CH_FingerIn2_R + parentName: CH_FingerIn1_R + position: {x: -0.019831695, y: 0.00048395872, z: -0.00000015258789} + rotation: {x: 0, y: 0, z: 0.15879549, w: 0.98731154} + scale: {x: 1.0000001, y: 0.9999999, z: 0.99999976} + - name: CH_FingerMid0_R + parentName: CH_Hand_R + position: {x: -0.065574415, y: 0.011041174, z: -0.008099975} + rotation: {x: 0.010693147, y: -0.04940608, z: -0.019562306, w: 0.99853003} + scale: {x: 0.9999994, y: 1.0000001, z: 0.99999917} + - name: CH_FingerMid1_R + parentName: CH_FingerMid0_R + position: {x: -0.041185685, y: -0.0007039541, z: 0.00014663696} + rotation: {x: -0.0005796822, y: -0.0005516259, z: 0.05480971, w: 0.9984965} + scale: {x: 0.99999994, y: 1.0000007, z: 1.0000002} + - name: CH_FingerMid2_R + parentName: CH_FingerMid1_R + position: {x: -0.02168396, y: 0.00048599957, z: 0.000107421874} + rotation: {x: 0, y: 0, z: 0.18801899, w: 0.9821654} + scale: {x: 0.99999964, y: 0.9999999, z: 1.0000001} + - name: CH_FingerP0_R + parentName: CH_Hand_R + position: {x: -0.052998427, y: 0.004468865, z: 0.027333297} + rotation: {x: 0.013489184, y: -0.0488795, z: -0.037809677, w: 0.99799764} + scale: {x: 1.0000005, y: 0.9999999, z: 0.9999995} + - name: CH_FingerP1_R + parentName: CH_FingerP0_R + position: {x: -0.030735472, y: -0.0015520048, z: 0} + rotation: {x: 0.00000070128584, y: 0.000003870576, z: 0.07462892, w: 0.99721146} + scale: {x: 1.0000001, y: 1.0000008, z: 1.0000004} + - name: CH_FingerP2_R + parentName: CH_FingerP1_R + position: {x: -0.016274948, y: 0.0004840374, z: -0.00000015258789} + rotation: {x: 0, y: 0, z: 0.21707165, w: 0.9761557} + scale: {x: 0.99999994, y: 1.0000007, z: 1.0000004} + - name: CH_FingerR0_R + parentName: CH_Hand_R + position: {x: -0.06365902, y: 0.010941544, z: 0.011445903} + rotation: {x: 0.012175316, y: -0.04851308, z: -0.02769646, w: 0.99836427} + scale: {x: 1.0000004, y: 1.0000001, z: 0.99999994} + - name: CH_FingerR1_R + parentName: CH_FingerR0_R + position: {x: -0.037883643, y: -0.0011924744, z: 0} + rotation: {x: 0.00000059138983, y: 0.0000035651026, z: 0.04982696, w: 0.9987579} + scale: {x: 0.9999999, y: 0.99999994, z: 1.0000001} + - name: CH_FingerR2_R + parentName: CH_FingerR1_R + position: {x: -0.01933979, y: -0.00000015258789, z: -0.00000015258789} + rotation: {x: 0, y: 0, z: 0.20256762, w: 0.9792683} + scale: {x: 1.0000002, y: 1.0000002, z: 1.0000001} + - name: CH_FingerTh0_R + parentName: CH_Hand_R + position: {x: -0.006407836, y: -0.012739294, z: -0.020646468} + rotation: {x: -0.6049892, y: -0.31676987, z: -0.31446207, w: 0.6593623} + scale: {x: 0.99999994, y: 1.0000002, z: 0.99999946} + - name: CH_FingerTh1_R + parentName: CH_FingerTh0_R + position: {x: -0.04057995, y: -0.00091072556, z: -0.0018042754} + rotation: {x: 0.004750162, y: -0.019504545, z: 0.060898073, w: 0.9979421} + scale: {x: 1.0000008, y: 0.9999999, z: 1.0000004} + - name: CH_FingerTh2_R + parentName: CH_FingerTh1_R + position: {x: -0.02221054, y: 0.0008296919, z: 0.00000022888183} + rotation: {x: 0, y: 0, z: 0.27279678, w: 0.9620717} + scale: {x: 1.0000012, y: 0.9999992, z: 1.0000001} + - name: CH_Thigh_L + parentName: CH_Hips + position: {x: -0.08826721, y: -0.014284587, z: 0.0023556517} + rotation: {x: 0.66444254, y: 0.025450764, z: 0.74656063, w: 0.022706961} + scale: {x: 1, y: 0.99999976, z: 0.9999996} + - name: CH_Shin_L + parentName: CH_Thigh_L + position: {x: -0.007925682, y: 0.36190096, z: 0.007466621} + rotation: {x: -0.05703204, y: -0.016010901, z: 0.09999778, w: 0.9932228} + scale: {x: 1.0000001, y: 1.0000005, z: 1.0000002} + - name: CH_Foot_L + parentName: CH_Shin_L + position: {x: 0.029875869, y: 0.38749614, z: 0.008091049} + rotation: {x: 0.046352614, y: 0.024369337, z: -0.31717333, w: 0.94692063} + scale: {x: 1.0000007, y: 0.9999995, z: 1.0000001} + - name: CH_Thigh_R + parentName: CH_Hips + position: {x: 0.08810974, y: -0.014284577, z: 0.0023555756} + rotation: {x: 0.74175715, y: 0.024268737, z: 0.67003995, w: 0.01593194} + scale: {x: 1, y: 0.9999999, z: 0.99999976} + - name: CH_Shin_R + parentName: CH_Thigh_R + position: {x: -0.007925891, y: 0.36190093, z: -0.007466888} + rotation: {x: 0.05868911, y: -0.0013824374, z: 0.08882158, w: 0.99431604} + scale: {x: 1.0000007, y: 1.0000005, z: 0.99999976} + - name: CH_Foot_R + parentName: CH_Shin_R + position: {x: 0.029875746, y: 0.38749602, z: -0.008090438} + rotation: {x: -0.03313012, y: -0.033069517, z: -0.31789255, w: 0.9469705} + scale: {x: 1.0000007, y: 1.0000004, z: 1.000001} + armTwist: 0.5 + foreArmTwist: 0.5 + upperLegTwist: 0.5 + legTwist: 0.5 + armStretch: 0.05 + legStretch: 0.05 + feetSpacing: 0 + globalScale: 1 + rootMotionBoneName: + hasTranslationDoF: 0 + hasExtraRoot: 0 + skeletonHasParents: 1 + lastHumanDescriptionAvatarSource: {instanceID: 0} + autoGenerateAvatarMappingIfUnspecified: 1 + animationType: 3 + humanoidOversampling: 1 + avatarSetup: 1 + addHumanoidExtraRootOnlyWhenUsingAvatar: 0 + remapMaterialsIfMaterialImportModeIsNone: 1 + additionalBone: 0 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Animation/UC01_001_UniteInTheSky + -WA-.fbx + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Animation/WAIT02.anim b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Animation/WAIT02.anim new file mode 100644 index 00000000..cc2218c2 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Animation/WAIT02.anim @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7827af0acb04f7f5f6b8569a0fbc708dff4b0e381f031f8605bf3a607161333d +size 25064552 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Animation/WAIT02.anim.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Animation/WAIT02.anim.meta new file mode 100644 index 00000000..a6fadf25 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Animation/WAIT02.anim.meta @@ -0,0 +1,15 @@ +fileFormatVersion: 2 +guid: 2a7cc8d66d3c2fc46a54cbf3d95e3b2d +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 7400000 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Animation/WAIT02.anim + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Animation/WAIT04.anim b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Animation/WAIT04.anim new file mode 100644 index 00000000..54609b28 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Animation/WAIT04.anim @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ccd5c7d567c916601ee4d0e3d8506d44fdc4e4cd2b64d7a628283b3b0d2b5a30 +size 16168563 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Animation/WAIT04.anim.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Animation/WAIT04.anim.meta new file mode 100644 index 00000000..f3be5339 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Animation/WAIT04.anim.meta @@ -0,0 +1,15 @@ +fileFormatVersion: 2 +guid: 3a954c05a2f94004eaff3df94a45c3ed +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 7400000 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Animation/WAIT04.anim + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Animation/WALK00_F.anim b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Animation/WALK00_F.anim new file mode 100644 index 00000000..df75be74 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Animation/WALK00_F.anim @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:286cfc46c72ddda7671fdcba313066d07983320aff1729689c88df33779065a8 +size 4192184 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Animation/WALK00_F.anim.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Animation/WALK00_F.anim.meta new file mode 100644 index 00000000..b92b211a --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Animation/WALK00_F.anim.meta @@ -0,0 +1,15 @@ +fileFormatVersion: 2 +guid: be35c3e99cdcca3439901f433aab54b2 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 7400000 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Animation/WALK00_F.anim + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Animation/WIN00.anim b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Animation/WIN00.anim new file mode 100644 index 00000000..7f487e5c --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Animation/WIN00.anim @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e46057c115918c40c09aba4424a69ff8582e34c3cefbfebc010ec0f743a9d2e8 +size 9027442 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Animation/WIN00.anim.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Animation/WIN00.anim.meta new file mode 100644 index 00000000..7a634ada --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Animation/WIN00.anim.meta @@ -0,0 +1,15 @@ +fileFormatVersion: 2 +guid: b5c22dfc5073c0c4f8c6d57c904f221e +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 7400000 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Animation/WIN00.anim + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials.meta new file mode 100644 index 00000000..eb9cb0bd --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 5d11ee2c7b51931438dd5531964bf875 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Albedo.mat b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Albedo.mat new file mode 100644 index 00000000..bf1472c8 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Albedo.mat @@ -0,0 +1,83 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 8 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: Albedo + m_Shader: {fileID: 4800000, guid: a3912d0e93a0b6f40b1f31f0bee7cac9, type: 3} + m_Parent: {fileID: 0} + m_ModifiedSerializedProperties: 0 + m_ValidKeywords: [] + m_InvalidKeywords: [] + m_LightmapFlags: 4 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: -1 + stringTagMap: {} + disabledShaderPasses: [] + m_LockedProperties: + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailAlbedoMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OcclusionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Ints: [] + m_Floats: + - _BumpScale: 1 + - _Cutoff: 0.5 + - _DetailNormalMapScale: 1 + - _DstBlend: 0 + - _GlossMapScale: 1 + - _Glossiness: 0.09901475 + - _GlossyReflections: 1 + - _Metallic: 0 + - _Mode: 0 + - _OcclusionStrength: 1 + - _Parallax: 0.02 + - _SmoothnessTextureChannel: 0 + - _SpecularHighlights: 1 + - _SrcBlend: 1 + - _UVSec: 0 + - _ZWrite: 1 + m_Colors: + - _Color: {r: 0.8, g: 0.8, b: 0.8, a: 1} + - _EmissionColor: {r: 0, g: 0, b: 0, a: 0} + m_BuildTextureStacks: [] diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Albedo.mat.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Albedo.mat.meta new file mode 100644 index 00000000..f7c1b078 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Albedo.mat.meta @@ -0,0 +1,15 @@ +fileFormatVersion: 2 +guid: 20a9ba0b540ef7841a222d3574fad507 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Albedo.mat + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Body Back.mat b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Body Back.mat new file mode 100644 index 00000000..3f7c374e --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Body Back.mat @@ -0,0 +1,405 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 8 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: Body Back + m_Shader: {fileID: -6465566751694194690, guid: b969454d26657854a8fe82c813fb0876, type: 3} + m_Parent: {fileID: 0} + m_ModifiedSerializedProperties: 0 + m_ValidKeywords: [] + m_InvalidKeywords: + - _DISABLE_SSR_TRANSPARENT + m_LightmapFlags: 4 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: 2450 + stringTagMap: + IgnoreProjection: False + disabledShaderPasses: + - TransparentDepthPrepass + - TransparentDepthPostpass + - TransparentBackface + - RayTracingPrepass + - MOTIONVECTORS + m_LockedProperties: + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _1st_ShadeMap: + m_Texture: {fileID: 2800000, guid: f180dfef53ad0924882657e28833a60b, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _2nd_ShadeMap: + m_Texture: {fileID: 2800000, guid: 9cd90983043e3974e971a6c8d66cc42d, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _AngelRing_Sampler: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BakedNormal: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BaseMap: + m_Texture: {fileID: 2800000, guid: d6a0b548a02e12e4e954cb6c5bb20e70, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ClippingMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailAlbedoMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Emissive_Tex: + m_Texture: {fileID: 2800000, guid: dc71d88ff73488f45ac239b21f552745, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _HighColor_Tex: + m_Texture: {fileID: 2800000, guid: a01adb17bdc53ba4da348b3cba074154, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main: + m_Texture: {fileID: 2800000, guid: d1e50199c6f08ed46bf2d136ab225409, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 2800000, guid: d1e50199c6f08ed46bf2d136ab225409, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MatCap_Sampler: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _NormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _NormalMapForMatCap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OcclusionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OutlineTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Outline_Sampler: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Set_1st_ShadePosition: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Set_2nd_ShadePosition: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Set_HighColorMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Set_MatcapMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Set_RimLightMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ShadingGradeMap: + m_Texture: {fileID: 2800000, guid: 7c75a3dfe8927774ea56a0777d1edcf1, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_Lightmaps: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_LightmapsInd: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_ShadowMasks: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Ints: [] + m_Floats: + - _1st2nd_Shades_Feather: 0.776 + - _1st_ShadeColor_Feather: 0.335 + - _1st_ShadeColor_Step: 0.677 + - _2nd_ShadeColor_Feather: 0.776 + - _2nd_ShadeColor_Step: 0.618 + - _ARSampler_AlphaOn: 0 + - _AR_OffsetU: 0 + - _AR_OffsetV: 0.3 + - _AddPrecomputedVelocity: 0 + - _Add_Antipodean_RimLight: 0 + - _AlphaCutoffEnable: 0 + - _AlphaDstBlend: 0 + - _AlphaSrcBlend: 1 + - _AlphaToMask: 0 + - _AlphaToMaskInspectorValue: 0 + - _AngelRing: 0 + - _Ap_RimLight_FeatherOff: 0 + - _Ap_RimLight_Power: 0.1 + - _AutoRenderQueue: 1 + - _BUILTIN_QueueControl: 0 + - _BUILTIN_QueueOffset: 0 + - _BaseColor_Step: 0.677 + - _BaseShade_Feather: 0.335 + - _Base_Speed: 0 + - _BlendMode: 0 + - _BlurLevelMatcap: 0 + - _BlurLevelSGM: 0 + - _BumpScale: 1 + - _BumpScaleMatcap: 1 + - _CameraRolling_Stabilizer: 0 + - _ClippingMode: 0 + - _Clipping_Level: 0 + - _ColorBoost: 1 + - _ColorShift_Speed: 0 + - _ConservativeDepthOffsetEnable: 0 + - _CullMode: 1 + - _CullModeForward: 1 + - _Cutoff: 0.5 + - _DepthOffsetEnable: 0 + - _DetailNormalMapScale: 1 + - _DoubleSidedEnable: 0 + - _DoubleSidedGIMode: 0 + - _DoubleSidedNormalMode: 2 + - _DstBlend: 0 + - _EMISSIVE: 0 + - _EnableBlendModePreserveSpecularLighting: 1 + - _EnableFogOnTransparent: 1 + - _Farthest_Distance: 0 + - _GI_Intensity: 0 + - _GlossMapScale: 1 + - _Glossiness: 0 + - _GlossyReflections: 1 + - _HighColor_Power: 0.48 + - _Inverse_Clipping: 0 + - _Inverse_MatcapMask: 0 + - _Inverse_Z_Axis_BLD: 1 + - _IsBaseMapAlphaAsClippingMask: 0 + - _Is_1st_ShadeColorOnly: 0 + - _Is_BLD: 0 + - _Is_BakedNormal: 0 + - _Is_BlendAddToHiColor: 1 + - _Is_BlendAddToMatCap: 1 + - _Is_BlendBaseColor: 1 + - _Is_ColorShift: 0 + - _Is_Filter_HiCutPointLightColor: 1 + - _Is_Filter_LightColor: 0 + - _Is_LightColor_1st_Shade: 1 + - _Is_LightColor_2nd_Shade: 1 + - _Is_LightColor_AR: 1 + - _Is_LightColor_Ap_RimLight: 1 + - _Is_LightColor_Base: 1 + - _Is_LightColor_HighColor: 0 + - _Is_LightColor_MatCap: 1 + - _Is_LightColor_Outline: 1 + - _Is_LightColor_RimLight: 1 + - _Is_NormalMap: 0 + - _Is_NormalMapForMatCap: 0 + - _Is_NormalMapToBase: 0 + - _Is_NormalMapToHighColor: 0 + - _Is_NormalMapToRimLight: 0 + - _Is_Ortho: 0 + - _Is_OutlineTex: 1 + - _Is_PingPong_Base: 0 + - _Is_SpecularToHighColor: 0 + - _Is_UseTweakHighColorOnShadow: 0 + - _Is_UseTweakMatCapOnShadow: 0 + - _Is_ViewCoord_Scroll: 0 + - _Is_ViewShift: 0 + - _LightDirection_MaskOn: 0 + - _MatCap: 0 + - _Metallic: 0 + - _Mode: 0 + - _Nearest_Distance: 1 + - _OUTLINE: 0 + - _OcclusionStrength: 1 + - _Offset_X_Axis_BLD: -0.05 + - _Offset_Y_Axis_BLD: 0.09 + - _Offset_Z: 0 + - _OpaqueCullMode: 1 + - _Outline_Width: 1 + - _Parallax: 0.02 + - _QueueControl: 0 + - _QueueOffset: 0 + - _RayTracing: 0 + - _ReceivesSSR: 1 + - _ReceivesSSRTransparent: 0 + - _RefractionModel: 0 + - _RenderQueueType: 1 + - _RequireSplitLighting: 0 + - _RimLight: 0 + - _RimLight_FeatherOff: 1 + - _RimLight_InsideMask: 0.47 + - _RimLight_Power: 0.01 + - _Rotate_EmissiveUV: 0 + - _Rotate_MatCapUV: 0 + - _Rotate_NormalMapForMatCapUV: 0 + - _SPRDefaultUnlitColorMask: 15 + - _SRPDefaultUnlitColMode: 1 + - _Scroll_EmissiveU: 0 + - _Scroll_EmissiveV: 0 + - _Set_SystemShadowsToBase: 1 + - _ShadeColor_Step: 0.618 + - _Smoothness: 0 + - _SmoothnessTextureChannel: 0 + - _SpecularHighlights: 1 + - _SrcBlend: 1 + - _StencilComp: 0 + - _StencilMode: 0 + - _StencilNo: 1 + - _StencilOpFail: 0 + - _StencilOpPass: 0 + - _StencilRef: 0 + - _StencilRefDepth: 8 + - _StencilRefDistortionVec: 4 + - _StencilRefGBuffer: 10 + - _StencilRefMV: 40 + - _StencilWriteMask: 6 + - _StencilWriteMaskDepth: 8 + - _StencilWriteMaskDistortionVec: 4 + - _StencilWriteMaskGBuffer: 14 + - _StencilWriteMaskMV: 40 + - _StepOffset: 0 + - _SupportDecals: 1 + - _SurfaceType: 0 + - _TessEdgeLength: 5 + - _TessExtrusionAmount: 0 + - _TessPhongStrength: 0.5 + - _TransparentBackfaceEnable: 0 + - _TransparentCullMode: 2 + - _TransparentDepthPostpassEnable: 0 + - _TransparentDepthPrepassEnable: 0 + - _TransparentEnabled: 0 + - _TransparentSortPriority: 0 + - _TransparentWritingMotionVec: 0 + - _TransparentZWrite: 0 + - _TweakHighColorOnShadow: 0 + - _TweakMatCapOnShadow: 0 + - _Tweak_HighColorMaskLevel: 0 + - _Tweak_LightDirection_MaskLevel: 0 + - _Tweak_MatCapUV: 0 + - _Tweak_MatcapMaskLevel: 0 + - _Tweak_RimLightMaskLevel: 0 + - _Tweak_ShadingGradeMapLevel: 0 + - _Tweak_SystemShadowsLevel: 0 + - _Tweak_transparency: 0 + - _UVSec: 0 + - _Unlit_Intensity: 1 + - _UseShadowThreshold: 0 + - _Use_1stAs2nd: 0 + - _Use_BaseAs1st: 0 + - _ZOverDrawMode: 0 + - _ZTestDepthEqualForOpaque: 3 + - _ZTestGBuffer: 4 + - _ZTestTransparent: 4 + - _ZWrite: 1 + - _ZWriteMode: 1 + - _simpleUI: 0 + - _utsTechnique: 1 + - _utsVersion: 2.07 + - _utsVersionX: 2 + - _utsVersionY: 2 + - _utsVersionZ: 0 + m_Colors: + - _1st_ShadeColor: {r: 1, g: 1, b: 1, a: 1} + - _2nd_ShadeColor: {r: 1, g: 1, b: 1, a: 1} + - _AngelRing_Color: {r: 1, g: 1, b: 1, a: 1} + - _Ap_RimLightColor: {r: 1, g: 1, b: 1, a: 1} + - _BaseColor: {r: 1, g: 1, b: 1, a: 1} + - _Color: {r: 1, g: 1, b: 1, a: 1} + - _ColorShift: {r: 0, g: 0, b: 0, a: 1} + - _DoubleSidedConstants: {r: 1, g: 1, b: -1, a: 0} + - _EmissionColor: {r: 1, g: 1, b: 1, a: 1} + - _Emissive_Color: {r: 1.319508, g: 1.319508, b: 1.319508, a: 1} + - _HighColor: {r: 0.3962264, g: 0.33053476, b: 0.25978997, a: 1} + - _MatCapColor: {r: 1, g: 1, b: 1, a: 1} + - _Outline_Color: {r: 0, g: 0, b: 0, a: 1} + - _RimLightColor: {r: 0, g: 0.8758622, b: 1, a: 1} + - _Tiling: {r: 1, g: 1, b: 0, a: 0} + - _ViewShift: {r: 0, g: 0, b: 0, a: 1} + m_BuildTextureStacks: [] + m_AllowLocking: 1 +--- !u!114 &2594153067871760303 +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 &5151949587641123878 +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: da692e001514ec24dbc4cca1949ff7e8, type: 3} + m_Name: + m_EditorClassIdentifier: + version: 12 + hdPluginSubTargetMaterialVersions: + m_Keys: [] + m_Values: +--- !u!114 &7694048184109273949 +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: 639247ca83abc874e893eb93af2b5e44, type: 3} + m_Name: + m_EditorClassIdentifier: + version: 0 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Body Back.mat.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Body Back.mat.meta new file mode 100644 index 00000000..308384c3 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Body Back.mat.meta @@ -0,0 +1,16 @@ +fileFormatVersion: 2 +guid: 77f776792836777419e18b9aa061fb0b +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Body + Back.mat + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Body.mat b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Body.mat new file mode 100644 index 00000000..bde3aeb3 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Body.mat @@ -0,0 +1,405 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 8 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: Body + m_Shader: {fileID: -6465566751694194690, guid: e0b73429f84a56840ba17b216237f806, type: 3} + m_Parent: {fileID: 0} + m_ModifiedSerializedProperties: 0 + m_ValidKeywords: [] + m_InvalidKeywords: + - _DISABLE_SSR_TRANSPARENT + m_LightmapFlags: 4 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: 2000 + stringTagMap: + IgnoreProjection: False + disabledShaderPasses: + - TransparentDepthPrepass + - TransparentDepthPostpass + - TransparentBackface + - RayTracingPrepass + - MOTIONVECTORS + m_LockedProperties: + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _1st_ShadeMap: + m_Texture: {fileID: 2800000, guid: f180dfef53ad0924882657e28833a60b, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _2nd_ShadeMap: + m_Texture: {fileID: 2800000, guid: 9cd90983043e3974e971a6c8d66cc42d, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _AngelRing_Sampler: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BakedNormal: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BaseMap: + m_Texture: {fileID: 2800000, guid: d6a0b548a02e12e4e954cb6c5bb20e70, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ClippingMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailAlbedoMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Emissive_Tex: + m_Texture: {fileID: 2800000, guid: dc71d88ff73488f45ac239b21f552745, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _HighColor_Tex: + m_Texture: {fileID: 2800000, guid: a01adb17bdc53ba4da348b3cba074154, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main: + m_Texture: {fileID: 2800000, guid: d1e50199c6f08ed46bf2d136ab225409, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 2800000, guid: d1e50199c6f08ed46bf2d136ab225409, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MatCap_Sampler: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _NormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _NormalMapForMatCap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OcclusionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OutlineTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Outline_Sampler: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Set_1st_ShadePosition: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Set_2nd_ShadePosition: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Set_HighColorMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Set_MatcapMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Set_RimLightMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ShadingGradeMap: + m_Texture: {fileID: 2800000, guid: 7c75a3dfe8927774ea56a0777d1edcf1, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_Lightmaps: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_LightmapsInd: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_ShadowMasks: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Ints: [] + m_Floats: + - _1st2nd_Shades_Feather: 0.776 + - _1st_ShadeColor_Feather: 0.335 + - _1st_ShadeColor_Step: 0.677 + - _2nd_ShadeColor_Feather: 0.776 + - _2nd_ShadeColor_Step: 0.618 + - _ARSampler_AlphaOn: 0 + - _AR_OffsetU: 0 + - _AR_OffsetV: 0.3 + - _AddPrecomputedVelocity: 0 + - _Add_Antipodean_RimLight: 0 + - _AlphaCutoffEnable: 0 + - _AlphaDstBlend: 0 + - _AlphaSrcBlend: 1 + - _AlphaToMask: 0 + - _AlphaToMaskInspectorValue: 0 + - _AngelRing: 0 + - _Ap_RimLight_FeatherOff: 0 + - _Ap_RimLight_Power: 0.1 + - _AutoRenderQueue: 1 + - _BUILTIN_QueueControl: 0 + - _BUILTIN_QueueOffset: 0 + - _BaseColor_Step: 0.677 + - _BaseShade_Feather: 0.335 + - _Base_Speed: 0 + - _BlendMode: 0 + - _BlurLevelMatcap: 0 + - _BlurLevelSGM: 0 + - _BumpScale: 1 + - _BumpScaleMatcap: 1 + - _CameraRolling_Stabilizer: 0 + - _ClippingMode: 0 + - _Clipping_Level: 0 + - _ColorBoost: 1 + - _ColorShift_Speed: 0 + - _ConservativeDepthOffsetEnable: 0 + - _CullMode: 2 + - _CullModeForward: 2 + - _Cutoff: 0.5 + - _DepthOffsetEnable: 0 + - _DetailNormalMapScale: 1 + - _DoubleSidedEnable: 0 + - _DoubleSidedGIMode: 0 + - _DoubleSidedNormalMode: 2 + - _DstBlend: 0 + - _EMISSIVE: 0 + - _EnableBlendModePreserveSpecularLighting: 1 + - _EnableFogOnTransparent: 1 + - _Farthest_Distance: 0 + - _GI_Intensity: 0 + - _GlossMapScale: 1 + - _Glossiness: 0 + - _GlossyReflections: 1 + - _HighColor_Power: 0.48 + - _Inverse_Clipping: 0 + - _Inverse_MatcapMask: 0 + - _Inverse_Z_Axis_BLD: 1 + - _IsBaseMapAlphaAsClippingMask: 0 + - _Is_1st_ShadeColorOnly: 0 + - _Is_BLD: 0 + - _Is_BakedNormal: 0 + - _Is_BlendAddToHiColor: 1 + - _Is_BlendAddToMatCap: 1 + - _Is_BlendBaseColor: 1 + - _Is_ColorShift: 0 + - _Is_Filter_HiCutPointLightColor: 1 + - _Is_Filter_LightColor: 0 + - _Is_LightColor_1st_Shade: 1 + - _Is_LightColor_2nd_Shade: 1 + - _Is_LightColor_AR: 1 + - _Is_LightColor_Ap_RimLight: 1 + - _Is_LightColor_Base: 1 + - _Is_LightColor_HighColor: 0 + - _Is_LightColor_MatCap: 1 + - _Is_LightColor_Outline: 1 + - _Is_LightColor_RimLight: 1 + - _Is_NormalMap: 0 + - _Is_NormalMapForMatCap: 0 + - _Is_NormalMapToBase: 0 + - _Is_NormalMapToHighColor: 0 + - _Is_NormalMapToRimLight: 0 + - _Is_Ortho: 0 + - _Is_OutlineTex: 1 + - _Is_PingPong_Base: 0 + - _Is_SpecularToHighColor: 0 + - _Is_UseTweakHighColorOnShadow: 0 + - _Is_UseTweakMatCapOnShadow: 0 + - _Is_ViewCoord_Scroll: 0 + - _Is_ViewShift: 0 + - _LightDirection_MaskOn: 0 + - _MatCap: 0 + - _Metallic: 0 + - _Mode: 0 + - _Nearest_Distance: 1 + - _OUTLINE: 0 + - _OcclusionStrength: 1 + - _Offset_X_Axis_BLD: -0.05 + - _Offset_Y_Axis_BLD: 0.09 + - _Offset_Z: 0 + - _OpaqueCullMode: 2 + - _Outline_Width: 1 + - _Parallax: 0.02 + - _QueueControl: 0 + - _QueueOffset: 0 + - _RayTracing: 0 + - _ReceivesSSR: 1 + - _ReceivesSSRTransparent: 0 + - _RefractionModel: 0 + - _RenderQueueType: 1 + - _RequireSplitLighting: 0 + - _RimLight: 0 + - _RimLight_FeatherOff: 1 + - _RimLight_InsideMask: 0.47 + - _RimLight_Power: 0.01 + - _Rotate_EmissiveUV: 0 + - _Rotate_MatCapUV: 0 + - _Rotate_NormalMapForMatCapUV: 0 + - _SPRDefaultUnlitColorMask: 15 + - _SRPDefaultUnlitColMode: 1 + - _Scroll_EmissiveU: 0 + - _Scroll_EmissiveV: 0 + - _Set_SystemShadowsToBase: 1 + - _ShadeColor_Step: 0.618 + - _Smoothness: 0 + - _SmoothnessTextureChannel: 0 + - _SpecularHighlights: 1 + - _SrcBlend: 1 + - _StencilComp: 0 + - _StencilMode: 0 + - _StencilNo: 1 + - _StencilOpFail: 0 + - _StencilOpPass: 0 + - _StencilRef: 0 + - _StencilRefDepth: 8 + - _StencilRefDistortionVec: 4 + - _StencilRefGBuffer: 10 + - _StencilRefMV: 40 + - _StencilWriteMask: 6 + - _StencilWriteMaskDepth: 8 + - _StencilWriteMaskDistortionVec: 4 + - _StencilWriteMaskGBuffer: 14 + - _StencilWriteMaskMV: 40 + - _StepOffset: 0 + - _SupportDecals: 1 + - _SurfaceType: 0 + - _TessEdgeLength: 5 + - _TessExtrusionAmount: 0 + - _TessPhongStrength: 0.5 + - _TransparentBackfaceEnable: 0 + - _TransparentCullMode: 2 + - _TransparentDepthPostpassEnable: 0 + - _TransparentDepthPrepassEnable: 0 + - _TransparentEnabled: 0 + - _TransparentSortPriority: 0 + - _TransparentWritingMotionVec: 0 + - _TransparentZWrite: 0 + - _TweakHighColorOnShadow: 0 + - _TweakMatCapOnShadow: 0 + - _Tweak_HighColorMaskLevel: 0 + - _Tweak_LightDirection_MaskLevel: 0 + - _Tweak_MatCapUV: 0 + - _Tweak_MatcapMaskLevel: 0 + - _Tweak_RimLightMaskLevel: 0 + - _Tweak_ShadingGradeMapLevel: 0 + - _Tweak_SystemShadowsLevel: 0 + - _Tweak_transparency: 0 + - _UVSec: 0 + - _Unlit_Intensity: 1 + - _UseShadowThreshold: 0 + - _Use_1stAs2nd: 0 + - _Use_BaseAs1st: 0 + - _ZOverDrawMode: 0 + - _ZTestDepthEqualForOpaque: 3 + - _ZTestGBuffer: 4 + - _ZTestTransparent: 4 + - _ZWrite: 1 + - _ZWriteMode: 1 + - _simpleUI: 0 + - _utsTechnique: 1 + - _utsVersion: 2.07 + - _utsVersionX: 2 + - _utsVersionY: 2 + - _utsVersionZ: 0 + m_Colors: + - _1st_ShadeColor: {r: 1, g: 1, b: 1, a: 1} + - _2nd_ShadeColor: {r: 1, g: 1, b: 1, a: 1} + - _AngelRing_Color: {r: 1, g: 1, b: 1, a: 1} + - _Ap_RimLightColor: {r: 1, g: 1, b: 1, a: 1} + - _BaseColor: {r: 1, g: 1, b: 1, a: 1} + - _Color: {r: 1, g: 1, b: 1, a: 1} + - _ColorShift: {r: 0, g: 0, b: 0, a: 1} + - _DoubleSidedConstants: {r: 1, g: 1, b: -1, a: 0} + - _EmissionColor: {r: 1, g: 1, b: 1, a: 1} + - _Emissive_Color: {r: 1.319508, g: 1.319508, b: 1.319508, a: 1} + - _HighColor: {r: 0.3962264, g: 0.33053476, b: 0.25978997, a: 1} + - _MatCapColor: {r: 1, g: 1, b: 1, a: 1} + - _Outline_Color: {r: 0, g: 0, b: 0, a: 1} + - _RimLightColor: {r: 0, g: 0.8758622, b: 1, a: 1} + - _Tiling: {r: 1, g: 1, b: 0, a: 0} + - _ViewShift: {r: 0, g: 0, b: 0, a: 1} + m_BuildTextureStacks: [] + m_AllowLocking: 1 +--- !u!114 &2129366640030291598 +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: da692e001514ec24dbc4cca1949ff7e8, type: 3} + m_Name: + m_EditorClassIdentifier: + version: 12 + hdPluginSubTargetMaterialVersions: + m_Keys: [] + m_Values: +--- !u!114 &2594153067871760303 +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 &7694048184109273949 +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: 639247ca83abc874e893eb93af2b5e44, type: 3} + m_Name: + m_EditorClassIdentifier: + version: 0 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Body.mat.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Body.mat.meta new file mode 100644 index 00000000..2a563cba --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Body.mat.meta @@ -0,0 +1,16 @@ +fileFormatVersion: 2 +guid: 2f1752b96ee4af7438efa446bf057ee1 +timeCreated: 1544184610 +licenseType: Store +NativeFormatImporter: + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Body.mat + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Eyes.mat b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Eyes.mat new file mode 100644 index 00000000..3109cd38 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Eyes.mat @@ -0,0 +1,405 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 8 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: Eyes + m_Shader: {fileID: -6465566751694194690, guid: e0b73429f84a56840ba17b216237f806, type: 3} + m_Parent: {fileID: 0} + m_ModifiedSerializedProperties: 0 + m_ValidKeywords: [] + m_InvalidKeywords: + - _DISABLE_SSR_TRANSPARENT + m_LightmapFlags: 4 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: 2000 + stringTagMap: + IgnoreProjection: False + disabledShaderPasses: + - TransparentDepthPrepass + - TransparentDepthPostpass + - TransparentBackface + - RayTracingPrepass + - MOTIONVECTORS + m_LockedProperties: + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _1st_ShadeMap: + m_Texture: {fileID: 2800000, guid: 6ff07624f73f6184f84deb5ba5242590, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _2nd_ShadeMap: + m_Texture: {fileID: 2800000, guid: 7d84fa1a7f8997342ba010124f77b1e8, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _AngelRing_Sampler: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BakedNormal: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BaseMap: + m_Texture: {fileID: 2800000, guid: caf3fd65fe2194f4a9458d9689902a73, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ClippingMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailAlbedoMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Emissive_Tex: + m_Texture: {fileID: 2800000, guid: 5a8dc6b89c866b546a4b2beebade28a1, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _HighColor_Tex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main: + m_Texture: {fileID: 2800000, guid: 6ff07624f73f6184f84deb5ba5242590, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 2800000, guid: 7275e6b9fb5d06847b114e33f0ab8ca6, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MatCap_Sampler: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _NormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _NormalMapForMatCap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OcclusionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OutlineTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Outline_Sampler: + m_Texture: {fileID: 2800000, guid: c5acb3acbd64e734b838b254bb0ee4d8, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Set_1st_ShadePosition: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Set_2nd_ShadePosition: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Set_HighColorMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Set_MatcapMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Set_RimLightMask: + m_Texture: {fileID: 2800000, guid: c5acb3acbd64e734b838b254bb0ee4d8, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ShadingGradeMap: + m_Texture: {fileID: 2800000, guid: ec3cb3dfef7e49a4eb0c10040e9733df, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_Lightmaps: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_LightmapsInd: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_ShadowMasks: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Ints: [] + m_Floats: + - _1st2nd_Shades_Feather: 1 + - _1st_ShadeColor_Feather: 0.0001 + - _1st_ShadeColor_Step: 0.254 + - _2nd_ShadeColor_Feather: 1 + - _2nd_ShadeColor_Step: 0.848 + - _ARSampler_AlphaOn: 0 + - _AR_OffsetU: 0 + - _AR_OffsetV: 0.3 + - _AddPrecomputedVelocity: 0 + - _Add_Antipodean_RimLight: 1 + - _AlphaCutoffEnable: 0 + - _AlphaDstBlend: 0 + - _AlphaSrcBlend: 1 + - _AlphaToMask: 0 + - _AlphaToMaskInspectorValue: 0 + - _AngelRing: 0 + - _Ap_RimLight_FeatherOff: 0 + - _Ap_RimLight_Power: 0.59 + - _AutoRenderQueue: 1 + - _BUILTIN_QueueControl: 1 + - _BUILTIN_QueueOffset: 0 + - _BaseColor_Step: 0.254 + - _BaseShade_Feather: 0.0001 + - _Base_Speed: 0 + - _BlendMode: 0 + - _BlurLevelMatcap: 0 + - _BlurLevelSGM: 0 + - _BumpScale: 1 + - _BumpScaleMatcap: 1 + - _CameraRolling_Stabilizer: 0 + - _ClippingMode: 0 + - _Clipping_Level: 0 + - _ColorBoost: 1 + - _ColorShift_Speed: 0 + - _ConservativeDepthOffsetEnable: 0 + - _CullMode: 2 + - _CullModeForward: 2 + - _Cutoff: 0.5 + - _DepthOffsetEnable: 0 + - _DetailNormalMapScale: 1 + - _DoubleSidedEnable: 0 + - _DoubleSidedGIMode: 0 + - _DoubleSidedNormalMode: 2 + - _DstBlend: 0 + - _EMISSIVE: 0 + - _EnableBlendModePreserveSpecularLighting: 1 + - _EnableFogOnTransparent: 1 + - _Farthest_Distance: 0 + - _GI_Intensity: 0 + - _GlossMapScale: 1 + - _Glossiness: 0 + - _GlossyReflections: 1 + - _HighColor_Power: 0 + - _Inverse_Clipping: 0 + - _Inverse_MatcapMask: 0 + - _Inverse_Z_Axis_BLD: 1 + - _IsBaseMapAlphaAsClippingMask: 0 + - _Is_1st_ShadeColorOnly: 0 + - _Is_BLD: 0 + - _Is_BakedNormal: 0 + - _Is_BlendAddToHiColor: 0 + - _Is_BlendAddToMatCap: 1 + - _Is_BlendBaseColor: 1 + - _Is_ColorShift: 0 + - _Is_Filter_HiCutPointLightColor: 1 + - _Is_Filter_LightColor: 0 + - _Is_LightColor_1st_Shade: 1 + - _Is_LightColor_2nd_Shade: 1 + - _Is_LightColor_AR: 1 + - _Is_LightColor_Ap_RimLight: 1 + - _Is_LightColor_Base: 1 + - _Is_LightColor_HighColor: 1 + - _Is_LightColor_MatCap: 1 + - _Is_LightColor_Outline: 1 + - _Is_LightColor_RimLight: 1 + - _Is_NormalMap: 0 + - _Is_NormalMapForMatCap: 0 + - _Is_NormalMapToBase: 0 + - _Is_NormalMapToHighColor: 0 + - _Is_NormalMapToRimLight: 0 + - _Is_Ortho: 0 + - _Is_OutlineTex: 0 + - _Is_PingPong_Base: 0 + - _Is_SpecularToHighColor: 0 + - _Is_UseTweakHighColorOnShadow: 0 + - _Is_UseTweakMatCapOnShadow: 0 + - _Is_ViewCoord_Scroll: 0 + - _Is_ViewShift: 0 + - _LightDirection_MaskOn: 0 + - _MatCap: 0 + - _Metallic: 0 + - _Mode: 0 + - _Nearest_Distance: 1 + - _OUTLINE: 0 + - _OcclusionStrength: 1 + - _Offset_X_Axis_BLD: -0.05 + - _Offset_Y_Axis_BLD: 0.09 + - _Offset_Z: 0 + - _OpaqueCullMode: 2 + - _Outline_Width: 1 + - _Parallax: 0.02 + - _QueueControl: 0 + - _QueueOffset: 0 + - _RayTracing: 0 + - _ReceivesSSR: 1 + - _ReceivesSSRTransparent: 0 + - _RefractionModel: 0 + - _RenderQueueType: 1 + - _RequireSplitLighting: 0 + - _RimLight: 0 + - _RimLight_FeatherOff: 0 + - _RimLight_InsideMask: 0.0001 + - _RimLight_Power: 1 + - _Rotate_EmissiveUV: 0 + - _Rotate_MatCapUV: 0 + - _Rotate_NormalMapForMatCapUV: 0 + - _SPRDefaultUnlitColorMask: 15 + - _SRPDefaultUnlitColMode: 1 + - _Scroll_EmissiveU: 0 + - _Scroll_EmissiveV: 0 + - _Set_SystemShadowsToBase: 1 + - _ShadeColor_Step: 0.848 + - _Smoothness: 0 + - _SmoothnessTextureChannel: 0 + - _SpecularHighlights: 1 + - _SrcBlend: 1 + - _StencilComp: 0 + - _StencilMode: 0 + - _StencilNo: 1 + - _StencilOpFail: 0 + - _StencilOpPass: 0 + - _StencilRef: 0 + - _StencilRefDepth: 8 + - _StencilRefDistortionVec: 4 + - _StencilRefGBuffer: 10 + - _StencilRefMV: 40 + - _StencilWriteMask: 6 + - _StencilWriteMaskDepth: 8 + - _StencilWriteMaskDistortionVec: 4 + - _StencilWriteMaskGBuffer: 14 + - _StencilWriteMaskMV: 40 + - _StepOffset: 0.04 + - _SupportDecals: 1 + - _SurfaceType: 0 + - _TessEdgeLength: 5 + - _TessExtrusionAmount: 0 + - _TessPhongStrength: 0.5 + - _TransparentBackfaceEnable: 0 + - _TransparentCullMode: 2 + - _TransparentDepthPostpassEnable: 0 + - _TransparentDepthPrepassEnable: 0 + - _TransparentEnabled: 0 + - _TransparentSortPriority: 0 + - _TransparentWritingMotionVec: 0 + - _TransparentZWrite: 0 + - _TweakHighColorOnShadow: 0 + - _TweakMatCapOnShadow: 0 + - _Tweak_HighColorMaskLevel: 0 + - _Tweak_LightDirection_MaskLevel: 0 + - _Tweak_MatCapUV: 0 + - _Tweak_MatcapMaskLevel: 0 + - _Tweak_RimLightMaskLevel: 0 + - _Tweak_ShadingGradeMapLevel: 0 + - _Tweak_SystemShadowsLevel: -0.5 + - _Tweak_transparency: 0 + - _UVSec: 0 + - _Unlit_Intensity: 1 + - _UseShadowThreshold: 0 + - _Use_1stAs2nd: 0 + - _Use_BaseAs1st: 0 + - _ZOverDrawMode: 0 + - _ZTestDepthEqualForOpaque: 3 + - _ZTestGBuffer: 4 + - _ZTestTransparent: 4 + - _ZWrite: 1 + - _ZWriteMode: 1 + - _simpleUI: 0 + - _utsTechnique: 1 + - _utsVersion: 2.07 + - _utsVersionX: 2 + - _utsVersionY: 2 + - _utsVersionZ: 0 + m_Colors: + - _1st_ShadeColor: {r: 1, g: 1, b: 1, a: 1} + - _2nd_ShadeColor: {r: 0.6021844, g: 0.59278214, b: 0.7264151, a: 1} + - _AngelRing_Color: {r: 1, g: 1, b: 1, a: 1} + - _Ap_RimLightColor: {r: 1, g: 0.80689657, b: 0, a: 1} + - _BaseColor: {r: 1, g: 1, b: 1, a: 1} + - _Color: {r: 1, g: 1, b: 1, a: 1} + - _ColorShift: {r: 0, g: 0, b: 0, a: 1} + - _DoubleSidedConstants: {r: 1, g: 1, b: -1, a: 0} + - _EmissionColor: {r: 1, g: 1, b: 1, a: 1} + - _Emissive_Color: {r: 0.21323532, g: 0, b: 0, a: 1} + - _HighColor: {r: 0, g: 0, b: 0, a: 1} + - _MatCapColor: {r: 1, g: 1, b: 1, a: 1} + - _Outline_Color: {r: 0.36764705, g: 0.059472308, b: 0.28263327, a: 1} + - _RimLightColor: {r: 1, g: 0, b: 0, a: 1} + - _Tiling: {r: 1, g: 1, b: 0, a: 0} + - _ViewShift: {r: 0, g: 0, b: 0, a: 1} + m_BuildTextureStacks: [] + m_AllowLocking: 1 +--- !u!114 &953996833678100074 +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: da692e001514ec24dbc4cca1949ff7e8, type: 3} + m_Name: + m_EditorClassIdentifier: + version: 12 + hdPluginSubTargetMaterialVersions: + m_Keys: [] + m_Values: +--- !u!114 &5432644595444900209 +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: 639247ca83abc874e893eb93af2b5e44, type: 3} + m_Name: + m_EditorClassIdentifier: + version: 0 +--- !u!114 &5578569521361078589 +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/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Eyes.mat.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Eyes.mat.meta new file mode 100644 index 00000000..2896036e --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Eyes.mat.meta @@ -0,0 +1,16 @@ +fileFormatVersion: 2 +guid: f72ba1415e9cdcf4eb6a64dd69cc4b31 +timeCreated: 1544184610 +licenseType: Store +NativeFormatImporter: + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Eyes.mat + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Eyes_HL.mat b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Eyes_HL.mat new file mode 100644 index 00000000..47462ca8 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Eyes_HL.mat @@ -0,0 +1,410 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &-2020739770036755877 +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: 639247ca83abc874e893eb93af2b5e44, type: 3} + m_Name: + m_EditorClassIdentifier: + version: 0 +--- !u!21 &2100000 +Material: + serializedVersion: 8 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: Eyes_HL + m_Shader: {fileID: -6465566751694194690, guid: e0b73429f84a56840ba17b216237f806, type: 3} + m_Parent: {fileID: 0} + m_ModifiedSerializedProperties: 0 + m_ValidKeywords: [] + m_InvalidKeywords: + - _DISABLE_SSR_TRANSPARENT + m_LightmapFlags: 4 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: 2000 + stringTagMap: + IgnoreProjection: False + disabledShaderPasses: + - TransparentDepthPrepass + - TransparentDepthPostpass + - TransparentBackface + - RayTracingPrepass + - MOTIONVECTORS + m_LockedProperties: + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _1st_ShadeMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _2nd_ShadeMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _AngelRing_Sampler: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BakedNormal: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BaseMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ClippingMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailAlbedoMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Emissive_Tex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _HighColor_Tex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main: + m_Texture: {fileID: 2800000, guid: 7d84fa1a7f8997342ba010124f77b1e8, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MatCap_Sampler: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _NormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _NormalMapForMatCap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OcclusionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OutlineTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Outline_Sampler: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Set_1st_ShadePosition: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Set_2nd_ShadePosition: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Set_HighColorMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Set_MatcapMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Set_RimLightMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ShadingGradeMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _SpecGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_Lightmaps: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_LightmapsInd: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_ShadowMasks: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Ints: [] + m_Floats: + - _1st2nd_Shades_Feather: 0.0001 + - _1st_ShadeColor_Feather: 0.0001 + - _1st_ShadeColor_Step: 0.5 + - _2nd_ShadeColor_Feather: 0.0001 + - _2nd_ShadeColor_Step: 0 + - _ARSampler_AlphaOn: 0 + - _AR_OffsetU: 0 + - _AR_OffsetV: 0.3 + - _AddPrecomputedVelocity: 0 + - _Add_Antipodean_RimLight: 0 + - _AlphaClip: 0 + - _AlphaCutoffEnable: 0 + - _AlphaDstBlend: 0 + - _AlphaSrcBlend: 1 + - _AlphaToMask: 0 + - _AlphaToMaskInspectorValue: 0 + - _AngelRing: 0 + - _Ap_RimLight_FeatherOff: 0 + - _Ap_RimLight_Power: 0.1 + - _AutoRenderQueue: 1 + - _BUILTIN_QueueControl: 1 + - _BUILTIN_QueueOffset: 0 + - _BaseColor_Step: 0.5 + - _BaseShade_Feather: 0.0001 + - _Base_Speed: 0 + - _Blend: 0 + - _BlendMode: 0 + - _BlurLevelMatcap: 0 + - _BlurLevelSGM: 0 + - _BumpScale: 1 + - _BumpScaleMatcap: 1 + - _CameraRolling_Stabilizer: 0 + - _ClippingMode: 0 + - _Clipping_Level: 0 + - _ColorShift_Speed: 0 + - _ConservativeDepthOffsetEnable: 0 + - _Cull: 2 + - _CullMode: 2 + - _CullModeForward: 2 + - _Cutoff: 0.5 + - _DepthOffsetEnable: 0 + - _DetailNormalMapScale: 1 + - _DoubleSidedEnable: 0 + - _DoubleSidedGIMode: 0 + - _DoubleSidedNormalMode: 2 + - _DstBlend: 0 + - _EMISSIVE: 0 + - _EnableBlendModePreserveSpecularLighting: 1 + - _EnableFogOnTransparent: 1 + - _EnvironmentReflections: 1 + - _Farthest_Distance: 0 + - _GI_Intensity: 0 + - _GlossMapScale: 0 + - _Glossiness: 0 + - _GlossyReflections: 0 + - _HighColor_Power: 0 + - _Inverse_Clipping: 0 + - _Inverse_MatcapMask: 0 + - _Inverse_Z_Axis_BLD: 1 + - _IsBaseMapAlphaAsClippingMask: 0 + - _Is_BLD: 0 + - _Is_BakedNormal: 0 + - _Is_BlendAddToHiColor: 0 + - _Is_BlendAddToMatCap: 1 + - _Is_BlendBaseColor: 0 + - _Is_ColorShift: 0 + - _Is_Filter_HiCutPointLightColor: 1 + - _Is_Filter_LightColor: 0 + - _Is_LightColor_1st_Shade: 1 + - _Is_LightColor_2nd_Shade: 1 + - _Is_LightColor_AR: 1 + - _Is_LightColor_Ap_RimLight: 1 + - _Is_LightColor_Base: 1 + - _Is_LightColor_HighColor: 1 + - _Is_LightColor_MatCap: 1 + - _Is_LightColor_Outline: 1 + - _Is_LightColor_RimLight: 1 + - _Is_NormalMapForMatCap: 0 + - _Is_NormalMapToBase: 0 + - _Is_NormalMapToHighColor: 0 + - _Is_NormalMapToRimLight: 0 + - _Is_Ortho: 0 + - _Is_OutlineTex: 0 + - _Is_PingPong_Base: 0 + - _Is_SpecularToHighColor: 0 + - _Is_UseTweakHighColorOnShadow: 0 + - _Is_UseTweakMatCapOnShadow: 0 + - _Is_ViewCoord_Scroll: 0 + - _Is_ViewShift: 0 + - _LightDirection_MaskOn: 0 + - _MatCap: 0 + - _Metallic: 0 + - _Mode: 0 + - _Nearest_Distance: 1 + - _OUTLINE: 0 + - _OcclusionStrength: 1 + - _Offset_X_Axis_BLD: -0.05 + - _Offset_Y_Axis_BLD: 0.09 + - _Offset_Z: 0 + - _OpaqueCullMode: 2 + - _Outline_Width: 0 + - _Parallax: 0.02 + - _QueueControl: 0 + - _QueueOffset: 0 + - _RayTracing: 0 + - _ReceiveShadows: 1 + - _ReceivesSSR: 1 + - _ReceivesSSRTransparent: 0 + - _RefractionModel: 0 + - _RenderQueueType: 1 + - _RequireSplitLighting: 0 + - _RimLight: 0 + - _RimLight_FeatherOff: 0 + - _RimLight_InsideMask: 0.0001 + - _RimLight_Power: 0.1 + - _Rotate_EmissiveUV: 0 + - _Rotate_MatCapUV: 0 + - _Rotate_NormalMapForMatCapUV: 0 + - _SPRDefaultUnlitColorMask: 15 + - _SRPDefaultUnlitColMode: 1 + - _Scroll_EmissiveU: 0 + - _Scroll_EmissiveV: 0 + - _Set_SystemShadowsToBase: 1 + - _ShadeColor_Step: 0 + - _Smoothness: 0.5 + - _SmoothnessTextureChannel: 0 + - _SpecularHighlights: 1 + - _SrcBlend: 1 + - _StencilComp: 0 + - _StencilMode: 0 + - _StencilNo: 1 + - _StencilOpFail: 0 + - _StencilOpPass: 0 + - _StencilRef: 0 + - _StencilRefDepth: 8 + - _StencilRefDistortionVec: 4 + - _StencilRefGBuffer: 10 + - _StencilRefMV: 40 + - _StencilWriteMask: 6 + - _StencilWriteMaskDepth: 8 + - _StencilWriteMaskDistortionVec: 4 + - _StencilWriteMaskGBuffer: 14 + - _StencilWriteMaskMV: 40 + - _StepOffset: 0 + - _SupportDecals: 1 + - _Surface: 0 + - _SurfaceType: 0 + - _TransparentBackfaceEnable: 0 + - _TransparentCullMode: 2 + - _TransparentDepthPostpassEnable: 0 + - _TransparentDepthPrepassEnable: 0 + - _TransparentEnabled: 0 + - _TransparentSortPriority: 0 + - _TransparentWritingMotionVec: 0 + - _TransparentZWrite: 0 + - _TweakHighColorOnShadow: 0 + - _TweakMatCapOnShadow: 0 + - _Tweak_HighColorMaskLevel: 0 + - _Tweak_LightDirection_MaskLevel: 0 + - _Tweak_MatCapUV: 0 + - _Tweak_MatcapMaskLevel: 0 + - _Tweak_RimLightMaskLevel: 0 + - _Tweak_ShadingGradeMapLevel: 0 + - _Tweak_SystemShadowsLevel: 0 + - _Tweak_transparency: 0 + - _UVSec: 0 + - _Unlit_Intensity: 1 + - _UseShadowThreshold: 0 + - _Use_1stAs2nd: 0 + - _Use_BaseAs1st: 0 + - _WorkflowMode: 1 + - _ZOverDrawMode: 0 + - _ZTestDepthEqualForOpaque: 3 + - _ZTestGBuffer: 4 + - _ZTestTransparent: 4 + - _ZWrite: 1 + - _ZWriteMode: 1 + - _simpleUI: 0 + - _utsTechnique: 0 + - _utsVersionX: 2 + - _utsVersionY: 2 + - _utsVersionZ: 0 + m_Colors: + - _1st_ShadeColor: {r: 1, g: 1, b: 1, a: 1} + - _2nd_ShadeColor: {r: 1, g: 1, b: 1, a: 1} + - _AngelRing_Color: {r: 1, g: 1, b: 1, a: 1} + - _Ap_RimLightColor: {r: 1, g: 1, b: 1, a: 1} + - _BaseColor: {r: 1, g: 1, b: 1, a: 1} + - _Color: {r: 1, g: 1, b: 1, a: 1} + - _ColorShift: {r: 0, g: 0, b: 0, a: 1} + - _DoubleSidedConstants: {r: 1, g: 1, b: -1, a: 0} + - _EmissionColor: {r: 1, g: 1, b: 1, a: 1} + - _Emissive_Color: {r: 2, g: 2, b: 2, a: 1} + - _HighColor: {r: 0, g: 0, b: 0, a: 1} + - _MatCapColor: {r: 1, g: 1, b: 1, a: 1} + - _Outline_Color: {r: 0.5, g: 0.5, b: 0.5, a: 1} + - _RimLightColor: {r: 1, g: 1, b: 1, a: 1} + - _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1} + - _Tiling: {r: 1, g: 1, b: 0, a: 0} + - _ViewShift: {r: 0, g: 0, b: 0, a: 1} + m_BuildTextureStacks: [] + m_AllowLocking: 1 +--- !u!114 &1141793881992010275 +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: da692e001514ec24dbc4cca1949ff7e8, type: 3} + m_Name: + m_EditorClassIdentifier: + version: 12 + hdPluginSubTargetMaterialVersions: + m_Keys: [] + m_Values: +--- !u!114 &4074571565025144848 +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/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Eyes_HL.mat.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Eyes_HL.mat.meta new file mode 100644 index 00000000..75a8bcd8 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Eyes_HL.mat.meta @@ -0,0 +1,15 @@ +fileFormatVersion: 2 +guid: b252b15c283524a45afa12c94b5a2853 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 0 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Eyes_HL.mat + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Face.mat b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Face.mat new file mode 100644 index 00000000..ad919034 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Face.mat @@ -0,0 +1,405 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &-5292109544577297850 +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: 639247ca83abc874e893eb93af2b5e44, type: 3} + m_Name: + m_EditorClassIdentifier: + version: 0 +--- !u!114 &-4702967822752667190 +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 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: Face + m_Shader: {fileID: -6465566751694194690, guid: e0b73429f84a56840ba17b216237f806, type: 3} + m_Parent: {fileID: 0} + m_ModifiedSerializedProperties: 0 + m_ValidKeywords: [] + m_InvalidKeywords: + - _DISABLE_SSR_TRANSPARENT + m_LightmapFlags: 4 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: 2000 + stringTagMap: + IgnoreProjection: False + disabledShaderPasses: + - TransparentDepthPrepass + - TransparentDepthPostpass + - TransparentBackface + - RayTracingPrepass + - MOTIONVECTORS + m_LockedProperties: + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _1st_ShadeMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _2nd_ShadeMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _AngelRing_Sampler: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BakedNormal: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BaseMap: + m_Texture: {fileID: 2800000, guid: caf3fd65fe2194f4a9458d9689902a73, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ClippingMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailAlbedoMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Emissive_Tex: + m_Texture: {fileID: 2800000, guid: 5a8dc6b89c866b546a4b2beebade28a1, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _HighColor_Tex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main: + m_Texture: {fileID: 2800000, guid: 7275e6b9fb5d06847b114e33f0ab8ca6, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 2800000, guid: 7275e6b9fb5d06847b114e33f0ab8ca6, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MatCap_Sampler: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _NormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _NormalMapForMatCap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OcclusionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OutlineTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Outline_Sampler: + m_Texture: {fileID: 2800000, guid: c5acb3acbd64e734b838b254bb0ee4d8, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Set_1st_ShadePosition: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Set_2nd_ShadePosition: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Set_HighColorMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Set_MatcapMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Set_RimLightMask: + m_Texture: {fileID: 2800000, guid: b925033b206f79942b43d77ac699fc72, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ShadingGradeMap: + m_Texture: {fileID: 2800000, guid: ec3cb3dfef7e49a4eb0c10040e9733df, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_Lightmaps: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_LightmapsInd: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_ShadowMasks: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Ints: [] + m_Floats: + - _1st2nd_Shades_Feather: 0.25 + - _1st_ShadeColor_Feather: 0.54 + - _1st_ShadeColor_Step: 0.39 + - _2nd_ShadeColor_Feather: 0.25 + - _2nd_ShadeColor_Step: 0.33 + - _ARSampler_AlphaOn: 0 + - _AR_OffsetU: 0 + - _AR_OffsetV: 0.3 + - _AddPrecomputedVelocity: 0 + - _Add_Antipodean_RimLight: 1 + - _AlphaCutoffEnable: 0 + - _AlphaDstBlend: 0 + - _AlphaSrcBlend: 1 + - _AlphaToMask: 0 + - _AlphaToMaskInspectorValue: 0 + - _AngelRing: 0 + - _Ap_RimLight_FeatherOff: 0 + - _Ap_RimLight_Power: 0.59 + - _AutoRenderQueue: 1 + - _BUILTIN_QueueControl: 1 + - _BUILTIN_QueueOffset: 0 + - _BaseColor_Step: 0.39 + - _BaseShade_Feather: 0.54 + - _Base_Speed: 0 + - _BlendMode: 0 + - _BlurLevelMatcap: 0 + - _BlurLevelSGM: 0 + - _BumpScale: 1 + - _BumpScaleMatcap: 1 + - _CameraRolling_Stabilizer: 0 + - _ClippingMode: 0 + - _Clipping_Level: 0 + - _ColorBoost: 1 + - _ColorShift_Speed: 0 + - _ConservativeDepthOffsetEnable: 0 + - _CullMode: 2 + - _CullModeForward: 2 + - _Cutoff: 0.5 + - _DepthOffsetEnable: 0 + - _DetailNormalMapScale: 1 + - _DoubleSidedEnable: 0 + - _DoubleSidedGIMode: 0 + - _DoubleSidedNormalMode: 2 + - _DstBlend: 0 + - _EMISSIVE: 0 + - _EnableBlendModePreserveSpecularLighting: 1 + - _EnableFogOnTransparent: 1 + - _Farthest_Distance: 0 + - _GI_Intensity: 0 + - _GlossMapScale: 1 + - _Glossiness: 0 + - _GlossyReflections: 1 + - _HighColor_Power: 0 + - _Inverse_Clipping: 0 + - _Inverse_MatcapMask: 0 + - _Inverse_Z_Axis_BLD: 1 + - _IsBaseMapAlphaAsClippingMask: 0 + - _Is_1st_ShadeColorOnly: 0 + - _Is_BLD: 0 + - _Is_BakedNormal: 0 + - _Is_BlendAddToHiColor: 0 + - _Is_BlendAddToMatCap: 1 + - _Is_BlendBaseColor: 1 + - _Is_ColorShift: 0 + - _Is_Filter_HiCutPointLightColor: 1 + - _Is_Filter_LightColor: 0 + - _Is_LightColor_1st_Shade: 1 + - _Is_LightColor_2nd_Shade: 1 + - _Is_LightColor_AR: 1 + - _Is_LightColor_Ap_RimLight: 1 + - _Is_LightColor_Base: 1 + - _Is_LightColor_HighColor: 1 + - _Is_LightColor_MatCap: 1 + - _Is_LightColor_Outline: 0 + - _Is_LightColor_RimLight: 1 + - _Is_NormalMap: 0 + - _Is_NormalMapForMatCap: 0 + - _Is_NormalMapToBase: 0 + - _Is_NormalMapToHighColor: 0 + - _Is_NormalMapToRimLight: 0 + - _Is_Ortho: 0 + - _Is_OutlineTex: 0 + - _Is_PingPong_Base: 0 + - _Is_SpecularToHighColor: 0 + - _Is_UseTweakHighColorOnShadow: 0 + - _Is_UseTweakMatCapOnShadow: 0 + - _Is_ViewCoord_Scroll: 0 + - _Is_ViewShift: 0 + - _LightDirection_MaskOn: 1 + - _MatCap: 0 + - _Metallic: 0 + - _Mode: 0 + - _Nearest_Distance: 1.2 + - _OUTLINE: 0 + - _OcclusionStrength: 1 + - _Offset_X_Axis_BLD: -0.05 + - _Offset_Y_Axis_BLD: 0.09 + - _Offset_Z: 0 + - _OpaqueCullMode: 2 + - _Outline_Width: 2 + - _Parallax: 0.02 + - _QueueControl: 0 + - _QueueOffset: 0 + - _RayTracing: 0 + - _ReceivesSSR: 1 + - _ReceivesSSRTransparent: 0 + - _RefractionModel: 0 + - _RenderQueueType: 1 + - _RequireSplitLighting: 0 + - _RimLight: 0 + - _RimLight_FeatherOff: 0 + - _RimLight_InsideMask: 0.0001 + - _RimLight_Power: 1 + - _Rotate_EmissiveUV: 0 + - _Rotate_MatCapUV: 0 + - _Rotate_NormalMapForMatCapUV: 0 + - _SPRDefaultUnlitColorMask: 15 + - _SRPDefaultUnlitColMode: 1 + - _Scroll_EmissiveU: 0 + - _Scroll_EmissiveV: 0 + - _Set_SystemShadowsToBase: 1 + - _ShadeColor_Step: 0.33 + - _Smoothness: 0 + - _SmoothnessTextureChannel: 0 + - _SpecularHighlights: 1 + - _SrcBlend: 1 + - _StencilComp: 0 + - _StencilMode: 0 + - _StencilNo: 1 + - _StencilOpFail: 0 + - _StencilOpPass: 0 + - _StencilRef: 0 + - _StencilRefDepth: 8 + - _StencilRefDistortionVec: 4 + - _StencilRefGBuffer: 10 + - _StencilRefMV: 40 + - _StencilWriteMask: 6 + - _StencilWriteMaskDepth: 8 + - _StencilWriteMaskDistortionVec: 4 + - _StencilWriteMaskGBuffer: 14 + - _StencilWriteMaskMV: 40 + - _StepOffset: 0.04 + - _SupportDecals: 1 + - _SurfaceType: 0 + - _TessEdgeLength: 5 + - _TessExtrusionAmount: 0 + - _TessPhongStrength: 0.5 + - _TransparentBackfaceEnable: 0 + - _TransparentCullMode: 2 + - _TransparentDepthPostpassEnable: 0 + - _TransparentDepthPrepassEnable: 0 + - _TransparentEnabled: 0 + - _TransparentSortPriority: 0 + - _TransparentWritingMotionVec: 0 + - _TransparentZWrite: 0 + - _TweakHighColorOnShadow: 0 + - _TweakMatCapOnShadow: 0 + - _Tweak_HighColorMaskLevel: 0 + - _Tweak_LightDirection_MaskLevel: 0 + - _Tweak_MatCapUV: 0 + - _Tweak_MatcapMaskLevel: 0 + - _Tweak_RimLightMaskLevel: 0 + - _Tweak_ShadingGradeMapLevel: 0 + - _Tweak_SystemShadowsLevel: -0.5 + - _Tweak_transparency: 0 + - _UVSec: 0 + - _Unlit_Intensity: 1 + - _UseShadowThreshold: 0 + - _Use_1stAs2nd: 1 + - _Use_BaseAs1st: 1 + - _ZOverDrawMode: 0 + - _ZTestDepthEqualForOpaque: 3 + - _ZTestGBuffer: 4 + - _ZTestTransparent: 4 + - _ZWrite: 1 + - _ZWriteMode: 1 + - _simpleUI: 0 + - _utsTechnique: 1 + - _utsVersion: 2.07 + - _utsVersionX: 2 + - _utsVersionY: 2 + - _utsVersionZ: 0 + m_Colors: + - _1st_ShadeColor: {r: 0.49264705, g: 0.304282, b: 0.304282, a: 1} + - _2nd_ShadeColor: {r: 0.50735295, g: 0.39543685, b: 0.4533245, a: 1} + - _AngelRing_Color: {r: 1, g: 1, b: 1, a: 1} + - _Ap_RimLightColor: {r: 1, g: 0.80689657, b: 0, a: 1} + - _BaseColor: {r: 0.9433962, g: 0.9137382, b: 0.7698469, a: 1} + - _Color: {r: 0.990566, g: 0.83280253, b: 0.6952652, a: 1} + - _ColorShift: {r: 0, g: 0, b: 0, a: 1} + - _DoubleSidedConstants: {r: 1, g: 1, b: -1, a: 0} + - _EmissionColor: {r: 1, g: 1, b: 1, a: 1} + - _Emissive_Color: {r: 0.21323532, g: 0, b: 0, a: 1} + - _HighColor: {r: 0, g: 0, b: 0, a: 1} + - _MatCapColor: {r: 1, g: 1, b: 1, a: 1} + - _Outline_Color: {r: 0.5294118, g: 0.22352937, b: 0.34159288, a: 1} + - _RimLightColor: {r: 1, g: 0, b: 0, a: 1} + - _Tiling: {r: 1, g: 1, b: 0, a: 0} + - _ViewShift: {r: 0, g: 0, b: 0, a: 1} + m_BuildTextureStacks: [] + m_AllowLocking: 1 +--- !u!114 &1856632363856593404 +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: da692e001514ec24dbc4cca1949ff7e8, type: 3} + m_Name: + m_EditorClassIdentifier: + version: 12 + hdPluginSubTargetMaterialVersions: + m_Keys: [] + m_Values: diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Face.mat.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Face.mat.meta new file mode 100644 index 00000000..c70fa8ce --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Face.mat.meta @@ -0,0 +1,16 @@ +fileFormatVersion: 2 +guid: 4bfb8e345eea4574ea3848039a393243 +timeCreated: 1544184610 +licenseType: Store +NativeFormatImporter: + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Face.mat + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Hair.mat b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Hair.mat new file mode 100644 index 00000000..bc323c93 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Hair.mat @@ -0,0 +1,405 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &-3276637965404939782 +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: 639247ca83abc874e893eb93af2b5e44, type: 3} + m_Name: + m_EditorClassIdentifier: + version: 0 +--- !u!21 &2100000 +Material: + serializedVersion: 8 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: Hair + m_Shader: {fileID: -6465566751694194690, guid: e0b73429f84a56840ba17b216237f806, type: 3} + m_Parent: {fileID: 0} + m_ModifiedSerializedProperties: 0 + m_ValidKeywords: [] + m_InvalidKeywords: + - _DISABLE_SSR_TRANSPARENT + m_LightmapFlags: 4 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: 2000 + stringTagMap: + IgnoreProjection: False + disabledShaderPasses: + - TransparentDepthPrepass + - TransparentDepthPostpass + - TransparentBackface + - RayTracingPrepass + - MOTIONVECTORS + m_LockedProperties: + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _1st_ShadeMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _2nd_ShadeMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _AngelRing_Sampler: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BakedNormal: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BaseMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ClippingMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailAlbedoMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Emissive_Tex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _HighColor_Tex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MatCap_Sampler: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _NormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _NormalMapForMatCap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OcclusionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OutlineTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Outline_Sampler: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Set_1st_ShadePosition: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Set_2nd_ShadePosition: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Set_HighColorMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Set_MatcapMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Set_RimLightMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ShadingGradeMap: + m_Texture: {fileID: 2800000, guid: 0620c25d224d4d543936ec89321802b6, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_Lightmaps: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_LightmapsInd: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_ShadowMasks: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Ints: [] + m_Floats: + - _1st2nd_Shades_Feather: 0.591 + - _1st_ShadeColor_Feather: 0.307 + - _1st_ShadeColor_Step: 0.67 + - _2nd_ShadeColor_Feather: 0.591 + - _2nd_ShadeColor_Step: 0.55 + - _ARSampler_AlphaOn: 0 + - _AR_OffsetU: 0 + - _AR_OffsetV: 0.3 + - _AddPrecomputedVelocity: 0 + - _Add_Antipodean_RimLight: 0 + - _AlphaCutoffEnable: 0 + - _AlphaDstBlend: 0 + - _AlphaSrcBlend: 1 + - _AlphaToMask: 0 + - _AlphaToMaskInspectorValue: 0 + - _AngelRing: 0 + - _Ap_RimLight_FeatherOff: 0 + - _Ap_RimLight_Power: 0.1 + - _AutoRenderQueue: 1 + - _BUILTIN_QueueControl: 1 + - _BUILTIN_QueueOffset: 0 + - _BaseColor_Step: 0.67 + - _BaseShade_Feather: 0.307 + - _Base_Speed: 0 + - _BlendMode: 0 + - _BlurLevelMatcap: 0 + - _BlurLevelSGM: 0 + - _BumpScale: 1 + - _BumpScaleMatcap: 1 + - _CameraRolling_Stabilizer: 0 + - _ClippingMode: 0 + - _Clipping_Level: 0 + - _ColorBoost: 1 + - _ColorShift_Speed: 0 + - _ConservativeDepthOffsetEnable: 0 + - _CullMode: 2 + - _CullModeForward: 2 + - _Cutoff: 0.5 + - _DepthOffsetEnable: 0 + - _DetailNormalMapScale: 1 + - _DoubleSidedEnable: 0 + - _DoubleSidedGIMode: 0 + - _DoubleSidedNormalMode: 2 + - _DstBlend: 0 + - _EMISSIVE: 0 + - _EnableBlendModePreserveSpecularLighting: 1 + - _EnableFogOnTransparent: 1 + - _Farthest_Distance: 0 + - _GI_Intensity: 0 + - _GlossMapScale: 1 + - _Glossiness: 0 + - _GlossyReflections: 1 + - _HighColor_Power: 0 + - _Inverse_Clipping: 0 + - _Inverse_MatcapMask: 0 + - _Inverse_Z_Axis_BLD: 1 + - _IsBaseMapAlphaAsClippingMask: 0 + - _Is_1st_ShadeColorOnly: 0 + - _Is_BLD: 0 + - _Is_BakedNormal: 0 + - _Is_BlendAddToHiColor: 0 + - _Is_BlendAddToMatCap: 1 + - _Is_BlendBaseColor: 1 + - _Is_ColorShift: 0 + - _Is_Filter_HiCutPointLightColor: 1 + - _Is_Filter_LightColor: 0 + - _Is_LightColor_1st_Shade: 1 + - _Is_LightColor_2nd_Shade: 1 + - _Is_LightColor_AR: 1 + - _Is_LightColor_Ap_RimLight: 1 + - _Is_LightColor_Base: 1 + - _Is_LightColor_HighColor: 1 + - _Is_LightColor_MatCap: 1 + - _Is_LightColor_Outline: 0 + - _Is_LightColor_RimLight: 1 + - _Is_NormalMap: 0 + - _Is_NormalMapForMatCap: 0 + - _Is_NormalMapToBase: 0 + - _Is_NormalMapToHighColor: 0 + - _Is_NormalMapToRimLight: 0 + - _Is_Ortho: 0 + - _Is_OutlineTex: 0 + - _Is_PingPong_Base: 0 + - _Is_SpecularToHighColor: 0 + - _Is_UseTweakHighColorOnShadow: 0 + - _Is_UseTweakMatCapOnShadow: 0 + - _Is_ViewCoord_Scroll: 0 + - _Is_ViewShift: 0 + - _LightDirection_MaskOn: 0 + - _MatCap: 0 + - _Metallic: 0 + - _Mode: 0 + - _Nearest_Distance: 1 + - _OUTLINE: 0 + - _OcclusionStrength: 1 + - _Offset_X_Axis_BLD: -0.05 + - _Offset_Y_Axis_BLD: 0.09 + - _Offset_Z: 1 + - _OpaqueCullMode: 2 + - _Outline_Width: 1.58 + - _Parallax: 0.02 + - _QueueControl: 0 + - _QueueOffset: 0 + - _RayTracing: 0 + - _ReceivesSSR: 1 + - _ReceivesSSRTransparent: 0 + - _RefractionModel: 0 + - _RenderQueueType: 1 + - _RequireSplitLighting: 0 + - _RimLight: 0 + - _RimLight_FeatherOff: 0 + - _RimLight_InsideMask: 0.0001 + - _RimLight_Power: 0.1 + - _Rotate_EmissiveUV: 0 + - _Rotate_MatCapUV: 0 + - _Rotate_NormalMapForMatCapUV: 0 + - _SPRDefaultUnlitColorMask: 15 + - _SRPDefaultUnlitColMode: 1 + - _Scroll_EmissiveU: 0 + - _Scroll_EmissiveV: 0 + - _Set_SystemShadowsToBase: 1 + - _ShadeColor_Step: 0.55 + - _Smoothness: 0 + - _SmoothnessTextureChannel: 0 + - _SpecularHighlights: 1 + - _SrcBlend: 1 + - _StencilComp: 0 + - _StencilMode: 0 + - _StencilNo: 1 + - _StencilOpFail: 0 + - _StencilOpPass: 0 + - _StencilRef: 0 + - _StencilRefDepth: 8 + - _StencilRefDistortionVec: 4 + - _StencilRefGBuffer: 10 + - _StencilRefMV: 40 + - _StencilWriteMask: 6 + - _StencilWriteMaskDepth: 8 + - _StencilWriteMaskDistortionVec: 4 + - _StencilWriteMaskGBuffer: 14 + - _StencilWriteMaskMV: 40 + - _StepOffset: 0 + - _SupportDecals: 1 + - _SurfaceType: 0 + - _TessEdgeLength: 5 + - _TessExtrusionAmount: 0 + - _TessPhongStrength: 0.5 + - _TransparentBackfaceEnable: 0 + - _TransparentCullMode: 2 + - _TransparentDepthPostpassEnable: 0 + - _TransparentDepthPrepassEnable: 0 + - _TransparentEnabled: 0 + - _TransparentSortPriority: 0 + - _TransparentWritingMotionVec: 0 + - _TransparentZWrite: 0 + - _TweakHighColorOnShadow: 0 + - _TweakMatCapOnShadow: 0 + - _Tweak_HighColorMaskLevel: 0 + - _Tweak_LightDirection_MaskLevel: 0 + - _Tweak_MatCapUV: 0 + - _Tweak_MatcapMaskLevel: 0 + - _Tweak_RimLightMaskLevel: 0 + - _Tweak_ShadingGradeMapLevel: 0 + - _Tweak_SystemShadowsLevel: 0 + - _Tweak_transparency: 0 + - _UVSec: 0 + - _Unlit_Intensity: 1 + - _UseShadowThreshold: 0 + - _Use_1stAs2nd: 1 + - _Use_BaseAs1st: 1 + - _ZOverDrawMode: 0 + - _ZTestDepthEqualForOpaque: 3 + - _ZTestGBuffer: 4 + - _ZTestTransparent: 4 + - _ZWrite: 1 + - _ZWriteMode: 1 + - _simpleUI: 0 + - _utsTechnique: 1 + - _utsVersion: 2.07 + - _utsVersionX: 2 + - _utsVersionY: 2 + - _utsVersionZ: 0 + m_Colors: + - _1st_ShadeColor: {r: 0.745283, g: 0.58061665, b: 0.46755964, a: 1} + - _2nd_ShadeColor: {r: 0.37334698, g: 0.29411766, b: 0.40392157, a: 1} + - _AngelRing_Color: {r: 1, g: 1, b: 1, a: 1} + - _Ap_RimLightColor: {r: 1, g: 1, b: 1, a: 1} + - _BaseColor: {r: 0.8962264, g: 0.83836275, b: 0.58762014, a: 1} + - _Color: {r: 0.8962264, g: 0.8383627, b: 0.58762014, a: 1} + - _ColorShift: {r: 0, g: 0, b: 0, a: 1} + - _DoubleSidedConstants: {r: 1, g: 1, b: -1, a: 0} + - _EmissionColor: {r: 1, g: 1, b: 1, a: 1} + - _Emissive_Color: {r: 0, g: 0, b: 0, a: 1} + - _HighColor: {r: 0, g: 0, b: 0, a: 1} + - _MatCapColor: {r: 1, g: 1, b: 1, a: 1} + - _Outline_Color: {r: 0.6792453, g: 0.1505874, b: 0.1505874, a: 1} + - _RimLightColor: {r: 1, g: 1, b: 1, a: 1} + - _Tiling: {r: 1, g: 1, b: 0, a: 0} + - _ViewShift: {r: 0, g: 0, b: 0, a: 1} + m_BuildTextureStacks: [] + m_AllowLocking: 1 +--- !u!114 &5923415025961005905 +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 &6202150226457244543 +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: da692e001514ec24dbc4cca1949ff7e8, type: 3} + m_Name: + m_EditorClassIdentifier: + version: 12 + hdPluginSubTargetMaterialVersions: + m_Keys: [] + m_Values: diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Hair.mat.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Hair.mat.meta new file mode 100644 index 00000000..0d86b7e9 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Hair.mat.meta @@ -0,0 +1,16 @@ +fileFormatVersion: 2 +guid: 8d079bda1b056ab40aa9dc79da22441f +timeCreated: 1544072709 +licenseType: Store +NativeFormatImporter: + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Hair.mat + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/HairPony.mat b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/HairPony.mat new file mode 100644 index 00000000..b784c4d1 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/HairPony.mat @@ -0,0 +1,405 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &-8801799964885519558 +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 &-7482000731104837112 +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: 639247ca83abc874e893eb93af2b5e44, type: 3} + m_Name: + m_EditorClassIdentifier: + version: 0 +--- !u!21 &2100000 +Material: + serializedVersion: 8 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: HairPony + m_Shader: {fileID: -6465566751694194690, guid: e0b73429f84a56840ba17b216237f806, type: 3} + m_Parent: {fileID: 0} + m_ModifiedSerializedProperties: 0 + m_ValidKeywords: [] + m_InvalidKeywords: + - _DISABLE_SSR_TRANSPARENT + m_LightmapFlags: 4 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: 2000 + stringTagMap: + IgnoreProjection: False + disabledShaderPasses: + - TransparentDepthPrepass + - TransparentDepthPostpass + - TransparentBackface + - RayTracingPrepass + - MOTIONVECTORS + m_LockedProperties: + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _1st_ShadeMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _2nd_ShadeMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _AngelRing_Sampler: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BakedNormal: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BaseMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ClippingMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailAlbedoMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Emissive_Tex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _HighColor_Tex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MatCap_Sampler: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _NormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _NormalMapForMatCap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OcclusionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OutlineTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Outline_Sampler: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Set_1st_ShadePosition: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Set_2nd_ShadePosition: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Set_HighColorMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Set_MatcapMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Set_RimLightMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ShadingGradeMap: + m_Texture: {fileID: 2800000, guid: 0620c25d224d4d543936ec89321802b6, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_Lightmaps: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_LightmapsInd: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_ShadowMasks: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Ints: [] + m_Floats: + - _1st2nd_Shades_Feather: 0.625 + - _1st_ShadeColor_Feather: 0.055 + - _1st_ShadeColor_Step: 0.798 + - _2nd_ShadeColor_Feather: 0.625 + - _2nd_ShadeColor_Step: 0.625 + - _ARSampler_AlphaOn: 0 + - _AR_OffsetU: 0 + - _AR_OffsetV: 0.3 + - _AddPrecomputedVelocity: 0 + - _Add_Antipodean_RimLight: 0 + - _AlphaCutoffEnable: 0 + - _AlphaDstBlend: 0 + - _AlphaSrcBlend: 1 + - _AlphaToMask: 0 + - _AlphaToMaskInspectorValue: 0 + - _AngelRing: 0 + - _Ap_RimLight_FeatherOff: 0 + - _Ap_RimLight_Power: 0.1 + - _AutoRenderQueue: 1 + - _BUILTIN_QueueControl: 1 + - _BUILTIN_QueueOffset: 0 + - _BaseColor_Step: 0.798 + - _BaseShade_Feather: 0.055 + - _Base_Speed: 0 + - _BlendMode: 0 + - _BlurLevelMatcap: 0 + - _BlurLevelSGM: 0 + - _BumpScale: 1 + - _BumpScaleMatcap: 1 + - _CameraRolling_Stabilizer: 0 + - _ClippingMode: 0 + - _Clipping_Level: 0 + - _ColorBoost: 1 + - _ColorShift_Speed: 0 + - _ConservativeDepthOffsetEnable: 0 + - _CullMode: 2 + - _CullModeForward: 2 + - _Cutoff: 0.5 + - _DepthOffsetEnable: 0 + - _DetailNormalMapScale: 1 + - _DoubleSidedEnable: 0 + - _DoubleSidedGIMode: 0 + - _DoubleSidedNormalMode: 2 + - _DstBlend: 0 + - _EMISSIVE: 0 + - _EnableBlendModePreserveSpecularLighting: 1 + - _EnableFogOnTransparent: 1 + - _Farthest_Distance: 0 + - _GI_Intensity: 0 + - _GlossMapScale: 1 + - _Glossiness: 0.5 + - _GlossyReflections: 1 + - _HighColor_Power: 0 + - _Inverse_Clipping: 0 + - _Inverse_MatcapMask: 0 + - _Inverse_Z_Axis_BLD: 1 + - _IsBaseMapAlphaAsClippingMask: 0 + - _Is_1st_ShadeColorOnly: 0 + - _Is_BLD: 0 + - _Is_BakedNormal: 0 + - _Is_BlendAddToHiColor: 0 + - _Is_BlendAddToMatCap: 1 + - _Is_BlendBaseColor: 1 + - _Is_ColorShift: 0 + - _Is_Filter_HiCutPointLightColor: 1 + - _Is_Filter_LightColor: 0 + - _Is_LightColor_1st_Shade: 1 + - _Is_LightColor_2nd_Shade: 1 + - _Is_LightColor_AR: 1 + - _Is_LightColor_Ap_RimLight: 1 + - _Is_LightColor_Base: 1 + - _Is_LightColor_HighColor: 1 + - _Is_LightColor_MatCap: 1 + - _Is_LightColor_Outline: 0 + - _Is_LightColor_RimLight: 1 + - _Is_NormalMap: 0 + - _Is_NormalMapForMatCap: 0 + - _Is_NormalMapToBase: 0 + - _Is_NormalMapToHighColor: 0 + - _Is_NormalMapToRimLight: 0 + - _Is_Ortho: 0 + - _Is_OutlineTex: 0 + - _Is_PingPong_Base: 0 + - _Is_SpecularToHighColor: 0 + - _Is_UseTweakHighColorOnShadow: 0 + - _Is_UseTweakMatCapOnShadow: 0 + - _Is_ViewCoord_Scroll: 0 + - _Is_ViewShift: 0 + - _LightDirection_MaskOn: 0 + - _MatCap: 0 + - _Metallic: 0 + - _Mode: 0 + - _Nearest_Distance: 1 + - _OUTLINE: 0 + - _OcclusionStrength: 1 + - _Offset_X_Axis_BLD: -0.05 + - _Offset_Y_Axis_BLD: 0.09 + - _Offset_Z: 25 + - _OpaqueCullMode: 2 + - _Outline_Width: 2.32 + - _Parallax: 0.02 + - _QueueControl: 0 + - _QueueOffset: 0 + - _RayTracing: 0 + - _ReceivesSSR: 1 + - _ReceivesSSRTransparent: 0 + - _RefractionModel: 0 + - _RenderQueueType: 1 + - _RequireSplitLighting: 0 + - _RimLight: 0 + - _RimLight_FeatherOff: 0 + - _RimLight_InsideMask: 0.0001 + - _RimLight_Power: 0.1 + - _Rotate_EmissiveUV: 0 + - _Rotate_MatCapUV: 0 + - _Rotate_NormalMapForMatCapUV: 0 + - _SPRDefaultUnlitColorMask: 15 + - _SRPDefaultUnlitColMode: 1 + - _Scroll_EmissiveU: 0 + - _Scroll_EmissiveV: 0 + - _Set_SystemShadowsToBase: 1 + - _ShadeColor_Step: 0.625 + - _Smoothness: 0 + - _SmoothnessTextureChannel: 0 + - _SpecularHighlights: 1 + - _SrcBlend: 1 + - _StencilComp: 0 + - _StencilMode: 0 + - _StencilNo: 1 + - _StencilOpFail: 0 + - _StencilOpPass: 0 + - _StencilRef: 0 + - _StencilRefDepth: 8 + - _StencilRefDistortionVec: 4 + - _StencilRefGBuffer: 10 + - _StencilRefMV: 40 + - _StencilWriteMask: 6 + - _StencilWriteMaskDepth: 8 + - _StencilWriteMaskDistortionVec: 4 + - _StencilWriteMaskGBuffer: 14 + - _StencilWriteMaskMV: 40 + - _StepOffset: 0 + - _SupportDecals: 1 + - _SurfaceType: 0 + - _TessEdgeLength: 5 + - _TessExtrusionAmount: 0 + - _TessPhongStrength: 0.5 + - _TransparentBackfaceEnable: 0 + - _TransparentCullMode: 2 + - _TransparentDepthPostpassEnable: 0 + - _TransparentDepthPrepassEnable: 0 + - _TransparentEnabled: 0 + - _TransparentSortPriority: 0 + - _TransparentWritingMotionVec: 0 + - _TransparentZWrite: 0 + - _TweakHighColorOnShadow: 0 + - _TweakMatCapOnShadow: 0 + - _Tweak_HighColorMaskLevel: 0 + - _Tweak_LightDirection_MaskLevel: 0 + - _Tweak_MatCapUV: 0 + - _Tweak_MatcapMaskLevel: 0 + - _Tweak_RimLightMaskLevel: 0 + - _Tweak_ShadingGradeMapLevel: 0 + - _Tweak_SystemShadowsLevel: 0 + - _Tweak_transparency: 0 + - _UVSec: 0 + - _Unlit_Intensity: 1 + - _UseShadowThreshold: 0 + - _Use_1stAs2nd: 1 + - _Use_BaseAs1st: 1 + - _ZOverDrawMode: 0 + - _ZTestDepthEqualForOpaque: 3 + - _ZTestGBuffer: 4 + - _ZTestTransparent: 4 + - _ZWrite: 1 + - _ZWriteMode: 1 + - _simpleUI: 0 + - _utsTechnique: 1 + - _utsVersion: 2.07 + - _utsVersionX: 2 + - _utsVersionY: 2 + - _utsVersionZ: 0 + m_Colors: + - _1st_ShadeColor: {r: 0.745283, g: 0.58061665, b: 0.46755964, a: 1} + - _2nd_ShadeColor: {r: 0.37334698, g: 0.29411766, b: 0.40392157, a: 1} + - _AngelRing_Color: {r: 1, g: 1, b: 1, a: 1} + - _Ap_RimLightColor: {r: 1, g: 1, b: 1, a: 1} + - _BaseColor: {r: 0.8962264, g: 0.83836275, b: 0.58762014, a: 1} + - _Color: {r: 0.8962264, g: 0.8383627, b: 0.58762014, a: 1} + - _ColorShift: {r: 0, g: 0, b: 0, a: 1} + - _DoubleSidedConstants: {r: 1, g: 1, b: -1, a: 0} + - _EmissionColor: {r: 1, g: 1, b: 1, a: 1} + - _Emissive_Color: {r: 0, g: 0, b: 0, a: 1} + - _HighColor: {r: 0, g: 0, b: 0, a: 1} + - _MatCapColor: {r: 1, g: 1, b: 1, a: 1} + - _Outline_Color: {r: 0.6792453, g: 0.1505874, b: 0.1505874, a: 1} + - _RimLightColor: {r: 1, g: 1, b: 1, a: 1} + - _Tiling: {r: 1, g: 1, b: 0, a: 0} + - _ViewShift: {r: 0, g: 0, b: 0, a: 1} + m_BuildTextureStacks: [] + m_AllowLocking: 1 +--- !u!114 &6789783673373974753 +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: da692e001514ec24dbc4cca1949ff7e8, type: 3} + m_Name: + m_EditorClassIdentifier: + version: 12 + hdPluginSubTargetMaterialVersions: + m_Keys: [] + m_Values: diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/HairPony.mat.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/HairPony.mat.meta new file mode 100644 index 00000000..702688ca --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/HairPony.mat.meta @@ -0,0 +1,16 @@ +fileFormatVersion: 2 +guid: 3ef43a7ac036e284a87d9da91a23d66d +timeCreated: 1544072709 +licenseType: Store +NativeFormatImporter: + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/HairPony.mat + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Headgear.mat b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Headgear.mat new file mode 100644 index 00000000..30426bb6 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Headgear.mat @@ -0,0 +1,405 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &-2815431603641581785 +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 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: Headgear + m_Shader: {fileID: -6465566751694194690, guid: e0b73429f84a56840ba17b216237f806, type: 3} + m_Parent: {fileID: 0} + m_ModifiedSerializedProperties: 0 + m_ValidKeywords: [] + m_InvalidKeywords: + - _DISABLE_SSR_TRANSPARENT + m_LightmapFlags: 4 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: 2000 + stringTagMap: + IgnoreProjection: False + disabledShaderPasses: + - TransparentDepthPrepass + - TransparentDepthPostpass + - TransparentBackface + - RayTracingPrepass + - MOTIONVECTORS + m_LockedProperties: + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _1st_ShadeMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _2nd_ShadeMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _AngelRing_Sampler: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BakedNormal: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BaseMap: + m_Texture: {fileID: 2800000, guid: 1c7c498cd2a3d8a469703921d8e5a9c6, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ClippingMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailAlbedoMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Emissive_Tex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _HighColor_Tex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main: + m_Texture: {fileID: 2800000, guid: a4a14922fc4479241aef660b68c498f5, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 2800000, guid: a4a14922fc4479241aef660b68c498f5, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MatCap_Sampler: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _NormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _NormalMapForMatCap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OcclusionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OutlineTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Outline_Sampler: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Set_1st_ShadePosition: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Set_2nd_ShadePosition: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Set_HighColorMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Set_MatcapMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Set_RimLightMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ShadingGradeMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_Lightmaps: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_LightmapsInd: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_ShadowMasks: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Ints: [] + m_Floats: + - _1st2nd_Shades_Feather: 0.776 + - _1st_ShadeColor_Feather: 0.316 + - _1st_ShadeColor_Step: 0.56 + - _2nd_ShadeColor_Feather: 0.776 + - _2nd_ShadeColor_Step: 0.619 + - _ARSampler_AlphaOn: 0 + - _AR_OffsetU: 0 + - _AR_OffsetV: 0.3 + - _AddPrecomputedVelocity: 0 + - _Add_Antipodean_RimLight: 0 + - _AlphaCutoffEnable: 0 + - _AlphaDstBlend: 0 + - _AlphaSrcBlend: 1 + - _AlphaToMask: 0 + - _AlphaToMaskInspectorValue: 0 + - _AngelRing: 0 + - _Ap_RimLight_FeatherOff: 0 + - _Ap_RimLight_Power: 0.1 + - _AutoRenderQueue: 1 + - _BUILTIN_QueueControl: 1 + - _BUILTIN_QueueOffset: 0 + - _BaseColor_Step: 0.56 + - _BaseShade_Feather: 0.316 + - _Base_Speed: 0 + - _BlendMode: 0 + - _BlurLevelMatcap: 0 + - _BlurLevelSGM: 0 + - _BumpScale: 1 + - _BumpScaleMatcap: 1 + - _CameraRolling_Stabilizer: 0 + - _ClippingMode: 0 + - _Clipping_Level: 0 + - _ColorBoost: 1 + - _ColorShift_Speed: 0 + - _ConservativeDepthOffsetEnable: 0 + - _CullMode: 2 + - _CullModeForward: 2 + - _Cutoff: 0.5 + - _DepthOffsetEnable: 0 + - _DetailNormalMapScale: 1 + - _DoubleSidedEnable: 0 + - _DoubleSidedGIMode: 0 + - _DoubleSidedNormalMode: 2 + - _DstBlend: 0 + - _EMISSIVE: 0 + - _EnableBlendModePreserveSpecularLighting: 1 + - _EnableFogOnTransparent: 1 + - _Farthest_Distance: 0 + - _GI_Intensity: 0 + - _GlossMapScale: 1 + - _Glossiness: 0 + - _GlossyReflections: 1 + - _HighColor_Power: 0 + - _Inverse_Clipping: 0 + - _Inverse_MatcapMask: 0 + - _Inverse_Z_Axis_BLD: 1 + - _IsBaseMapAlphaAsClippingMask: 0 + - _Is_1st_ShadeColorOnly: 0 + - _Is_BLD: 0 + - _Is_BakedNormal: 0 + - _Is_BlendAddToHiColor: 0 + - _Is_BlendAddToMatCap: 1 + - _Is_BlendBaseColor: 1 + - _Is_ColorShift: 0 + - _Is_Filter_HiCutPointLightColor: 1 + - _Is_Filter_LightColor: 0 + - _Is_LightColor_1st_Shade: 1 + - _Is_LightColor_2nd_Shade: 1 + - _Is_LightColor_AR: 1 + - _Is_LightColor_Ap_RimLight: 1 + - _Is_LightColor_Base: 1 + - _Is_LightColor_HighColor: 1 + - _Is_LightColor_MatCap: 1 + - _Is_LightColor_Outline: 1 + - _Is_LightColor_RimLight: 1 + - _Is_NormalMap: 0 + - _Is_NormalMapForMatCap: 0 + - _Is_NormalMapToBase: 0 + - _Is_NormalMapToHighColor: 0 + - _Is_NormalMapToRimLight: 0 + - _Is_Ortho: 0 + - _Is_OutlineTex: 0 + - _Is_PingPong_Base: 0 + - _Is_SpecularToHighColor: 0 + - _Is_UseTweakHighColorOnShadow: 0 + - _Is_UseTweakMatCapOnShadow: 0 + - _Is_ViewCoord_Scroll: 0 + - _Is_ViewShift: 0 + - _LightDirection_MaskOn: 0 + - _MatCap: 0 + - _Metallic: 0 + - _Mode: 0 + - _Nearest_Distance: 1 + - _OUTLINE: 0 + - _OcclusionStrength: 1 + - _Offset_X_Axis_BLD: -0.05 + - _Offset_Y_Axis_BLD: 0.09 + - _Offset_Z: 0 + - _OpaqueCullMode: 2 + - _Outline_Width: 1.5 + - _Parallax: 0.02 + - _QueueControl: 0 + - _QueueOffset: 0 + - _RayTracing: 0 + - _ReceivesSSR: 1 + - _ReceivesSSRTransparent: 0 + - _RefractionModel: 0 + - _RenderQueueType: 1 + - _RequireSplitLighting: 0 + - _RimLight: 0 + - _RimLight_FeatherOff: 0 + - _RimLight_InsideMask: 0.0001 + - _RimLight_Power: 0.1 + - _Rotate_EmissiveUV: 0 + - _Rotate_MatCapUV: 0 + - _Rotate_NormalMapForMatCapUV: 0 + - _SPRDefaultUnlitColorMask: 15 + - _SRPDefaultUnlitColMode: 1 + - _Scroll_EmissiveU: 0 + - _Scroll_EmissiveV: 0 + - _Set_SystemShadowsToBase: 1 + - _ShadeColor_Step: 0.619 + - _Smoothness: 0 + - _SmoothnessTextureChannel: 0 + - _SpecularHighlights: 1 + - _SrcBlend: 1 + - _StencilComp: 0 + - _StencilMode: 0 + - _StencilNo: 1 + - _StencilOpFail: 0 + - _StencilOpPass: 0 + - _StencilRef: 0 + - _StencilRefDepth: 8 + - _StencilRefDistortionVec: 4 + - _StencilRefGBuffer: 10 + - _StencilRefMV: 40 + - _StencilWriteMask: 6 + - _StencilWriteMaskDepth: 8 + - _StencilWriteMaskDistortionVec: 4 + - _StencilWriteMaskGBuffer: 14 + - _StencilWriteMaskMV: 40 + - _StepOffset: 0 + - _SupportDecals: 1 + - _SurfaceType: 0 + - _TessEdgeLength: 5 + - _TessExtrusionAmount: 0 + - _TessPhongStrength: 0.5 + - _TransparentBackfaceEnable: 0 + - _TransparentCullMode: 2 + - _TransparentDepthPostpassEnable: 0 + - _TransparentDepthPrepassEnable: 0 + - _TransparentEnabled: 0 + - _TransparentSortPriority: 0 + - _TransparentWritingMotionVec: 0 + - _TransparentZWrite: 0 + - _TweakHighColorOnShadow: 0 + - _TweakMatCapOnShadow: 0 + - _Tweak_HighColorMaskLevel: 0 + - _Tweak_LightDirection_MaskLevel: 0 + - _Tweak_MatCapUV: 0 + - _Tweak_MatcapMaskLevel: 0 + - _Tweak_RimLightMaskLevel: 0 + - _Tweak_ShadingGradeMapLevel: 0 + - _Tweak_SystemShadowsLevel: 0 + - _Tweak_transparency: 0 + - _UVSec: 0 + - _Unlit_Intensity: 1 + - _UseShadowThreshold: 0 + - _Use_1stAs2nd: 1 + - _Use_BaseAs1st: 1 + - _ZOverDrawMode: 0 + - _ZTestDepthEqualForOpaque: 3 + - _ZTestGBuffer: 4 + - _ZTestTransparent: 4 + - _ZWrite: 1 + - _ZWriteMode: 1 + - _simpleUI: 0 + - _utsTechnique: 1 + - _utsVersion: 2.07 + - _utsVersionX: 2 + - _utsVersionY: 2 + - _utsVersionZ: 0 + m_Colors: + - _1st_ShadeColor: {r: 0.5580278, g: 0.6476488, b: 0.7169812, a: 1} + - _2nd_ShadeColor: {r: 0.2654909, g: 0.2524475, b: 0.2924528, a: 1} + - _AngelRing_Color: {r: 1, g: 1, b: 1, a: 1} + - _Ap_RimLightColor: {r: 1, g: 1, b: 1, a: 1} + - _BaseColor: {r: 1, g: 1, b: 1, a: 1} + - _Color: {r: 1, g: 1, b: 1, a: 1} + - _ColorShift: {r: 0, g: 0, b: 0, a: 1} + - _DoubleSidedConstants: {r: 1, g: 1, b: -1, a: 0} + - _EmissionColor: {r: 1, g: 1, b: 1, a: 1} + - _Emissive_Color: {r: 0, g: 0, b: 0, a: 1} + - _HighColor: {r: 0, g: 0, b: 0, a: 1} + - _MatCapColor: {r: 1, g: 1, b: 1, a: 1} + - _Outline_Color: {r: 0.4056604, g: 0.33340088, b: 0.2238786, a: 1} + - _RimLightColor: {r: 1, g: 1, b: 1, a: 1} + - _Tiling: {r: 1, g: 1, b: 0, a: 0} + - _ViewShift: {r: 0, g: 0, b: 0, a: 1} + m_BuildTextureStacks: [] + m_AllowLocking: 1 +--- !u!114 &4572752908142662559 +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: 639247ca83abc874e893eb93af2b5e44, type: 3} + m_Name: + m_EditorClassIdentifier: + version: 0 +--- !u!114 &7100622548993059210 +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: da692e001514ec24dbc4cca1949ff7e8, type: 3} + m_Name: + m_EditorClassIdentifier: + version: 12 + hdPluginSubTargetMaterialVersions: + m_Keys: [] + m_Values: diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Headgear.mat.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Headgear.mat.meta new file mode 100644 index 00000000..23aa5060 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Headgear.mat.meta @@ -0,0 +1,16 @@ +fileFormatVersion: 2 +guid: c16b248a968fde5488f78283549588ca +timeCreated: 1544072709 +licenseType: Store +NativeFormatImporter: + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Headgear.mat + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/LongSleeve Back.mat b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/LongSleeve Back.mat new file mode 100644 index 00000000..36abf9be --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/LongSleeve Back.mat @@ -0,0 +1,405 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 8 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: LongSleeve Back + m_Shader: {fileID: -6465566751694194690, guid: e0b73429f84a56840ba17b216237f806, type: 3} + m_Parent: {fileID: 0} + m_ModifiedSerializedProperties: 0 + m_ValidKeywords: [] + m_InvalidKeywords: + - _DISABLE_SSR_TRANSPARENT + m_LightmapFlags: 4 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: 2000 + stringTagMap: + IgnoreProjection: False + disabledShaderPasses: + - TransparentDepthPrepass + - TransparentDepthPostpass + - TransparentBackface + - RayTracingPrepass + - MOTIONVECTORS + m_LockedProperties: + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _1st_ShadeMap: + m_Texture: {fileID: 2800000, guid: f180dfef53ad0924882657e28833a60b, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _2nd_ShadeMap: + m_Texture: {fileID: 2800000, guid: 9cd90983043e3974e971a6c8d66cc42d, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _AngelRing_Sampler: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BakedNormal: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BaseMap: + m_Texture: {fileID: 2800000, guid: d6a0b548a02e12e4e954cb6c5bb20e70, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ClippingMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailAlbedoMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Emissive_Tex: + m_Texture: {fileID: 2800000, guid: dc71d88ff73488f45ac239b21f552745, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _HighColor_Tex: + m_Texture: {fileID: 2800000, guid: a01adb17bdc53ba4da348b3cba074154, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 2800000, guid: d1e50199c6f08ed46bf2d136ab225409, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MatCap_Sampler: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _NormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _NormalMapForMatCap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OcclusionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OutlineTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Outline_Sampler: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Set_1st_ShadePosition: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Set_2nd_ShadePosition: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Set_HighColorMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Set_MatcapMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Set_RimLightMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ShadingGradeMap: + m_Texture: {fileID: 2800000, guid: 7c75a3dfe8927774ea56a0777d1edcf1, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_Lightmaps: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_LightmapsInd: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_ShadowMasks: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Ints: [] + m_Floats: + - _1st2nd_Shades_Feather: 0.776 + - _1st_ShadeColor_Feather: 0.335 + - _1st_ShadeColor_Step: 0.677 + - _2nd_ShadeColor_Feather: 0.776 + - _2nd_ShadeColor_Step: 0.618 + - _ARSampler_AlphaOn: 0 + - _AR_OffsetU: 0 + - _AR_OffsetV: 0.3 + - _AddPrecomputedVelocity: 0 + - _Add_Antipodean_RimLight: 0 + - _AlphaCutoffEnable: 0 + - _AlphaDstBlend: 0 + - _AlphaSrcBlend: 1 + - _AlphaToMask: 0 + - _AlphaToMaskInspectorValue: 0 + - _AngelRing: 0 + - _Ap_RimLight_FeatherOff: 0 + - _Ap_RimLight_Power: 0.1 + - _AutoRenderQueue: 1 + - _BUILTIN_QueueControl: -1 + - _BUILTIN_QueueOffset: 0 + - _BaseColor_Step: 0.677 + - _BaseShade_Feather: 0.335 + - _Base_Speed: 0 + - _BlendMode: 0 + - _BlurLevelMatcap: 0 + - _BlurLevelSGM: 0 + - _BumpScale: 1 + - _BumpScaleMatcap: 1 + - _CameraRolling_Stabilizer: 0 + - _ClippingMode: 0 + - _Clipping_Level: 0 + - _ColorBoost: 1 + - _ColorShift_Speed: 0 + - _ConservativeDepthOffsetEnable: 0 + - _CullMode: 2 + - _CullModeForward: 2 + - _Cutoff: 0.5 + - _DepthOffsetEnable: 0 + - _DetailNormalMapScale: 1 + - _DoubleSidedEnable: 0 + - _DoubleSidedGIMode: 0 + - _DoubleSidedNormalMode: 2 + - _DstBlend: 0 + - _EMISSIVE: 0 + - _EnableBlendModePreserveSpecularLighting: 1 + - _EnableFogOnTransparent: 1 + - _Farthest_Distance: 0 + - _GI_Intensity: 0 + - _GlossMapScale: 1 + - _Glossiness: 0 + - _GlossyReflections: 1 + - _HighColor_Power: 0.48 + - _Inverse_Clipping: 0 + - _Inverse_MatcapMask: 0 + - _Inverse_Z_Axis_BLD: 1 + - _IsBaseMapAlphaAsClippingMask: 0 + - _Is_1st_ShadeColorOnly: 0 + - _Is_BLD: 0 + - _Is_BakedNormal: 0 + - _Is_BlendAddToHiColor: 1 + - _Is_BlendAddToMatCap: 1 + - _Is_BlendBaseColor: 1 + - _Is_ColorShift: 0 + - _Is_Filter_HiCutPointLightColor: 1 + - _Is_Filter_LightColor: 0 + - _Is_LightColor_1st_Shade: 1 + - _Is_LightColor_2nd_Shade: 1 + - _Is_LightColor_AR: 1 + - _Is_LightColor_Ap_RimLight: 1 + - _Is_LightColor_Base: 1 + - _Is_LightColor_HighColor: 0 + - _Is_LightColor_MatCap: 1 + - _Is_LightColor_Outline: 1 + - _Is_LightColor_RimLight: 1 + - _Is_NormalMap: 0 + - _Is_NormalMapForMatCap: 0 + - _Is_NormalMapToBase: 0 + - _Is_NormalMapToHighColor: 0 + - _Is_NormalMapToRimLight: 0 + - _Is_Ortho: 0 + - _Is_OutlineTex: 1 + - _Is_PingPong_Base: 0 + - _Is_SpecularToHighColor: 0 + - _Is_UseTweakHighColorOnShadow: 0 + - _Is_UseTweakMatCapOnShadow: 0 + - _Is_ViewCoord_Scroll: 0 + - _Is_ViewShift: 0 + - _LightDirection_MaskOn: 0 + - _MatCap: 0 + - _Metallic: 0 + - _Mode: 0 + - _Nearest_Distance: 1 + - _OUTLINE: 0 + - _OcclusionStrength: 1 + - _Offset_X_Axis_BLD: -0.05 + - _Offset_Y_Axis_BLD: 0.09 + - _Offset_Z: 2 + - _OpaqueCullMode: 2 + - _Outline_Width: 1.5 + - _Parallax: 0.02 + - _QueueControl: 0 + - _QueueOffset: 0 + - _RayTracing: 0 + - _ReceivesSSR: 1 + - _ReceivesSSRTransparent: 0 + - _RefractionModel: 0 + - _RenderQueueType: 1 + - _RequireSplitLighting: 0 + - _RimLight: 0 + - _RimLight_FeatherOff: 1 + - _RimLight_InsideMask: 0.47 + - _RimLight_Power: 0.01 + - _Rotate_EmissiveUV: 0 + - _Rotate_MatCapUV: 0 + - _Rotate_NormalMapForMatCapUV: 0 + - _SPRDefaultUnlitColorMask: 15 + - _SRPDefaultUnlitColMode: 1 + - _Scroll_EmissiveU: 0 + - _Scroll_EmissiveV: 0 + - _Set_SystemShadowsToBase: 1 + - _ShadeColor_Step: 0.618 + - _Smoothness: 0 + - _SmoothnessTextureChannel: 0 + - _SpecularHighlights: 1 + - _SrcBlend: 1 + - _StencilComp: 0 + - _StencilMode: 0 + - _StencilNo: 1 + - _StencilOpFail: 0 + - _StencilOpPass: 0 + - _StencilRef: 0 + - _StencilRefDepth: 8 + - _StencilRefDistortionVec: 4 + - _StencilRefGBuffer: 10 + - _StencilRefMV: 40 + - _StencilWriteMask: 6 + - _StencilWriteMaskDepth: 8 + - _StencilWriteMaskDistortionVec: 4 + - _StencilWriteMaskGBuffer: 14 + - _StencilWriteMaskMV: 40 + - _StepOffset: 0 + - _SupportDecals: 1 + - _SurfaceType: 0 + - _TessEdgeLength: 5 + - _TessExtrusionAmount: 0 + - _TessPhongStrength: 0.5 + - _TransparentBackfaceEnable: 0 + - _TransparentCullMode: 2 + - _TransparentDepthPostpassEnable: 0 + - _TransparentDepthPrepassEnable: 0 + - _TransparentEnabled: 0 + - _TransparentSortPriority: 0 + - _TransparentWritingMotionVec: 0 + - _TransparentZWrite: 0 + - _TweakHighColorOnShadow: 0 + - _TweakMatCapOnShadow: 0 + - _Tweak_HighColorMaskLevel: 0 + - _Tweak_LightDirection_MaskLevel: 0 + - _Tweak_MatCapUV: 0 + - _Tweak_MatcapMaskLevel: 0 + - _Tweak_RimLightMaskLevel: 0 + - _Tweak_ShadingGradeMapLevel: 0 + - _Tweak_SystemShadowsLevel: 0 + - _Tweak_transparency: 0 + - _UVSec: 0 + - _Unlit_Intensity: 1 + - _UseShadowThreshold: 0 + - _Use_1stAs2nd: 0 + - _Use_BaseAs1st: 0 + - _ZOverDrawMode: 0 + - _ZTestDepthEqualForOpaque: 3 + - _ZTestGBuffer: 4 + - _ZTestTransparent: 4 + - _ZWrite: 1 + - _ZWriteMode: 1 + - _simpleUI: 2 + - _utsTechnique: 1 + - _utsVersion: 2.07 + - _utsVersionX: 2 + - _utsVersionY: 2 + - _utsVersionZ: 0 + m_Colors: + - _1st_ShadeColor: {r: 1, g: 1, b: 1, a: 1} + - _2nd_ShadeColor: {r: 1, g: 1, b: 1, a: 1} + - _AngelRing_Color: {r: 1, g: 1, b: 1, a: 1} + - _Ap_RimLightColor: {r: 1, g: 1, b: 1, a: 1} + - _BaseColor: {r: 1, g: 1, b: 1, a: 1} + - _Color: {r: 1, g: 1, b: 1, a: 1} + - _ColorShift: {r: 0, g: 0, b: 0, a: 1} + - _DoubleSidedConstants: {r: 1, g: 1, b: -1, a: 0} + - _EmissionColor: {r: 1, g: 1, b: 1, a: 1} + - _Emissive_Color: {r: 5.2780313, g: 5.2780313, b: 5.2780313, a: 1} + - _HighColor: {r: 0.3962264, g: 0.33053476, b: 0.25978997, a: 1} + - _MatCapColor: {r: 1, g: 1, b: 1, a: 1} + - _Outline_Color: {r: 0, g: 0, b: 0, a: 1} + - _RimLightColor: {r: 0, g: 0.8758622, b: 1, a: 1} + - _Tiling: {r: 1, g: 1, b: 0, a: 0} + - _ViewShift: {r: 0, g: 0, b: 0, a: 1} + m_BuildTextureStacks: [] + m_AllowLocking: 1 +--- !u!114 &242505081636331739 +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 &1781190763146025199 +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: da692e001514ec24dbc4cca1949ff7e8, type: 3} + m_Name: + m_EditorClassIdentifier: + version: 12 + hdPluginSubTargetMaterialVersions: + m_Keys: [] + m_Values: +--- !u!114 &6621973610829896646 +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: 639247ca83abc874e893eb93af2b5e44, type: 3} + m_Name: + m_EditorClassIdentifier: + version: 0 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/LongSleeve Back.mat.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/LongSleeve Back.mat.meta new file mode 100644 index 00000000..740db15a --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/LongSleeve Back.mat.meta @@ -0,0 +1,16 @@ +fileFormatVersion: 2 +guid: 1f9555b9b84a8db44b796ecf62912b2a +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/LongSleeve + Back.mat + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/LongSleeve.mat b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/LongSleeve.mat new file mode 100644 index 00000000..cf100497 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/LongSleeve.mat @@ -0,0 +1,405 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &-2573086500142053668 +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: da692e001514ec24dbc4cca1949ff7e8, type: 3} + m_Name: + m_EditorClassIdentifier: + version: 12 + hdPluginSubTargetMaterialVersions: + m_Keys: [] + m_Values: +--- !u!21 &2100000 +Material: + serializedVersion: 8 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: LongSleeve + m_Shader: {fileID: -6465566751694194690, guid: e0b73429f84a56840ba17b216237f806, type: 3} + m_Parent: {fileID: 0} + m_ModifiedSerializedProperties: 0 + m_ValidKeywords: [] + m_InvalidKeywords: + - _DISABLE_SSR_TRANSPARENT + m_LightmapFlags: 4 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: 2000 + stringTagMap: + IgnoreProjection: False + disabledShaderPasses: + - TransparentDepthPrepass + - TransparentDepthPostpass + - TransparentBackface + - RayTracingPrepass + - MOTIONVECTORS + m_LockedProperties: + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _1st_ShadeMap: + m_Texture: {fileID: 2800000, guid: f180dfef53ad0924882657e28833a60b, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _2nd_ShadeMap: + m_Texture: {fileID: 2800000, guid: 9cd90983043e3974e971a6c8d66cc42d, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _AngelRing_Sampler: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BakedNormal: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BaseMap: + m_Texture: {fileID: 2800000, guid: d6a0b548a02e12e4e954cb6c5bb20e70, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ClippingMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailAlbedoMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Emissive_Tex: + m_Texture: {fileID: 2800000, guid: dc71d88ff73488f45ac239b21f552745, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _HighColor_Tex: + m_Texture: {fileID: 2800000, guid: a01adb17bdc53ba4da348b3cba074154, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main: + m_Texture: {fileID: 2800000, guid: d1e50199c6f08ed46bf2d136ab225409, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 2800000, guid: d1e50199c6f08ed46bf2d136ab225409, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MatCap_Sampler: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _NormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _NormalMapForMatCap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OcclusionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OutlineTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Outline_Sampler: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Set_1st_ShadePosition: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Set_2nd_ShadePosition: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Set_HighColorMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Set_MatcapMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Set_RimLightMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ShadingGradeMap: + m_Texture: {fileID: 2800000, guid: 7c75a3dfe8927774ea56a0777d1edcf1, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_Lightmaps: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_LightmapsInd: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_ShadowMasks: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Ints: [] + m_Floats: + - _1st2nd_Shades_Feather: 0.776 + - _1st_ShadeColor_Feather: 0.335 + - _1st_ShadeColor_Step: 0.677 + - _2nd_ShadeColor_Feather: 0.776 + - _2nd_ShadeColor_Step: 0.618 + - _ARSampler_AlphaOn: 0 + - _AR_OffsetU: 0 + - _AR_OffsetV: 0.3 + - _AddPrecomputedVelocity: 0 + - _Add_Antipodean_RimLight: 0 + - _AlphaCutoffEnable: 0 + - _AlphaDstBlend: 0 + - _AlphaSrcBlend: 1 + - _AlphaToMask: 0 + - _AlphaToMaskInspectorValue: 0 + - _AngelRing: 0 + - _Ap_RimLight_FeatherOff: 0 + - _Ap_RimLight_Power: 0.1 + - _AutoRenderQueue: 1 + - _BUILTIN_QueueControl: 1 + - _BUILTIN_QueueOffset: 0 + - _BaseColor_Step: 0.677 + - _BaseShade_Feather: 0.335 + - _Base_Speed: 0 + - _BlendMode: 0 + - _BlurLevelMatcap: 0 + - _BlurLevelSGM: 0 + - _BumpScale: 1 + - _BumpScaleMatcap: 1 + - _CameraRolling_Stabilizer: 0 + - _ClippingMode: 0 + - _Clipping_Level: 0 + - _ColorBoost: 1 + - _ColorShift_Speed: 0 + - _ConservativeDepthOffsetEnable: 0 + - _CullMode: 2 + - _CullModeForward: 2 + - _Cutoff: 0.5 + - _DepthOffsetEnable: 0 + - _DetailNormalMapScale: 1 + - _DoubleSidedEnable: 0 + - _DoubleSidedGIMode: 0 + - _DoubleSidedNormalMode: 2 + - _DstBlend: 0 + - _EMISSIVE: 0 + - _EnableBlendModePreserveSpecularLighting: 1 + - _EnableFogOnTransparent: 1 + - _Farthest_Distance: 0 + - _GI_Intensity: 0 + - _GlossMapScale: 1 + - _Glossiness: 0 + - _GlossyReflections: 1 + - _HighColor_Power: 0.48 + - _Inverse_Clipping: 0 + - _Inverse_MatcapMask: 0 + - _Inverse_Z_Axis_BLD: 1 + - _IsBaseMapAlphaAsClippingMask: 0 + - _Is_1st_ShadeColorOnly: 0 + - _Is_BLD: 0 + - _Is_BakedNormal: 0 + - _Is_BlendAddToHiColor: 1 + - _Is_BlendAddToMatCap: 1 + - _Is_BlendBaseColor: 1 + - _Is_ColorShift: 0 + - _Is_Filter_HiCutPointLightColor: 1 + - _Is_Filter_LightColor: 0 + - _Is_LightColor_1st_Shade: 1 + - _Is_LightColor_2nd_Shade: 1 + - _Is_LightColor_AR: 1 + - _Is_LightColor_Ap_RimLight: 1 + - _Is_LightColor_Base: 1 + - _Is_LightColor_HighColor: 0 + - _Is_LightColor_MatCap: 1 + - _Is_LightColor_Outline: 1 + - _Is_LightColor_RimLight: 1 + - _Is_NormalMap: 0 + - _Is_NormalMapForMatCap: 0 + - _Is_NormalMapToBase: 0 + - _Is_NormalMapToHighColor: 0 + - _Is_NormalMapToRimLight: 0 + - _Is_Ortho: 0 + - _Is_OutlineTex: 1 + - _Is_PingPong_Base: 0 + - _Is_SpecularToHighColor: 0 + - _Is_UseTweakHighColorOnShadow: 0 + - _Is_UseTweakMatCapOnShadow: 0 + - _Is_ViewCoord_Scroll: 0 + - _Is_ViewShift: 0 + - _LightDirection_MaskOn: 0 + - _MatCap: 0 + - _Metallic: 0 + - _Mode: 0 + - _Nearest_Distance: 1 + - _OUTLINE: 0 + - _OcclusionStrength: 1 + - _Offset_X_Axis_BLD: -0.05 + - _Offset_Y_Axis_BLD: 0.09 + - _Offset_Z: 2 + - _OpaqueCullMode: 2 + - _Outline_Width: 1.5 + - _Parallax: 0.02 + - _QueueControl: 0 + - _QueueOffset: 0 + - _RayTracing: 0 + - _ReceivesSSR: 1 + - _ReceivesSSRTransparent: 0 + - _RefractionModel: 0 + - _RenderQueueType: 1 + - _RequireSplitLighting: 0 + - _RimLight: 0 + - _RimLight_FeatherOff: 1 + - _RimLight_InsideMask: 0.47 + - _RimLight_Power: 0.01 + - _Rotate_EmissiveUV: 0 + - _Rotate_MatCapUV: 0 + - _Rotate_NormalMapForMatCapUV: 0 + - _SPRDefaultUnlitColorMask: 15 + - _SRPDefaultUnlitColMode: 1 + - _Scroll_EmissiveU: 0 + - _Scroll_EmissiveV: 0 + - _Set_SystemShadowsToBase: 1 + - _ShadeColor_Step: 0.618 + - _Smoothness: 0 + - _SmoothnessTextureChannel: 0 + - _SpecularHighlights: 1 + - _SrcBlend: 1 + - _StencilComp: 0 + - _StencilMode: 0 + - _StencilNo: 1 + - _StencilOpFail: 0 + - _StencilOpPass: 0 + - _StencilRef: 0 + - _StencilRefDepth: 8 + - _StencilRefDistortionVec: 4 + - _StencilRefGBuffer: 10 + - _StencilRefMV: 40 + - _StencilWriteMask: 6 + - _StencilWriteMaskDepth: 8 + - _StencilWriteMaskDistortionVec: 4 + - _StencilWriteMaskGBuffer: 14 + - _StencilWriteMaskMV: 40 + - _StepOffset: 0 + - _SupportDecals: 1 + - _SurfaceType: 0 + - _TessEdgeLength: 5 + - _TessExtrusionAmount: 0 + - _TessPhongStrength: 0.5 + - _TransparentBackfaceEnable: 0 + - _TransparentCullMode: 2 + - _TransparentDepthPostpassEnable: 0 + - _TransparentDepthPrepassEnable: 0 + - _TransparentEnabled: 0 + - _TransparentSortPriority: 0 + - _TransparentWritingMotionVec: 0 + - _TransparentZWrite: 0 + - _TweakHighColorOnShadow: 0 + - _TweakMatCapOnShadow: 0 + - _Tweak_HighColorMaskLevel: 0 + - _Tweak_LightDirection_MaskLevel: 0 + - _Tweak_MatCapUV: 0 + - _Tweak_MatcapMaskLevel: 0 + - _Tweak_RimLightMaskLevel: 0 + - _Tweak_ShadingGradeMapLevel: 0 + - _Tweak_SystemShadowsLevel: 0 + - _Tweak_transparency: 0 + - _UVSec: 0 + - _Unlit_Intensity: 1 + - _UseShadowThreshold: 0 + - _Use_1stAs2nd: 0 + - _Use_BaseAs1st: 0 + - _ZOverDrawMode: 0 + - _ZTestDepthEqualForOpaque: 3 + - _ZTestGBuffer: 4 + - _ZTestTransparent: 4 + - _ZWrite: 1 + - _ZWriteMode: 1 + - _simpleUI: 2 + - _utsTechnique: 1 + - _utsVersion: 2.07 + - _utsVersionX: 2 + - _utsVersionY: 2 + - _utsVersionZ: 0 + m_Colors: + - _1st_ShadeColor: {r: 1, g: 1, b: 1, a: 1} + - _2nd_ShadeColor: {r: 1, g: 1, b: 1, a: 1} + - _AngelRing_Color: {r: 1, g: 1, b: 1, a: 1} + - _Ap_RimLightColor: {r: 1, g: 1, b: 1, a: 1} + - _BaseColor: {r: 1, g: 1, b: 1, a: 1} + - _Color: {r: 1, g: 1, b: 1, a: 1} + - _ColorShift: {r: 0, g: 0, b: 0, a: 1} + - _DoubleSidedConstants: {r: 1, g: 1, b: -1, a: 0} + - _EmissionColor: {r: 1, g: 1, b: 1, a: 1} + - _Emissive_Color: {r: 5.2780313, g: 5.2780313, b: 5.2780313, a: 1} + - _HighColor: {r: 0.3962264, g: 0.33053476, b: 0.25978997, a: 1} + - _MatCapColor: {r: 1, g: 1, b: 1, a: 1} + - _Outline_Color: {r: 0, g: 0, b: 0, a: 1} + - _RimLightColor: {r: 0, g: 0.8758622, b: 1, a: 1} + - _Tiling: {r: 1, g: 1, b: 0, a: 0} + - _ViewShift: {r: 0, g: 0, b: 0, a: 1} + m_BuildTextureStacks: [] + m_AllowLocking: 1 +--- !u!114 &242505081636331739 +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 &6621973610829896646 +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: 639247ca83abc874e893eb93af2b5e44, type: 3} + m_Name: + m_EditorClassIdentifier: + version: 0 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/LongSleeve.mat.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/LongSleeve.mat.meta new file mode 100644 index 00000000..eb5e6184 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/LongSleeve.mat.meta @@ -0,0 +1,16 @@ +fileFormatVersion: 2 +guid: 002064652c69eba4699de7e0319b02dc +timeCreated: 1544184610 +licenseType: Store +NativeFormatImporter: + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/LongSleeve.mat + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Skin.mat b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Skin.mat new file mode 100644 index 00000000..4e8a1e47 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Skin.mat @@ -0,0 +1,405 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &-7024018919946654760 +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 &-2976717314438926610 +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: 639247ca83abc874e893eb93af2b5e44, type: 3} + m_Name: + m_EditorClassIdentifier: + version: 0 +--- !u!21 &2100000 +Material: + serializedVersion: 8 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: Skin + m_Shader: {fileID: -6465566751694194690, guid: e0b73429f84a56840ba17b216237f806, type: 3} + m_Parent: {fileID: 0} + m_ModifiedSerializedProperties: 0 + m_ValidKeywords: [] + m_InvalidKeywords: + - _DISABLE_SSR_TRANSPARENT + m_LightmapFlags: 4 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: 2000 + stringTagMap: + IgnoreProjection: False + disabledShaderPasses: + - TransparentDepthPrepass + - TransparentDepthPostpass + - TransparentBackface + - RayTracingPrepass + - MOTIONVECTORS + m_LockedProperties: + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _1st_ShadeMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _2nd_ShadeMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _AngelRing_Sampler: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BakedNormal: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BaseMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ClippingMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailAlbedoMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Emissive_Tex: + m_Texture: {fileID: 2800000, guid: 5ca59e98250004241ac83aa8c82eecd3, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _HighColor_Tex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main: + m_Texture: {fileID: 2800000, guid: 415a7cc21eec4e94fa9ae0b2078f352c, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 2800000, guid: 415a7cc21eec4e94fa9ae0b2078f352c, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MatCap_Sampler: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _NormalMap: + m_Texture: {fileID: 2800000, guid: 4243081d0d648654ead0ba36af1cc134, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _NormalMapForMatCap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OcclusionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OutlineTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Outline_Sampler: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Set_1st_ShadePosition: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Set_2nd_ShadePosition: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Set_HighColorMask: + m_Texture: {fileID: 2800000, guid: 3f05059980aad7443bb782b29a2af1c3, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Set_MatcapMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Set_RimLightMask: + m_Texture: {fileID: 2800000, guid: 55e006481a55b4947b38566992e7bfd0, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ShadingGradeMap: + m_Texture: {fileID: 2800000, guid: 98574cca734649441bf1127cbec80f76, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_Lightmaps: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_LightmapsInd: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_ShadowMasks: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Ints: [] + m_Floats: + - _1st2nd_Shades_Feather: 0.25 + - _1st_ShadeColor_Feather: 0.54 + - _1st_ShadeColor_Step: 0.39 + - _2nd_ShadeColor_Feather: 0.25 + - _2nd_ShadeColor_Step: 0.33 + - _ARSampler_AlphaOn: 0 + - _AR_OffsetU: 0 + - _AR_OffsetV: 0.3 + - _AddPrecomputedVelocity: 0 + - _Add_Antipodean_RimLight: 1 + - _AlphaCutoffEnable: 0 + - _AlphaDstBlend: 0 + - _AlphaSrcBlend: 1 + - _AlphaToMask: 0 + - _AlphaToMaskInspectorValue: 0 + - _AngelRing: 0 + - _Ap_RimLight_FeatherOff: 0 + - _Ap_RimLight_Power: 0.59 + - _AutoRenderQueue: 1 + - _BUILTIN_QueueControl: 1 + - _BUILTIN_QueueOffset: 0 + - _BaseColor_Step: 0.39 + - _BaseShade_Feather: 0.54 + - _Base_Speed: 0 + - _BlendMode: 0 + - _BlurLevelMatcap: 0 + - _BlurLevelSGM: 0 + - _BumpScale: 0.252 + - _BumpScaleMatcap: 1 + - _CameraRolling_Stabilizer: 0 + - _ClippingMode: 0 + - _Clipping_Level: 0 + - _ColorBoost: 1 + - _ColorShift_Speed: 0 + - _ConservativeDepthOffsetEnable: 0 + - _CullMode: 2 + - _CullModeForward: 2 + - _Cutoff: 0.5 + - _DepthOffsetEnable: 0 + - _DetailNormalMapScale: 1 + - _DoubleSidedEnable: 0 + - _DoubleSidedGIMode: 0 + - _DoubleSidedNormalMode: 2 + - _DstBlend: 0 + - _EMISSIVE: 0 + - _EnableBlendModePreserveSpecularLighting: 1 + - _EnableFogOnTransparent: 1 + - _Farthest_Distance: 0 + - _GI_Intensity: 0 + - _GlossMapScale: 1 + - _Glossiness: 0 + - _GlossyReflections: 1 + - _HighColor_Power: 0.872 + - _Inverse_Clipping: 0 + - _Inverse_MatcapMask: 0 + - _Inverse_Z_Axis_BLD: 1 + - _IsBaseMapAlphaAsClippingMask: 0 + - _Is_1st_ShadeColorOnly: 0 + - _Is_BLD: 0 + - _Is_BakedNormal: 0 + - _Is_BlendAddToHiColor: 1 + - _Is_BlendAddToMatCap: 1 + - _Is_BlendBaseColor: 1 + - _Is_ColorShift: 0 + - _Is_Filter_HiCutPointLightColor: 1 + - _Is_Filter_LightColor: 0 + - _Is_LightColor_1st_Shade: 1 + - _Is_LightColor_2nd_Shade: 1 + - _Is_LightColor_AR: 1 + - _Is_LightColor_Ap_RimLight: 1 + - _Is_LightColor_Base: 1 + - _Is_LightColor_HighColor: 1 + - _Is_LightColor_MatCap: 1 + - _Is_LightColor_Outline: 0 + - _Is_LightColor_RimLight: 1 + - _Is_NormalMap: 0 + - _Is_NormalMapForMatCap: 0 + - _Is_NormalMapToBase: 0 + - _Is_NormalMapToHighColor: 1 + - _Is_NormalMapToRimLight: 0 + - _Is_Ortho: 0 + - _Is_OutlineTex: 0 + - _Is_PingPong_Base: 0 + - _Is_SpecularToHighColor: 1 + - _Is_UseTweakHighColorOnShadow: 1 + - _Is_UseTweakMatCapOnShadow: 0 + - _Is_ViewCoord_Scroll: 0 + - _Is_ViewShift: 0 + - _LightDirection_MaskOn: 1 + - _MatCap: 0 + - _Metallic: 0 + - _Mode: 0 + - _Nearest_Distance: 2 + - _OUTLINE: 0 + - _OcclusionStrength: 1 + - _Offset_X_Axis_BLD: -0.05 + - _Offset_Y_Axis_BLD: 0.09 + - _Offset_Z: 0 + - _OpaqueCullMode: 2 + - _Outline_Width: 2 + - _Parallax: 0.02 + - _QueueControl: 0 + - _QueueOffset: 0 + - _RayTracing: 0 + - _ReceivesSSR: 1 + - _ReceivesSSRTransparent: 0 + - _RefractionModel: 0 + - _RenderQueueType: 1 + - _RequireSplitLighting: 0 + - _RimLight: 0 + - _RimLight_FeatherOff: 0 + - _RimLight_InsideMask: 0.0001 + - _RimLight_Power: 1 + - _Rotate_EmissiveUV: 0 + - _Rotate_MatCapUV: 0 + - _Rotate_NormalMapForMatCapUV: 0 + - _SPRDefaultUnlitColorMask: 15 + - _SRPDefaultUnlitColMode: 1 + - _Scroll_EmissiveU: 0 + - _Scroll_EmissiveV: 0 + - _Set_SystemShadowsToBase: 1 + - _ShadeColor_Step: 0.33 + - _Smoothness: 0 + - _SmoothnessTextureChannel: 0 + - _SpecularHighlights: 1 + - _SrcBlend: 1 + - _StencilComp: 0 + - _StencilMode: 0 + - _StencilNo: 1 + - _StencilOpFail: 0 + - _StencilOpPass: 0 + - _StencilRef: 0 + - _StencilRefDepth: 8 + - _StencilRefDistortionVec: 4 + - _StencilRefGBuffer: 10 + - _StencilRefMV: 40 + - _StencilWriteMask: 6 + - _StencilWriteMaskDepth: 8 + - _StencilWriteMaskDistortionVec: 4 + - _StencilWriteMaskGBuffer: 14 + - _StencilWriteMaskMV: 40 + - _StepOffset: 0.04 + - _SupportDecals: 1 + - _SurfaceType: 0 + - _TessEdgeLength: 5 + - _TessExtrusionAmount: 0 + - _TessPhongStrength: 0.5 + - _TransparentBackfaceEnable: 0 + - _TransparentCullMode: 2 + - _TransparentDepthPostpassEnable: 0 + - _TransparentDepthPrepassEnable: 0 + - _TransparentEnabled: 0 + - _TransparentSortPriority: 0 + - _TransparentWritingMotionVec: 0 + - _TransparentZWrite: 0 + - _TweakHighColorOnShadow: 0 + - _TweakMatCapOnShadow: 0 + - _Tweak_HighColorMaskLevel: 0 + - _Tweak_LightDirection_MaskLevel: 0 + - _Tweak_MatCapUV: 0 + - _Tweak_MatcapMaskLevel: 0 + - _Tweak_RimLightMaskLevel: 0 + - _Tweak_ShadingGradeMapLevel: 0 + - _Tweak_SystemShadowsLevel: -0.5 + - _Tweak_transparency: 0 + - _UVSec: 0 + - _Unlit_Intensity: 1 + - _UseShadowThreshold: 0 + - _Use_1stAs2nd: 1 + - _Use_BaseAs1st: 1 + - _ZOverDrawMode: 0 + - _ZTestDepthEqualForOpaque: 3 + - _ZTestGBuffer: 4 + - _ZTestTransparent: 4 + - _ZWrite: 1 + - _ZWriteMode: 1 + - _simpleUI: 0 + - _utsTechnique: 1 + - _utsVersion: 2.07 + - _utsVersionX: 2 + - _utsVersionY: 2 + - _utsVersionZ: 0 + m_Colors: + - _1st_ShadeColor: {r: 0.49264705, g: 0.304282, b: 0.304282, a: 1} + - _2nd_ShadeColor: {r: 0.50735295, g: 0.39543685, b: 0.4533245, a: 1} + - _AngelRing_Color: {r: 1, g: 1, b: 1, a: 1} + - _Ap_RimLightColor: {r: 1, g: 0.80689657, b: 0, a: 1} + - _BaseColor: {r: 0.9433962, g: 0.9137382, b: 0.7698469, a: 1} + - _Color: {r: 0.9811321, g: 0.81316864, b: 0.69789964, a: 1} + - _ColorShift: {r: 0, g: 0, b: 0, a: 1} + - _DoubleSidedConstants: {r: 1, g: 1, b: -1, a: 0} + - _EmissionColor: {r: 1, g: 1, b: 1, a: 1} + - _Emissive_Color: {r: 0.21323532, g: 0, b: 0, a: 1} + - _HighColor: {r: 0.33962262, g: 0.20665716, b: 0.20665716, a: 1} + - _MatCapColor: {r: 1, g: 1, b: 1, a: 1} + - _Outline_Color: {r: 0.5294118, g: 0.22352937, b: 0.34159288, a: 1} + - _RimLightColor: {r: 1, g: 0, b: 0, a: 1} + - _Tiling: {r: 1, g: 1, b: 0, a: 0} + - _ViewShift: {r: 0, g: 0, b: 0, a: 1} + m_BuildTextureStacks: [] + m_AllowLocking: 1 +--- !u!114 &3673746192689313980 +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: da692e001514ec24dbc4cca1949ff7e8, type: 3} + m_Name: + m_EditorClassIdentifier: + version: 12 + hdPluginSubTargetMaterialVersions: + m_Keys: [] + m_Values: diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Skin.mat.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Skin.mat.meta new file mode 100644 index 00000000..055cbbbe --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Skin.mat.meta @@ -0,0 +1,16 @@ +fileFormatVersion: 2 +guid: cc28b9ef0843c9746a5a8276ed0f876a +timeCreated: 1544184610 +licenseType: Store +NativeFormatImporter: + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Skin.mat + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX.meta new file mode 100644 index 00000000..8ececb57 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: efacb57bb1f8f0340a7d27ddde68f694 +folderAsset: yes +timeCreated: 1544184608 +licenseType: Store +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG.meta new file mode 100644 index 00000000..df409db0 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 6b19b3993b4a0e14096972aa4c5b57ce +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Body_Base.png b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Body_Base.png new file mode 100644 index 00000000..1e469a4a --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Body_Base.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:413d2b06b45982532a23fced5cc6f47bf645e42edccf7ff163d9c273772fef47 +size 9543528 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Body_Base.png.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Body_Base.png.meta new file mode 100644 index 00000000..f1a35075 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Body_Base.png.meta @@ -0,0 +1,147 @@ +fileFormatVersion: 2 +guid: d1e50199c6f08ed46bf2d136ab225409 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 11 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: 2 + mipBias: -100 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + applyGammaDecoding: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: iPhone + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Android + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Windows Store Apps + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Body_Base.png + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Body_Emi.png b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Body_Emi.png new file mode 100644 index 00000000..d60ec4c1 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Body_Emi.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c262520fd86d46d5c8726347171b20f1a10691eee57f973aa2fbd5e4e1b93488 +size 3170257 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Body_Emi.png.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Body_Emi.png.meta new file mode 100644 index 00000000..30e1d01f --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Body_Emi.png.meta @@ -0,0 +1,147 @@ +fileFormatVersion: 2 +guid: dc71d88ff73488f45ac239b21f552745 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 11 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: 2 + mipBias: -100 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + applyGammaDecoding: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: iPhone + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Android + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Windows Store Apps + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Body_Emi.png + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Body_SGM.png b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Body_SGM.png new file mode 100644 index 00000000..0d845478 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Body_SGM.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5eb3b34acefe0e43f3b499bb679b91eb322daf963ea63b4cb4e09c9a1679eb17 +size 1765521 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Body_SGM.png.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Body_SGM.png.meta new file mode 100644 index 00000000..aef65e2d --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Body_SGM.png.meta @@ -0,0 +1,147 @@ +fileFormatVersion: 2 +guid: 7c75a3dfe8927774ea56a0777d1edcf1 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 11 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: 2 + mipBias: -100 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + applyGammaDecoding: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: iPhone + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Android + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Windows Store Apps + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Body_SGM.png + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Body_Shd1.png b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Body_Shd1.png new file mode 100644 index 00000000..336ec407 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Body_Shd1.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:da051ffea3268e6d3bd8baaca33a02bfee336169b5d9493d2f2a76b433e4cb48 +size 10374433 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Body_Shd1.png.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Body_Shd1.png.meta new file mode 100644 index 00000000..c6fa27a7 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Body_Shd1.png.meta @@ -0,0 +1,147 @@ +fileFormatVersion: 2 +guid: f180dfef53ad0924882657e28833a60b +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 11 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: 2 + mipBias: -100 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + applyGammaDecoding: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: iPhone + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Android + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Windows Store Apps + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Body_Shd1.png + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Body_Shd2.png b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Body_Shd2.png new file mode 100644 index 00000000..4519b00f --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Body_Shd2.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6a7b180ce3ca5e3546920c1293a9a46d5e7d51122437161d7309e5721e2c51b2 +size 9765866 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Body_Shd2.png.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Body_Shd2.png.meta new file mode 100644 index 00000000..f21ddfd1 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Body_Shd2.png.meta @@ -0,0 +1,147 @@ +fileFormatVersion: 2 +guid: 9cd90983043e3974e971a6c8d66cc42d +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 11 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: 2 + mipBias: -100 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + applyGammaDecoding: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: iPhone + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Android + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Windows Store Apps + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Body_Shd2.png + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Body_Spc.png b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Body_Spc.png new file mode 100644 index 00000000..a2d0dded --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Body_Spc.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e47f968aa338e0b9701d6e4fec1ec6a6103e5e4c2a3582f2b120f297cc14375f +size 321265 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Body_Spc.png.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Body_Spc.png.meta new file mode 100644 index 00000000..f41842fc --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Body_Spc.png.meta @@ -0,0 +1,147 @@ +fileFormatVersion: 2 +guid: a01adb17bdc53ba4da348b3cba074154 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 11 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: 2 + mipBias: -100 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + applyGammaDecoding: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: iPhone + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Android + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Windows Store Apps + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Body_Spc.png + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Face_Base.png b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Face_Base.png new file mode 100644 index 00000000..bdcb329c --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Face_Base.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5cf66c73c477e167c528d4c8ee309d2f511ea08a7fa729dbb1355a153b4ddc75 +size 260026 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Face_Base.png.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Face_Base.png.meta new file mode 100644 index 00000000..6a307388 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Face_Base.png.meta @@ -0,0 +1,147 @@ +fileFormatVersion: 2 +guid: 7275e6b9fb5d06847b114e33f0ab8ca6 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 11 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: 2 + mipBias: -100 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + applyGammaDecoding: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: iPhone + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Android + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Windows Store Apps + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Face_Base.png + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Face_Emi.png b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Face_Emi.png new file mode 100644 index 00000000..664deb23 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Face_Emi.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7158ee0b8947b690d57c7ebe365d43ceed951af27de4ede5465f08a0d8b4d32e +size 230512 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Face_Emi.png.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Face_Emi.png.meta new file mode 100644 index 00000000..56f2fd29 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Face_Emi.png.meta @@ -0,0 +1,147 @@ +fileFormatVersion: 2 +guid: 5a8dc6b89c866b546a4b2beebade28a1 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 11 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: 2 + mipBias: -100 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + applyGammaDecoding: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: iPhone + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Android + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Windows Store Apps + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Face_Emi.png + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Face_LSM.png b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Face_LSM.png new file mode 100644 index 00000000..57411113 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Face_LSM.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bf12eabc1da69ba191742a44d0f6f6e1b96b63087688a8783f3acca29d42aa81 +size 102715 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Face_LSM.png.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Face_LSM.png.meta new file mode 100644 index 00000000..90b37ae7 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Face_LSM.png.meta @@ -0,0 +1,147 @@ +fileFormatVersion: 2 +guid: c5acb3acbd64e734b838b254bb0ee4d8 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 11 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: 2 + mipBias: -100 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + applyGammaDecoding: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: iPhone + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Android + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Windows Store Apps + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Face_LSM.png + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Face_Rim.png b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Face_Rim.png new file mode 100644 index 00000000..c3c449a6 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Face_Rim.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b9c68db6072ad182cea54cca38a6a4a25b49cd87ec952c5ed2dcabf05ff05b65 +size 86398 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Face_Rim.png.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Face_Rim.png.meta new file mode 100644 index 00000000..3307e274 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Face_Rim.png.meta @@ -0,0 +1,147 @@ +fileFormatVersion: 2 +guid: b925033b206f79942b43d77ac699fc72 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 11 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: 2 + mipBias: -100 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + applyGammaDecoding: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: iPhone + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Android + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Windows Store Apps + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Face_Rim.png + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Face_SGM.png b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Face_SGM.png new file mode 100644 index 00000000..c28475d4 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Face_SGM.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3b9ac40f88f5bf17e0b2ef428ff3312d1f447d1815fc2444973e30cb6b5f7841 +size 98781 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Face_SGM.png.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Face_SGM.png.meta new file mode 100644 index 00000000..0f5b78ca --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Face_SGM.png.meta @@ -0,0 +1,147 @@ +fileFormatVersion: 2 +guid: ec3cb3dfef7e49a4eb0c10040e9733df +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 11 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: 2 + mipBias: -100 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + applyGammaDecoding: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: iPhone + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Android + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Windows Store Apps + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Face_SGM.png + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Face_Shd1.png b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Face_Shd1.png new file mode 100644 index 00000000..9945893e --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Face_Shd1.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8db3560c1424d3ba10c2ba06f19819eb0462425810d71bc6a55d788ea9479859 +size 268553 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Face_Shd1.png.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Face_Shd1.png.meta new file mode 100644 index 00000000..1e0dbeaf --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Face_Shd1.png.meta @@ -0,0 +1,147 @@ +fileFormatVersion: 2 +guid: 6ff07624f73f6184f84deb5ba5242590 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 11 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: 2 + mipBias: -100 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + applyGammaDecoding: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: iPhone + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Android + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Windows Store Apps + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Face_Shd1.png + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Face_Shd2.png b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Face_Shd2.png new file mode 100644 index 00000000..8b873223 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Face_Shd2.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dd28c03f9d89091ee7a82bfa4a9e5d230421dcb1aba9caf75e743337c2adf609 +size 268629 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Face_Shd2.png.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Face_Shd2.png.meta new file mode 100644 index 00000000..a893f4da --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Face_Shd2.png.meta @@ -0,0 +1,147 @@ +fileFormatVersion: 2 +guid: 7d84fa1a7f8997342ba010124f77b1e8 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 11 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: 2 + mipBias: -100 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + applyGammaDecoding: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: iPhone + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Android + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Windows Store Apps + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Face_Shd2.png + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Hair_SGM.png b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Hair_SGM.png new file mode 100644 index 00000000..8ffb3a00 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Hair_SGM.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4d8620f39fbaad23dc56ec31df23f3f4d46c9be6c1a8ff19d080e84d66882f35 +size 372684 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Hair_SGM.png.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Hair_SGM.png.meta new file mode 100644 index 00000000..533635bc --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Hair_SGM.png.meta @@ -0,0 +1,147 @@ +fileFormatVersion: 2 +guid: 0620c25d224d4d543936ec89321802b6 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 11 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: 2 + mipBias: -100 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + applyGammaDecoding: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: iPhone + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Android + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Windows Store Apps + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Hair_SGM.png + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Headfgear_Base.png b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Headfgear_Base.png new file mode 100644 index 00000000..2dbbd3a9 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Headfgear_Base.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:da00d9d928e847d49fe1ec22263432932153c05ec68349b39db07340c6255a2a +size 2521344 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Headfgear_Base.png.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Headfgear_Base.png.meta new file mode 100644 index 00000000..f4695d41 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Headfgear_Base.png.meta @@ -0,0 +1,147 @@ +fileFormatVersion: 2 +guid: a4a14922fc4479241aef660b68c498f5 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 11 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: 2 + mipBias: -100 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + applyGammaDecoding: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: iPhone + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Android + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Windows Store Apps + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Headfgear_Base.png + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Skin_Base.png b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Skin_Base.png new file mode 100644 index 00000000..009f5850 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Skin_Base.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:10e54eebda12bc8de706e629932a2b1d241da9e9d8a4fad33a0ea821ce7447f5 +size 406064 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Skin_Base.png.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Skin_Base.png.meta new file mode 100644 index 00000000..1fcb02f9 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Skin_Base.png.meta @@ -0,0 +1,147 @@ +fileFormatVersion: 2 +guid: 415a7cc21eec4e94fa9ae0b2078f352c +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 11 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: 2 + mipBias: -100 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + applyGammaDecoding: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: iPhone + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Android + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Windows Store Apps + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Skin_Base.png + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Skin_Emi.png b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Skin_Emi.png new file mode 100644 index 00000000..6a7e69ee --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Skin_Emi.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1242757658345a7c7bfaddfec2a9944c61daa1f794fbe465a8dbea653768f457 +size 293959 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Skin_Emi.png.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Skin_Emi.png.meta new file mode 100644 index 00000000..f41252c7 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Skin_Emi.png.meta @@ -0,0 +1,147 @@ +fileFormatVersion: 2 +guid: 5ca59e98250004241ac83aa8c82eecd3 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 11 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: 2 + mipBias: -100 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + applyGammaDecoding: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: iPhone + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Android + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Windows Store Apps + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Skin_Emi.png + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Skin_Nrm.png b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Skin_Nrm.png new file mode 100644 index 00000000..6ef09a62 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Skin_Nrm.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:aabf7397cffbbf5e209157f5ec1c47717f14370a392d9afa8cd18638db6a0fa9 +size 608907 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Skin_Nrm.png.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Skin_Nrm.png.meta new file mode 100644 index 00000000..57209d6c --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Skin_Nrm.png.meta @@ -0,0 +1,147 @@ +fileFormatVersion: 2 +guid: 4d07b49e5565791478554cb770c6f8d2 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 11 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 1 + externalNormalMap: 0 + heightScale: 0.148 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: 2 + mipBias: -100 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 1 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + applyGammaDecoding: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: iPhone + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Android + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Windows Store Apps + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Skin_Nrm.png + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Skin_Rim.png b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Skin_Rim.png new file mode 100644 index 00000000..ca539077 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Skin_Rim.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:774a8fe5d58bf0a48898206672ac24ca0f0ae40dd422f5af225e189c18bf9fa0 +size 286855 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Skin_Rim.png.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Skin_Rim.png.meta new file mode 100644 index 00000000..617474f7 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Skin_Rim.png.meta @@ -0,0 +1,147 @@ +fileFormatVersion: 2 +guid: 55e006481a55b4947b38566992e7bfd0 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 11 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: 2 + mipBias: -100 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + applyGammaDecoding: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: iPhone + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Android + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Windows Store Apps + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Skin_Rim.png + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Skin_SGM.png b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Skin_SGM.png new file mode 100644 index 00000000..67363986 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Skin_SGM.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f0d13bdf956f09705154514a3f861e3cea51bf7776a7718834993c084f161118 +size 537789 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Skin_SGM.png.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Skin_SGM.png.meta new file mode 100644 index 00000000..0b989ade --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Skin_SGM.png.meta @@ -0,0 +1,147 @@ +fileFormatVersion: 2 +guid: 98574cca734649441bf1127cbec80f76 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 11 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: 2 + mipBias: -100 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + applyGammaDecoding: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: iPhone + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Android + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Windows Store Apps + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Skin_SGM.png + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Skin_Spc.png b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Skin_Spc.png new file mode 100644 index 00000000..4cd0a67d --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Skin_Spc.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0b47f16c94dc4b99d7d6907669db8cef8917c79897a713ff5f3ee935960b65e5 +size 444876 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Skin_Spc.png.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Skin_Spc.png.meta new file mode 100644 index 00000000..9a0bf564 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Skin_Spc.png.meta @@ -0,0 +1,147 @@ +fileFormatVersion: 2 +guid: 3f05059980aad7443bb782b29a2af1c3 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 11 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: 2 + mipBias: -100 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + applyGammaDecoding: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: iPhone + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Android + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Windows Store Apps + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Skin_Spc.png + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Skin_SpcCol.png b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Skin_SpcCol.png new file mode 100644 index 00000000..7f45a35c --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Skin_SpcCol.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ca028916e819332ed16de576c9c89d3b871b92139faeb9fe6d31ac4fdb5ed1aa +size 350979 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Skin_SpcCol.png.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Skin_SpcCol.png.meta new file mode 100644 index 00000000..68eab35c --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Skin_SpcCol.png.meta @@ -0,0 +1,147 @@ +fileFormatVersion: 2 +guid: b992e82399d98b44e85ee1318110377d +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 11 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: 2 + mipBias: -100 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + applyGammaDecoding: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: iPhone + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Android + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Windows Store Apps + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Skin_SpcCol.png + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/face3_main.mat b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/face3_main.mat new file mode 100644 index 00000000..a257a470 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/face3_main.mat @@ -0,0 +1,201 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &-3956095719398336066 +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: 639247ca83abc874e893eb93af2b5e44, type: 3} + m_Name: + m_EditorClassIdentifier: + version: 0 +--- !u!114 &-2131633107486826859 +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: da692e001514ec24dbc4cca1949ff7e8, type: 3} + m_Name: + m_EditorClassIdentifier: + version: 12 + hdPluginSubTargetMaterialVersions: + m_Keys: [] + m_Values: +--- !u!21 &2100000 +Material: + serializedVersion: 8 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: face3_main + m_Shader: {fileID: -6465566751694194690, guid: e0b73429f84a56840ba17b216237f806, type: 3} + m_Parent: {fileID: 0} + m_ModifiedSerializedProperties: 0 + m_ValidKeywords: [] + m_InvalidKeywords: + - _DISABLE_SSR_TRANSPARENT + m_LightmapFlags: 4 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: 2000 + stringTagMap: {} + disabledShaderPasses: + - TransparentDepthPrepass + - TransparentDepthPostpass + - TransparentBackface + - RayTracingPrepass + - MOTIONVECTORS + m_LockedProperties: + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailAlbedoMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OcclusionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_Lightmaps: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_LightmapsInd: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_ShadowMasks: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Ints: [] + m_Floats: + - _AddPrecomputedVelocity: 0 + - _AlphaCutoffEnable: 0 + - _AlphaDstBlend: 0 + - _AlphaSrcBlend: 1 + - _AlphaToMask: 0 + - _AlphaToMaskInspectorValue: 0 + - _BUILTIN_QueueControl: -1 + - _BUILTIN_QueueOffset: 0 + - _BlendMode: 0 + - _BumpScale: 1 + - _ConservativeDepthOffsetEnable: 0 + - _CullMode: 2 + - _CullModeForward: 2 + - _Cutoff: 0.5 + - _DepthOffsetEnable: 0 + - _DetailNormalMapScale: 1 + - _DoubleSidedEnable: 0 + - _DoubleSidedGIMode: 0 + - _DoubleSidedNormalMode: 2 + - _DstBlend: 0 + - _EnableBlendModePreserveSpecularLighting: 1 + - _EnableFogOnTransparent: 1 + - _GlossMapScale: 1 + - _Glossiness: 0 + - _GlossyReflections: 1 + - _Metallic: 0 + - _Mode: 0 + - _OcclusionStrength: 1 + - _OpaqueCullMode: 2 + - _Parallax: 0.02 + - _QueueControl: 0 + - _QueueOffset: 0 + - _RayTracing: 0 + - _ReceivesSSR: 1 + - _ReceivesSSRTransparent: 0 + - _RefractionModel: 0 + - _RenderQueueType: 1 + - _RequireSplitLighting: 0 + - _Smoothness: 0 + - _SmoothnessTextureChannel: 0 + - _SpecularHighlights: 1 + - _SrcBlend: 1 + - _StencilRef: 0 + - _StencilRefDepth: 8 + - _StencilRefDistortionVec: 4 + - _StencilRefGBuffer: 10 + - _StencilRefMV: 40 + - _StencilWriteMask: 6 + - _StencilWriteMaskDepth: 8 + - _StencilWriteMaskDistortionVec: 4 + - _StencilWriteMaskGBuffer: 14 + - _StencilWriteMaskMV: 40 + - _SupportDecals: 1 + - _SurfaceType: 0 + - _TransparentBackfaceEnable: 0 + - _TransparentCullMode: 2 + - _TransparentDepthPostpassEnable: 0 + - _TransparentDepthPrepassEnable: 0 + - _TransparentSortPriority: 0 + - _TransparentWritingMotionVec: 0 + - _TransparentZWrite: 0 + - _UVSec: 0 + - _UseShadowThreshold: 0 + - _ZTestDepthEqualForOpaque: 3 + - _ZTestGBuffer: 4 + - _ZTestTransparent: 4 + - _ZWrite: 1 + m_Colors: + - _Color: {r: 0.8, g: 0.8, b: 0.8, a: 1} + - _DoubleSidedConstants: {r: 1, g: 1, b: -1, a: 0} + - _EmissionColor: {r: 1, g: 1, b: 1, a: 1} + - _Tiling: {r: 1, g: 1, b: 0, a: 0} + m_BuildTextureStacks: [] + m_AllowLocking: 1 +--- !u!114 &2718186772625287269 +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/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/face3_main.mat.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/face3_main.mat.meta new file mode 100644 index 00000000..88657fb0 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/face3_main.mat.meta @@ -0,0 +1,15 @@ +fileFormatVersion: 2 +guid: 4eea2ba65c52fad4b88ac8e9d67c594f +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/face3_main.mat + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/headExt.mat b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/headExt.mat new file mode 100644 index 00000000..0285fc0c --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/headExt.mat @@ -0,0 +1,201 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &-8845708009397242001 +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 &-8324562969990519675 +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: da692e001514ec24dbc4cca1949ff7e8, type: 3} + m_Name: + m_EditorClassIdentifier: + version: 12 + hdPluginSubTargetMaterialVersions: + m_Keys: [] + m_Values: +--- !u!114 &-3939152729430346464 +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: 639247ca83abc874e893eb93af2b5e44, type: 3} + m_Name: + m_EditorClassIdentifier: + version: 0 +--- !u!21 &2100000 +Material: + serializedVersion: 8 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: headExt + m_Shader: {fileID: -6465566751694194690, guid: e0b73429f84a56840ba17b216237f806, type: 3} + m_Parent: {fileID: 0} + m_ModifiedSerializedProperties: 0 + m_ValidKeywords: [] + m_InvalidKeywords: + - _DISABLE_SSR_TRANSPARENT + m_LightmapFlags: 4 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: 2000 + stringTagMap: {} + disabledShaderPasses: + - TransparentDepthPrepass + - TransparentDepthPostpass + - TransparentBackface + - RayTracingPrepass + - MOTIONVECTORS + m_LockedProperties: + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailAlbedoMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Main: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OcclusionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_Lightmaps: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_LightmapsInd: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_ShadowMasks: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Ints: [] + m_Floats: + - _AddPrecomputedVelocity: 0 + - _AlphaCutoffEnable: 0 + - _AlphaDstBlend: 0 + - _AlphaSrcBlend: 1 + - _AlphaToMask: 0 + - _AlphaToMaskInspectorValue: 0 + - _BUILTIN_QueueControl: -1 + - _BUILTIN_QueueOffset: 0 + - _BlendMode: 0 + - _BumpScale: 1 + - _ConservativeDepthOffsetEnable: 0 + - _CullMode: 2 + - _CullModeForward: 2 + - _Cutoff: 0.5 + - _DepthOffsetEnable: 0 + - _DetailNormalMapScale: 1 + - _DoubleSidedEnable: 0 + - _DoubleSidedGIMode: 0 + - _DoubleSidedNormalMode: 2 + - _DstBlend: 0 + - _EnableBlendModePreserveSpecularLighting: 1 + - _EnableFogOnTransparent: 1 + - _GlossMapScale: 1 + - _Glossiness: 0.09901475 + - _GlossyReflections: 1 + - _Metallic: 0 + - _Mode: 0 + - _OcclusionStrength: 1 + - _OpaqueCullMode: 2 + - _Parallax: 0.02 + - _QueueControl: 0 + - _QueueOffset: 0 + - _RayTracing: 0 + - _ReceivesSSR: 1 + - _ReceivesSSRTransparent: 0 + - _RefractionModel: 0 + - _RenderQueueType: 1 + - _RequireSplitLighting: 0 + - _Smoothness: 0 + - _SmoothnessTextureChannel: 0 + - _SpecularHighlights: 1 + - _SrcBlend: 1 + - _StencilRef: 0 + - _StencilRefDepth: 8 + - _StencilRefDistortionVec: 4 + - _StencilRefGBuffer: 10 + - _StencilRefMV: 40 + - _StencilWriteMask: 6 + - _StencilWriteMaskDepth: 8 + - _StencilWriteMaskDistortionVec: 4 + - _StencilWriteMaskGBuffer: 14 + - _StencilWriteMaskMV: 40 + - _SupportDecals: 1 + - _SurfaceType: 0 + - _TransparentBackfaceEnable: 0 + - _TransparentCullMode: 2 + - _TransparentDepthPostpassEnable: 0 + - _TransparentDepthPrepassEnable: 0 + - _TransparentSortPriority: 0 + - _TransparentWritingMotionVec: 0 + - _TransparentZWrite: 0 + - _UVSec: 0 + - _UseShadowThreshold: 0 + - _ZTestDepthEqualForOpaque: 3 + - _ZTestGBuffer: 4 + - _ZTestTransparent: 4 + - _ZWrite: 1 + m_Colors: + - _Color: {r: 0.8, g: 0.8, b: 0.8, a: 1} + - _DoubleSidedConstants: {r: 1, g: 1, b: -1, a: 0} + - _EmissionColor: {r: 1, g: 1, b: 1, a: 1} + - _Tiling: {r: 1, g: 1, b: 0, a: 0} + m_BuildTextureStacks: [] + m_AllowLocking: 1 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/headExt.mat.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/headExt.mat.meta new file mode 100644 index 00000000..db5b81f8 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/headExt.mat.meta @@ -0,0 +1,15 @@ +fileFormatVersion: 2 +guid: 2907c0cac24ed4b4c93075f883200c46 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/headExt.mat + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/UniteInTheSky.controller b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/UniteInTheSky.controller new file mode 100644 index 00000000..7eaf3433 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/UniteInTheSky.controller @@ -0,0 +1,460 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1101 &-5330246061505920765 +AnimatorStateTransition: + m_ObjectHideFlags: 1 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: + m_Conditions: + - m_ConditionMode: 1 + m_ConditionEvent: Next + m_EventTreshold: 0 + m_DstStateMachine: {fileID: 0} + m_DstState: {fileID: -2037826335270817655} + m_Solo: 0 + m_Mute: 0 + m_IsExit: 0 + serializedVersion: 3 + m_TransitionDuration: 0.25 + m_TransitionOffset: 0 + m_ExitTime: 0.9985577 + m_HasExitTime: 0 + m_HasFixedDuration: 1 + m_InterruptionSource: 0 + m_OrderedInterruption: 1 + m_CanTransitionToSelf: 1 +--- !u!1101 &-4051815149419108730 +AnimatorStateTransition: + m_ObjectHideFlags: 1 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: + m_Conditions: + - m_ConditionMode: 1 + m_ConditionEvent: Next + m_EventTreshold: 0 + m_DstStateMachine: {fileID: 0} + m_DstState: {fileID: 6956152088544691744} + m_Solo: 0 + m_Mute: 0 + m_IsExit: 0 + serializedVersion: 3 + m_TransitionDuration: 0.25 + m_TransitionOffset: 0 + m_ExitTime: 0.6875 + m_HasExitTime: 0 + m_HasFixedDuration: 1 + m_InterruptionSource: 0 + m_OrderedInterruption: 1 + m_CanTransitionToSelf: 1 +--- !u!1101 &-3630659354654148562 +AnimatorStateTransition: + m_ObjectHideFlags: 1 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: + m_Conditions: + - m_ConditionMode: 1 + m_ConditionEvent: Back + m_EventTreshold: 0 + m_DstStateMachine: {fileID: 0} + m_DstState: {fileID: 696072945675995140} + m_Solo: 0 + m_Mute: 0 + m_IsExit: 0 + serializedVersion: 3 + m_TransitionDuration: 0.25 + m_TransitionOffset: 0 + m_ExitTime: 0.9698795 + m_HasExitTime: 0 + m_HasFixedDuration: 1 + m_InterruptionSource: 0 + m_OrderedInterruption: 1 + m_CanTransitionToSelf: 1 +--- !u!1107 &-2476057408743069352 +AnimatorStateMachine: + serializedVersion: 6 + m_ObjectHideFlags: 1 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: Base Layer + m_ChildStates: + - serializedVersion: 1 + m_State: {fileID: 2495779494147398468} + m_Position: {x: 250, y: 80, z: 0} + - serializedVersion: 1 + m_State: {fileID: 696072945675995140} + m_Position: {x: 30, y: 330, z: 0} + - serializedVersion: 1 + m_State: {fileID: 1912442270958618819} + m_Position: {x: 300, y: 410, z: 0} + - serializedVersion: 1 + m_State: {fileID: 6956152088544691744} + m_Position: {x: 300, y: 330, z: 0} + - serializedVersion: 1 + m_State: {fileID: -1561510447695394969} + m_Position: {x: 30, y: 230, z: 0} + - serializedVersion: 1 + m_State: {fileID: -2037826335270817655} + m_Position: {x: 30, y: 410, z: 0} + m_ChildStateMachines: [] + m_AnyStateTransitions: [] + m_EntryTransitions: [] + m_StateMachineTransitions: {} + m_StateMachineBehaviours: [] + m_AnyStatePosition: {x: 50, y: 20, z: 0} + m_EntryPosition: {x: 50, y: 120, z: 0} + m_ExitPosition: {x: 800, y: 120, z: 0} + m_ParentStateMachinePosition: {x: 800, y: 20, z: 0} + m_DefaultState: {fileID: -1561510447695394969} +--- !u!1102 &-2037826335270817655 +AnimatorState: + serializedVersion: 6 + m_ObjectHideFlags: 1 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: WAIT02 + m_Speed: 1 + m_CycleOffset: 0 + m_Transitions: + - {fileID: 5192254936906539051} + - {fileID: -3630659354654148562} + m_StateMachineBehaviours: [] + m_Position: {x: 50, y: 50, z: 0} + m_IKOnFeet: 1 + m_WriteDefaultValues: 1 + m_Mirror: 0 + m_SpeedParameterActive: 0 + m_MirrorParameterActive: 0 + m_CycleOffsetParameterActive: 0 + m_TimeParameterActive: 0 + m_Motion: {fileID: 7400000, guid: 2a7cc8d66d3c2fc46a54cbf3d95e3b2d, type: 2} + m_Tag: + m_SpeedParameter: + m_MirrorParameter: + m_CycleOffsetParameter: + m_TimeParameter: +--- !u!1102 &-1561510447695394969 +AnimatorState: + serializedVersion: 6 + m_ObjectHideFlags: 1 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: UC01_001_INIT_POSE + m_Speed: 1 + m_CycleOffset: 0 + m_Transitions: + - {fileID: 568215038525939242} + m_StateMachineBehaviours: [] + m_Position: {x: 50, y: 50, z: 0} + m_IKOnFeet: 1 + m_WriteDefaultValues: 1 + m_Mirror: 0 + m_SpeedParameterActive: 0 + m_MirrorParameterActive: 0 + m_CycleOffsetParameterActive: 0 + m_TimeParameterActive: 0 + m_Motion: {fileID: 5322403403441133380, guid: 6f7e0371a1f07ea49b5d6fe4d634ae6c, type: 3} + m_Tag: + m_SpeedParameter: + m_MirrorParameter: + m_CycleOffsetParameter: + m_TimeParameter: +--- !u!1101 &-916830137542702695 +AnimatorStateTransition: + m_ObjectHideFlags: 1 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: + m_Conditions: + - m_ConditionMode: 1 + m_ConditionEvent: Back + m_EventTreshold: 0 + m_DstStateMachine: {fileID: 0} + m_DstState: {fileID: -2037826335270817655} + m_Solo: 0 + m_Mute: 0 + m_IsExit: 0 + serializedVersion: 3 + m_TransitionDuration: 0.25 + m_TransitionOffset: 0 + m_ExitTime: 0.6875 + m_HasExitTime: 0 + m_HasFixedDuration: 1 + m_InterruptionSource: 0 + m_OrderedInterruption: 1 + m_CanTransitionToSelf: 1 +--- !u!91 &9100000 +AnimatorController: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: UniteInTheSky + serializedVersion: 5 + m_AnimatorParameters: + - m_Name: Next + m_Type: 9 + m_DefaultFloat: 0 + m_DefaultInt: 0 + m_DefaultBool: 0 + m_Controller: {fileID: 0} + - m_Name: Back + m_Type: 9 + m_DefaultFloat: 0 + m_DefaultInt: 0 + m_DefaultBool: 0 + m_Controller: {fileID: 0} + m_AnimatorLayers: + - serializedVersion: 5 + m_Name: Base Layer + m_StateMachine: {fileID: -2476057408743069352} + m_Mask: {fileID: 0} + m_Motions: [] + m_Behaviours: [] + m_BlendingMode: 0 + m_SyncedLayerIndex: -1 + m_DefaultWeight: 0 + m_IKPass: 0 + m_SyncedLayerAffectsTiming: 0 + m_Controller: {fileID: 9100000} +--- !u!1101 &568215038525939242 +AnimatorStateTransition: + m_ObjectHideFlags: 1 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: + m_Conditions: [] + m_DstStateMachine: {fileID: 0} + m_DstState: {fileID: 696072945675995140} + m_Solo: 0 + m_Mute: 0 + m_IsExit: 0 + serializedVersion: 3 + m_TransitionDuration: 0.25 + m_TransitionOffset: 0 + m_ExitTime: 0.77272725 + m_HasExitTime: 1 + m_HasFixedDuration: 1 + m_InterruptionSource: 0 + m_OrderedInterruption: 1 + m_CanTransitionToSelf: 1 +--- !u!1102 &696072945675995140 +AnimatorState: + serializedVersion: 6 + m_ObjectHideFlags: 1 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: UC01_001_JAK01_003 (short) + m_Speed: 1 + m_CycleOffset: 0 + m_Transitions: + - {fileID: -5330246061505920765} + - {fileID: 3175375460379069471} + m_StateMachineBehaviours: [] + m_Position: {x: 50, y: 50, z: 0} + m_IKOnFeet: 1 + m_WriteDefaultValues: 1 + m_Mirror: 0 + m_SpeedParameterActive: 0 + m_MirrorParameterActive: 0 + m_CycleOffsetParameterActive: 0 + m_TimeParameterActive: 0 + m_Motion: {fileID: -6150270346426837497, guid: 6f7e0371a1f07ea49b5d6fe4d634ae6c, type: 3} + m_Tag: + m_SpeedParameter: + m_MirrorParameter: + m_CycleOffsetParameter: + m_TimeParameter: +--- !u!1102 &1912442270958618819 +AnimatorState: + serializedVersion: 6 + m_ObjectHideFlags: 1 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: RUN00_F + m_Speed: 1 + m_CycleOffset: 0 + m_Transitions: + - {fileID: -4051815149419108730} + - {fileID: -916830137542702695} + m_StateMachineBehaviours: [] + m_Position: {x: 50, y: 50, z: 0} + m_IKOnFeet: 1 + m_WriteDefaultValues: 1 + m_Mirror: 0 + m_SpeedParameterActive: 0 + m_MirrorParameterActive: 0 + m_CycleOffsetParameterActive: 0 + m_TimeParameterActive: 0 + m_Motion: {fileID: 7400000, guid: d57512b99bc2cc84f92c873f858d9714, type: 2} + m_Tag: + m_SpeedParameter: + m_MirrorParameter: + m_CycleOffsetParameter: + m_TimeParameter: +--- !u!1102 &2495779494147398468 +AnimatorState: + serializedVersion: 6 + m_ObjectHideFlags: 1 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: UC01_001_JAK01_003 + m_Speed: 1 + m_CycleOffset: 0 + m_Transitions: [] + m_StateMachineBehaviours: [] + m_Position: {x: 50, y: 50, z: 0} + m_IKOnFeet: 1 + m_WriteDefaultValues: 1 + m_Mirror: 0 + m_SpeedParameterActive: 0 + m_MirrorParameterActive: 0 + m_CycleOffsetParameterActive: 0 + m_TimeParameterActive: 0 + m_Motion: {fileID: 7400000, guid: 6f7e0371a1f07ea49b5d6fe4d634ae6c, type: 3} + m_Tag: + m_SpeedParameter: + m_MirrorParameter: + m_CycleOffsetParameter: + m_TimeParameter: +--- !u!1101 &3175375460379069471 +AnimatorStateTransition: + m_ObjectHideFlags: 1 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: + m_Conditions: + - m_ConditionMode: 1 + m_ConditionEvent: Back + m_EventTreshold: 0 + m_DstStateMachine: {fileID: 0} + m_DstState: {fileID: 6956152088544691744} + m_Solo: 0 + m_Mute: 0 + m_IsExit: 0 + serializedVersion: 3 + m_TransitionDuration: 0.25 + m_TransitionOffset: 0 + m_ExitTime: 0.9985577 + m_HasExitTime: 0 + m_HasFixedDuration: 1 + m_InterruptionSource: 0 + m_OrderedInterruption: 1 + m_CanTransitionToSelf: 1 +--- !u!1101 &5192254936906539051 +AnimatorStateTransition: + m_ObjectHideFlags: 1 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: + m_Conditions: + - m_ConditionMode: 1 + m_ConditionEvent: Next + m_EventTreshold: 0 + m_DstStateMachine: {fileID: 0} + m_DstState: {fileID: 1912442270958618819} + m_Solo: 0 + m_Mute: 0 + m_IsExit: 0 + serializedVersion: 3 + m_TransitionDuration: 0.25 + m_TransitionOffset: 0 + m_ExitTime: 0.9698795 + m_HasExitTime: 0 + m_HasFixedDuration: 1 + m_InterruptionSource: 0 + m_OrderedInterruption: 1 + m_CanTransitionToSelf: 1 +--- !u!1102 &6956152088544691744 +AnimatorState: + serializedVersion: 6 + m_ObjectHideFlags: 1 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: WAIT04 + m_Speed: 1 + m_CycleOffset: 0 + m_Transitions: + - {fileID: 7249238807102717173} + - {fileID: 7236196480753496729} + m_StateMachineBehaviours: [] + m_Position: {x: 50, y: 50, z: 0} + m_IKOnFeet: 1 + m_WriteDefaultValues: 1 + m_Mirror: 0 + m_SpeedParameterActive: 0 + m_MirrorParameterActive: 0 + m_CycleOffsetParameterActive: 0 + m_TimeParameterActive: 0 + m_Motion: {fileID: 7400000, guid: 3a954c05a2f94004eaff3df94a45c3ed, type: 2} + m_Tag: + m_SpeedParameter: + m_MirrorParameter: + m_CycleOffsetParameter: + m_TimeParameter: +--- !u!1101 &7236196480753496729 +AnimatorStateTransition: + m_ObjectHideFlags: 1 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: + m_Conditions: + - m_ConditionMode: 1 + m_ConditionEvent: Back + m_EventTreshold: 0 + m_DstStateMachine: {fileID: 0} + m_DstState: {fileID: 1912442270958618819} + m_Solo: 0 + m_Mute: 0 + m_IsExit: 0 + serializedVersion: 3 + m_TransitionDuration: 0.25 + m_TransitionOffset: 0 + m_ExitTime: 0.9516129 + m_HasExitTime: 0 + m_HasFixedDuration: 1 + m_InterruptionSource: 0 + m_OrderedInterruption: 1 + m_CanTransitionToSelf: 1 +--- !u!1101 &7249238807102717173 +AnimatorStateTransition: + m_ObjectHideFlags: 1 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: + m_Conditions: + - m_ConditionMode: 1 + m_ConditionEvent: Next + m_EventTreshold: 0 + m_DstStateMachine: {fileID: 0} + m_DstState: {fileID: 696072945675995140} + m_Solo: 0 + m_Mute: 0 + m_IsExit: 0 + serializedVersion: 3 + m_TransitionDuration: 0.25 + m_TransitionOffset: 0 + m_ExitTime: 0.9516129 + m_HasExitTime: 0 + m_HasFixedDuration: 1 + m_InterruptionSource: 0 + m_OrderedInterruption: 1 + m_CanTransitionToSelf: 1 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/UniteInTheSky.controller.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/UniteInTheSky.controller.meta new file mode 100644 index 00000000..7f54f5ec --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/UniteInTheSky.controller.meta @@ -0,0 +1,15 @@ +fileFormatVersion: 2 +guid: 5d5603d7af037e1498d1f99450574dca +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 9100000 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/UniteInTheSky.controller + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/UnityCHanKAGURA.fbx b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/UnityCHanKAGURA.fbx new file mode 100644 index 00000000..030c246e --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/UnityCHanKAGURA.fbx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0b3e2eb35233f716fa175d5da35f8ae55c4e20e92025bb12f45f819e404b03f1 +size 7144380 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/UnityCHanKAGURA.fbx.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/UnityCHanKAGURA.fbx.meta new file mode 100644 index 00000000..13338b1c --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/UnityCHanKAGURA.fbx.meta @@ -0,0 +1,2266 @@ +fileFormatVersion: 2 +guid: 13d8e3dd1da9f6845b5d673e9ac54ecf +ModelImporter: + serializedVersion: 22200 + internalIDToNameTable: [] + externalObjects: {} + materials: + materialImportMode: 2 + materialName: 0 + materialSearch: 1 + materialLocation: 1 + animations: + legacyGenerateAnimations: 4 + bakeSimulation: 0 + resampleCurves: 1 + optimizeGameObjects: 0 + removeConstantScaleCurves: 0 + motionNodeName: + rigImportErrors: + rigImportWarnings: + animationImportErrors: + animationImportWarnings: + animationRetargetingWarnings: + animationDoRetargetingWarnings: 0 + importAnimatedCustomProperties: 0 + importConstraints: 0 + animationCompression: 3 + animationRotationError: 0.5 + animationPositionError: 0.5 + animationScaleError: 0.5 + animationWrapMode: 0 + extraExposedTransformPaths: [] + extraUserProperties: [] + clipAnimations: [] + isReadable: 1 + meshes: + lODScreenPercentages: [] + globalScale: 1 + meshCompression: 0 + addColliders: 0 + useSRGBMaterialColor: 1 + sortHierarchyByName: 1 + importVisibility: 1 + importBlendShapes: 1 + importCameras: 1 + importLights: 1 + nodeNameCollisionStrategy: 1 + fileIdsGeneration: 2 + swapUVChannels: 0 + generateSecondaryUV: 0 + useFileUnits: 1 + keepQuads: 0 + weldVertices: 1 + bakeAxisConversion: 0 + preserveHierarchy: 0 + skinWeightsMode: 0 + maxBonesPerVertex: 4 + minBoneWeight: 0.001 + optimizeBones: 1 + meshOptimizationFlags: -1 + indexFormat: 0 + secondaryUVAngleDistortion: 8 + secondaryUVAreaDistortion: 15.000001 + secondaryUVHardAngle: 88 + secondaryUVMarginMethod: 1 + secondaryUVMinLightmapResolution: 40 + secondaryUVMinObjectScale: 1 + secondaryUVPackMargin: 4 + useFileScale: 1 + strictVertexDataChecks: 0 + tangentSpace: + normalSmoothAngle: 60 + normalImportMode: 0 + tangentImportMode: 3 + normalCalculationMode: 4 + legacyComputeAllNormalsFromSmoothingGroupsWhenMeshHasBlendShapes: 0 + blendShapeNormalImportMode: 1 + normalSmoothingSource: 0 + referencedClips: [] + importAnimation: 1 + humanDescription: + serializedVersion: 3 + human: + - boneName: CH_Hips + humanName: Hips + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_Thigh_L + humanName: LeftUpperLeg + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_Thigh_R + humanName: RightUpperLeg + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_Shin_L + humanName: LeftLowerLeg + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_Shin_R + humanName: RightLowerLeg + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_Foot_L + humanName: LeftFoot + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_Foot_R + humanName: RightFoot + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_Spine + humanName: Spine + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_Chest + humanName: Chest + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_Neck + humanName: Neck + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_Head + humanName: Head + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_Shou_L + humanName: LeftShoulder + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_Shou_R + humanName: RightShoulder + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_Uppe_L + humanName: LeftUpperArm + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_Uppe_R + humanName: RightUpperArm + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_For_L + humanName: LeftLowerArm + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_For_R + humanName: RightLowerArm + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_Hand_L + humanName: LeftHand + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_Hand_R + humanName: RightHand + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_Toe_L + humanName: LeftToes + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_Toe_R + humanName: RightToes + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_eye_L + humanName: LeftEye + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_eye_R + humanName: RightEye + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_FingerTh0_L + humanName: Left Thumb Proximal + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_FingerTh1_L + humanName: Left Thumb Intermediate + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_FingerTh2_L + humanName: Left Thumb Distal + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_FingerIn0_L + humanName: Left Index Proximal + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_FingerIn1_L + humanName: Left Index Intermediate + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_FingerIn2_L + humanName: Left Index Distal + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_FingerMid0_L + humanName: Left Middle Proximal + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_FingerMid1_L + humanName: Left Middle Intermediate + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_FingerMid2_L + humanName: Left Middle Distal + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_FingerR0_L + humanName: Left Ring Proximal + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_FingerR1_L + humanName: Left Ring Intermediate + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_FingerR2_L + humanName: Left Ring Distal + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_FingerP0_L + humanName: Left Little Proximal + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_FingerP1_L + humanName: Left Little Intermediate + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_FingerP2_L + humanName: Left Little Distal + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_FingerTh0_R + humanName: Right Thumb Proximal + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_FingerTh1_R + humanName: Right Thumb Intermediate + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_FingerTh2_R + humanName: Right Thumb Distal + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_FingerIn0_R + humanName: Right Index Proximal + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_FingerIn1_R + humanName: Right Index Intermediate + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_FingerIn2_R + humanName: Right Index Distal + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_FingerMid0_R + humanName: Right Middle Proximal + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_FingerMid1_R + humanName: Right Middle Intermediate + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_FingerMid2_R + humanName: Right Middle Distal + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_FingerR0_R + humanName: Right Ring Proximal + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_FingerR1_R + humanName: Right Ring Intermediate + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_FingerR2_R + humanName: Right Ring Distal + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_FingerP0_R + humanName: Right Little Proximal + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_FingerP1_R + humanName: Right Little Intermediate + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + - boneName: CH_FingerP2_R + humanName: Right Little Distal + limit: + min: {x: 0, y: 0, z: 0} + max: {x: 0, y: 0, z: 0} + value: {x: 0, y: 0, z: 0} + length: 0 + modified: 0 + skeleton: + - name: UnityCHanKAGURA_B(Clone) + parentName: + position: {x: 0, y: 0, z: 0} + rotation: {x: 0, y: 0, z: 0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: Character1_Reference + parentName: UnityCHanKAGURA_B(Clone) + position: {x: -0, y: 0, z: 0} + rotation: {x: 0.019478308, y: 6.7074776e-11, z: 0.000000006886462, w: 0.9998103} + scale: {x: 1, y: 0.99999994, z: 0.99999994} + - name: CH_Hips + parentName: Character1_Reference + position: {x: 1.8092397e-12, y: 0.84116226, z: -0.01639} + rotation: {x: -0.019478302, y: -7.177182e-18, z: 6.3360314e-16, w: 0.9998103} + scale: {x: 1, y: 1, z: 1} + - name: CH_Thigh_L + parentName: CH_Hips + position: {x: -0.08826721, y: -0.014284544, z: 0.002355653} + rotation: {x: -0.13432857, y: -0.17403738, z: 0.5565042, w: 0.8012303} + scale: {x: 0.9999999, y: 0.9999998, z: 0.9999999} + - name: CH_Shin_L + parentName: CH_Thigh_L + position: {x: -0.33039492, y: -0.14232448, z: -0.040917292} + rotation: {x: 0.6617167, y: -0.5369391, z: 0.44836724, w: 0.2698041} + scale: {x: 0.99999994, y: 1.0000001, z: 1.0000001} + - name: DB_Leg_D_01_L + parentName: CH_Shin_L + position: {x: -0.015720347, y: 0.36488265, z: 0.018263556} + rotation: {x: -0.6654126, y: 0.6857607, z: -0.20170403, w: 0.21511385} + scale: {x: 1, y: 1.0000002, z: 0.99999994} + - name: DB_Leg_D_02_L + parentName: DB_Leg_D_01_L + position: {x: -0.020465324, y: -0.0057213255, z: -0.0148777515} + rotation: {x: 0.83505213, y: 0.2453058, z: 0.21297534, w: -0.44402093} + scale: {x: 1.0000001, y: 1, z: 1} + - name: DB_Leg_D_02_L_end + parentName: DB_Leg_D_02_L + position: {x: -0, y: 0.02594052, z: 0} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: DB_Leg_B_01_L + parentName: CH_Shin_L + position: {x: -0.015909798, y: 0.3523997, z: 0.018111004} + rotation: {x: 0.8541138, y: -0.31677046, z: -0.35583758, w: -0.208628} + scale: {x: 1.0000001, y: 1.0000001, z: 0.9999998} + - name: DB_Leg_B_02_L + parentName: DB_Leg_B_01_L + position: {x: -0.019698037, y: -0.002069448, z: -0.016751628} + rotation: {x: -0.33618087, y: -0.33662862, z: -0.08369401, w: 0.8755906} + scale: {x: 1.0000001, y: 1.0000004, z: 1.0000002} + - name: DB_Leg_B_02_L_end + parentName: DB_Leg_B_02_L + position: {x: -0, y: 0.025940558, z: 0} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: DB_Leg_A_01_L + parentName: CH_Shin_L + position: {x: -0.016215084, y: 0.3530168, z: 0.008331124} + rotation: {x: 0.8030182, y: -0.111592114, z: 0.5777915, w: 0.09415919} + scale: {x: 0.9999973, y: 0.9999997, z: 1.0000002} + - name: DB_Leg_A_02_L + parentName: DB_Leg_A_01_L + position: {x: -0.025264768, y: -0.0006684357, z: 0.0058448003} + rotation: {x: 0.114606865, y: 0.11413812, z: -0.00020055493, w: 0.9868322} + scale: {x: 1.0000002, y: 1.0000002, z: 1} + - name: DB_Leg_A_02_L_end + parentName: DB_Leg_A_02_L + position: {x: -0, y: 0.025940567, z: 0} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: DB_Leg_C_01_L + parentName: CH_Shin_L + position: {x: -0.015241163, y: 0.36570385, z: 0.007816298} + rotation: {x: 0.12014065, y: -0.30020246, z: -0.5220277, w: 0.7892604} + scale: {x: 0.9999999, y: 0.99999994, z: 1.0000001} + - name: DB_Leg_C_02_L + parentName: DB_Leg_C_01_L + position: {x: -0.024774697, y: 0.0006814647, z: -0.0076592406} + rotation: {x: 0.460765, y: -0.13830368, z: 0.05783245, w: 0.87477034} + scale: {x: 1.0000001, y: 0.99999994, z: 1} + - name: DB_Leg_C_02_L_end + parentName: DB_Leg_C_02_L + position: {x: -0, y: 0.02594055, z: 0} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: CH_Foot_L + parentName: CH_Shin_L + position: {x: 0.029875912, y: 0.3874966, z: 0.008091103} + rotation: {x: 0.061005134, y: 0.21119405, z: 0.92646635, w: -0.30550867} + scale: {x: 0.9999999, y: 1.0000001, z: 0.99999994} + - name: CH_Toe_L + parentName: CH_Foot_L + position: {x: -0.11841869, y: 0.013799544, z: 0.025782034} + rotation: {x: -0.12559782, y: 0.19541794, z: 0.38654023, w: 0.89253783} + scale: {x: 1.0000001, y: 1.0000001, z: 1.0000002} + - name: CH_Toe_L_end + parentName: CH_Toe_L + position: {x: -0, y: 0.12197585, z: 0} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: CH_Thigh_R + parentName: CH_Hips + position: {x: 0.08810974, y: -0.014284541, z: 0.0023555718} + rotation: {x: 0.5563986, y: 0.80125886, z: -0.13458051, w: -0.17404875} + scale: {x: 0.9999998, y: 0.9999997, z: 0.9999997} + - name: CH_Shin_R + parentName: CH_Thigh_R + position: {x: -0.33036518, y: -0.14234428, z: 0.041079752} + rotation: {x: 0.66174173, y: -0.5370415, z: -0.44836113, w: -0.26954895} + scale: {x: 1, y: 1.0000001, z: 1} + - name: CH_Foot_R + parentName: CH_Shin_R + position: {x: 0.02987569, y: 0.3874962, z: -0.008090359} + rotation: {x: -0.060998213, y: -0.21113306, z: 0.9264768, w: -0.30552068} + scale: {x: 1.0000005, y: 1.0000002, z: 1} + - name: CH_Toe_R + parentName: CH_Foot_R + position: {x: -0.11841994, y: 0.013798753, z: -0.025776036} + rotation: {x: 0.12555602, y: -0.19537207, z: 0.38653955, w: 0.892554} + scale: {x: 1, y: 1.0000001, z: 1.0000001} + - name: CH_Toe_R_end + parentName: CH_Toe_R + position: {x: -0, y: 0.12197583, z: 0} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: DB_Leg_D_01_R + parentName: CH_Shin_R + position: {x: -0.015720518, y: 0.36488253, z: -0.018263748} + rotation: {x: -0.6654132, y: 0.68576103, z: 0.20170169, w: -0.21511294} + scale: {x: 0.99999964, y: 0.9999996, z: 0.9999998} + - name: DB_Leg_D_02_R + parentName: DB_Leg_D_01_R + position: {x: -0.020465378, y: -0.0057213013, z: 0.014877751} + rotation: {x: 0.83505267, y: 0.24530488, z: -0.21297555, w: 0.44402036} + scale: {x: 1.0000001, y: 1.0000001, z: 1} + - name: DB_Leg_D_02_R_end + parentName: DB_Leg_D_02_R + position: {x: -0, y: 0.025940496, z: 0} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: DB_Leg_B_01_R + parentName: CH_Shin_R + position: {x: -0.015910042, y: 0.3523994, z: -0.018111194} + rotation: {x: 0.8541113, y: -0.31677485, z: 0.35583863, w: 0.2086299} + scale: {x: 0.9999997, y: 0.9999997, z: 0.99999976} + - name: DB_Leg_B_02_R + parentName: DB_Leg_B_01_R + position: {x: -0.019698039, y: -0.002069446, z: 0.016751638} + rotation: {x: 0.33618426, y: 0.33662817, z: -0.08369033, w: 0.87558985} + scale: {x: 1, y: 0.9999998, z: 0.9999998} + - name: DB_Leg_B_02_R_end + parentName: DB_Leg_B_02_R + position: {x: -0, y: 0.025940554, z: 0} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: DB_Leg_A_01_R + parentName: CH_Shin_R + position: {x: -0.016215283, y: 0.35301623, z: -0.008331298} + rotation: {x: 0.8030201, y: -0.11158819, z: -0.57778937, w: -0.094161056} + scale: {x: 0.99999917, y: 0.99999976, z: 1.0000001} + - name: DB_Leg_A_02_R + parentName: DB_Leg_A_01_R + position: {x: -0.025264671, y: -0.0006686662, z: -0.005844774} + rotation: {x: -0.11460477, y: -0.11413833, z: -0.00020045551, w: 0.9868324} + scale: {x: 1.0000001, y: 1, z: 0.9999997} + - name: DB_Leg_A_02_R_end + parentName: DB_Leg_A_02_R + position: {x: -0, y: 0.025940524, z: 0} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: DB_Leg_C_01_R + parentName: CH_Shin_R + position: {x: -0.0152413435, y: 0.36570352, z: -0.0078165} + rotation: {x: -0.12014231, y: 0.3002036, z: -0.52202654, w: 0.78926045} + scale: {x: 0.9999998, y: 1, z: 1} + - name: DB_Leg_C_02_R + parentName: DB_Leg_C_01_R + position: {x: -0.024774678, y: 0.0006814384, z: 0.007659211} + rotation: {x: -0.46076074, y: 0.13830246, z: 0.057832856, w: 0.8747728} + scale: {x: 1.0000001, y: 0.9999999, z: 1} + - name: DB_Leg_C_02_R_end + parentName: DB_Leg_C_02_R + position: {x: -0, y: 0.025940556, z: 0} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: CH_Spine + parentName: CH_Hips + position: {x: 8.7094215e-10, y: 0.052382283, z: 0.003530197} + rotation: {x: 0.013204711, y: 5.156483e-12, z: -0.0000000083063645, w: 0.99991286} + scale: {x: 1, y: 0.99999994, z: 0.9999999} + - name: CH_Chest + parentName: CH_Spine + position: {x: -6.7333555e-10, y: 0.16491224, z: 0.0065771495} + rotation: {x: -0.031049041, y: -7.781174e-11, z: 0.0000000020394886, w: 0.99951786} + scale: {x: 1, y: 0.9999998, z: 0.9999999} + - name: CH_Neck + parentName: CH_Chest + position: {x: -0.0000000010773759, y: 0.24534914, z: -0.035706315} + rotation: {x: 0.18392648, y: 3.824621e-10, z: 0.0000000021234396, w: 0.98294} + scale: {x: 1, y: 1, z: 1} + - name: CH_Head + parentName: CH_Neck + position: {x: -2.0999868e-14, y: 0.090854794, z: -0.034652326} + rotation: {x: -0.16635364, y: 8.074895e-16, z: 2.1137224e-15, w: 0.98606616} + scale: {x: 1, y: 1, z: 1} + - name: CH_eye_L + parentName: CH_Head + position: {x: -0.017834922, y: 0.04682619, z: 0.015588715} + rotation: {x: 0.13649605, y: -0.17832369, z: 0.06646494, w: 0.97218925} + scale: {x: 1.0000001, y: 0.9999998, z: 1} + - name: CH_eye_L_end + parentName: CH_eye_L + position: {x: -0, y: 0.067616336, z: 0} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: CH_eye_R + parentName: CH_Head + position: {x: 0.017834948, y: 0.04682619, z: 0.01558871} + rotation: {x: 0.061989237, y: 0.96416754, z: 0.13923119, w: -0.21714754} + scale: {x: 0.9999999, y: 0.9999999, z: 0.99999994} + - name: CH_eye_R_end + parentName: CH_eye_R + position: {x: -0, y: 0.067616336, z: 0} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: CH_HairRoot + parentName: CH_Head + position: {x: -0.000078737154, y: 0.09505858, z: 0.023397414} + rotation: {x: -0.7071067, y: 0.7071068, z: 0.00000009487339, w: -0.00000018048416} + scale: {x: 1, y: 0.99999976, z: 1} + - name: DB_Hair_F1_01_L + parentName: CH_HairRoot + position: {x: -0.0022801124, y: 0.02419522, z: -0.10100859} + rotation: {x: 0.030597411, y: 0.96931905, z: 0.24035265, w: -0.041411996} + scale: {x: 1, y: 1.0000005, z: 0.9999999} + - name: DB_Hair_F1_02_L + parentName: DB_Hair_F1_01_L + position: {x: -0.03985014, y: -0.005924668, z: -0.0063618347} + rotation: {x: -0.013739697, y: -0.16939762, z: 0.014907225, w: 0.9853393} + scale: {x: 1.0000001, y: 0.99999994, z: 0.9999998} + - name: DB_Hair_F1_02_L_end + parentName: DB_Hair_F1_02_L + position: {x: -0, y: 0.040787358, z: 0} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: DB_Hair_F1_01_R + parentName: CH_HairRoot + position: {x: -0.020420857, y: -0.02655642, z: -0.097100414} + rotation: {x: 0.022290053, y: 0.96187854, z: -0.26513365, w: -0.06322205} + scale: {x: 0.9999999, y: 0.99999994, z: 0.99999994} + - name: DB_Hair_F1_01_R_end + parentName: DB_Hair_F1_01_R + position: {x: -0, y: 0.11285751, z: 0} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: DB_Hair_F2_01_L + parentName: CH_HairRoot + position: {x: 0.011319053, y: 0.07265613, z: -0.074083224} + rotation: {x: -0.20547554, y: 0.92748624, z: 0.27937216, w: 0.13964385} + scale: {x: 0.9999999, y: 1, z: 1.0000001} + - name: DB_Hair_F2_01_L_end + parentName: DB_Hair_F2_01_L + position: {x: -0, y: 0.11285751, z: 0} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: DB_Hair_F3_01_L + parentName: CH_HairRoot + position: {x: -0.034934714, y: 0.068165414, z: -0.09195771} + rotation: {x: 0.81319416, y: -0.33171567, z: 0.46750733, w: 0.10058277} + scale: {x: 1.0000001, y: 1.0000002, z: 0.9999998} + - name: DB_Hair_F3_02_L + parentName: DB_Hair_F3_01_L + position: {x: 0.0045398497, y: -0.039559294, z: 0.016659176} + rotation: {x: -0.48918706, y: -0.26743877, z: 0.7575304, w: 0.3395884} + scale: {x: 1.0000002, y: 1.0000002, z: 1.0000002} + - name: DB_Hair_F3_02_L_end + parentName: DB_Hair_F3_02_L + position: {x: -0, y: 0.04316329, z: 0} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: DB_Hair_S1_01_L + parentName: CH_HairRoot + position: {x: -0.019978656, y: 0.08724394, z: -0.06901977} + rotation: {x: -0.20777045, y: 0.6752454, z: 0.70667404, w: -0.038560253} + scale: {x: 1, y: 0.9999992, z: 1.0000001} + - name: DB_Hair_S1_02_L + parentName: DB_Hair_S1_01_L + position: {x: -0.06366916, y: 0.0037784262, z: -0.013001636} + rotation: {x: -0.14839575, y: -0.17151457, z: -0.059975024, w: 0.97209287} + scale: {x: 0.9999999, y: 1, z: 1.0000001} + - name: DB_Hair_S1_03_L + parentName: DB_Hair_S1_02_L + position: {x: -0.049858354, y: -0.010453356, z: -0.00893953} + rotation: {x: 0.08697805, y: -0.13373399, z: 0.14230917, w: 0.97688186} + scale: {x: 1, y: 1, z: 0.99999994} + - name: DB_Hair_S1_03_L_end + parentName: DB_Hair_S1_03_L + position: {x: -0, y: 0.05172089, z: 0} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: DB_Hair_S2_01_L + parentName: CH_HairRoot + position: {x: -0.028588507, y: 0.09171348, z: -0.047888175} + rotation: {x: -0.2981027, y: 0.6886669, z: 0.65323377, w: -0.10078889} + scale: {x: 0.9999999, y: 0.9999995, z: 0.9999998} + - name: DB_Hair_S2_02_L + parentName: DB_Hair_S2_01_L + position: {x: -0.065382436, y: -0.0035510426, z: -0.016678598} + rotation: {x: 0.91674775, y: 0.12557316, z: 0.12861632, w: 0.35673907} + scale: {x: 1.0000001, y: 1.0000004, z: 1.0000001} + - name: DB_Hair_S2_03_L + parentName: DB_Hair_S2_02_L + position: {x: -0.04668184, y: -0.017777428, z: 0.011950299} + rotation: {x: 0.9063441, y: 0.09186723, z: -0.19777134, w: -0.3619216} + scale: {x: 1.0000001, y: 1, z: 0.99999964} + - name: DB_Hair_S2_03_L_end + parentName: DB_Hair_S2_03_L + position: {x: -0, y: 0.0513617, z: 0} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: DB_Hair_S3_02_L + parentName: DB_Hair_S2_01_L + position: {x: -0.05340869, y: 0.019261943, z: -0.0020288706} + rotation: {x: -0.038595226, y: -0.0036078964, z: -0.16786668, w: 0.98504734} + scale: {x: 1.0000001, y: 1.0000001, z: 1.0000004} + - name: DB_Hair_S3_03_L + parentName: DB_Hair_S3_02_L + position: {x: -0.028766641, y: 0.0014682745, z: -0.00022172167} + rotation: {x: 0.05522288, y: 0.0009373553, z: -0.13676472, w: 0.98906267} + scale: {x: 1, y: 1.0000001, z: 1} + - name: DB_Hair_S3_03_L_end + parentName: DB_Hair_S3_03_L + position: {x: -0, y: 0.02880491, z: 0} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: DB_Hair_S4_01_L + parentName: DB_Hair_S2_01_L + position: {x: -0.013684165, y: 0.032540567, z: 0.008590495} + rotation: {x: -0.017482588, y: -0.2846315, z: 0.20225425, w: 0.93689513} + scale: {x: 1.0000001, y: 1.0000004, z: 1} + - name: DB_Hair_S4_02_L + parentName: DB_Hair_S4_01_L + position: {x: -0.008308211, y: 0.01992834, z: 0.008190181} + rotation: {x: -0.09751992, y: 0.24453256, z: -0.60901856, w: 0.74819124} + scale: {x: 1, y: 0.99999994, z: 1.0000001} + - name: DB_Hair_S4_02_L_end + parentName: DB_Hair_S4_02_L + position: {x: -0, y: 0.023092227, z: 0} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: DB_Hontai_01_L + parentName: CH_HairRoot + position: {x: -0.086341955, y: 0.062616855, z: -0.042004235} + rotation: {x: -0.3612036, y: 0.20890346, z: 0.90290606, w: 0.10320863} + scale: {x: 0.99999946, y: 0.99999994, z: 0.99999976} + - name: DB_Hontai_02_L + parentName: DB_Hontai_01_L + position: {x: 0.013905792, y: -0.003743007, z: 0.07425396} + rotation: {x: 0.30036432, y: 0.883534, z: -0.33884135, w: 0.11973093} + scale: {x: 1, y: 0.9999997, z: 1} + - name: DB_Hontai_03_L + parentName: DB_Hontai_02_L + position: {x: 0.068108946, y: -0.04859436, z: -0.015849028} + rotation: {x: 0.2806118, y: 0.89910394, z: -0.26827514, w: -0.20223151} + scale: {x: 1.0000001, y: 1.0000001, z: 0.99999994} + - name: DB_Hontai_03_L_end + parentName: DB_Hontai_03_L + position: {x: -0, y: 0.08515516, z: 0} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: DB_Hontai_01_R + parentName: CH_HairRoot + position: {x: -0.086341955, y: -0.06261684, z: -0.042004287} + rotation: {x: -0.10320989, y: 0.9029046, z: 0.20890565, w: 0.36120546} + scale: {x: 1, y: 1.0000001, z: 1.0000001} + - name: DB_Hontai_02_R + parentName: DB_Hontai_01_R + position: {x: 0.013905919, y: -0.0037429333, z: -0.074253894} + rotation: {x: 0.30036542, y: 0.8835329, z: 0.33884236, w: -0.11973349} + scale: {x: 0.9999998, y: 1.0000002, z: 0.99999976} + - name: DB_Hontai_03_R + parentName: DB_Hontai_02_R + position: {x: 0.06810854, y: -0.04859424, z: 0.01584912} + rotation: {x: 0.2806133, y: 0.8991033, z: 0.26827475, w: 0.20223276} + scale: {x: 0.99999994, y: 0.9999998, z: 0.9999999} + - name: DB_Hontai_03_R_end + parentName: DB_Hontai_03_R + position: {x: -0, y: 0.08515518, z: 0} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: DB_Hair_F2_01_R + parentName: CH_HairRoot + position: {x: 0.011319056, y: -0.072656065, z: -0.07408326} + rotation: {x: -0.13964343, y: 0.2793721, z: 0.92748624, w: 0.20547579} + scale: {x: 0.99999994, y: 0.99999994, z: 0.9999998} + - name: DB_Hair_F2_01_R_end + parentName: DB_Hair_F2_01_R + position: {x: -0, y: 0.11285753, z: 0} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: DB_Hair_S1_01_R + parentName: CH_HairRoot + position: {x: -0.019978652, y: -0.08724391, z: -0.06901983} + rotation: {x: 0.0385596, y: 0.7066755, z: 0.6752447, w: 0.20776786} + scale: {x: 1, y: 1.0000001, z: 1.0000001} + - name: DB_Hair_S1_02_R + parentName: DB_Hair_S1_01_R + position: {x: -0.06366941, y: 0.0037786753, z: 0.013001638} + rotation: {x: 0.14843307, y: 0.17151333, z: -0.059982203, w: 0.9720869} + scale: {x: 1.0000001, y: 1.0000002, z: 1} + - name: DB_Hair_S1_03_R + parentName: DB_Hair_S1_02_R + position: {x: -0.04985849, y: -0.010452575, z: 0.008940113} + rotation: {x: -0.08701619, y: 0.13373652, z: 0.14230235, w: 0.9768791} + scale: {x: 1.0000001, y: 0.99999964, z: 0.9999999} + - name: DB_Hair_S1_03_R_end + parentName: DB_Hair_S1_03_R + position: {x: -0, y: 0.0517209, z: 0} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: DB_Hair_F3_01_R + parentName: CH_HairRoot + position: {x: -0.034934867, y: -0.06816536, z: -0.09195772} + rotation: {x: 0.10057529, y: -0.4675015, z: 0.33172283, w: 0.8131955} + scale: {x: 0.9999999, y: 0.9999999, z: 0.9999999} + - name: DB_Hair_F3_02_R + parentName: DB_Hair_F3_01_R + position: {x: 0.0045397305, y: -0.03955913, z: -0.016659042} + rotation: {x: 0.48918247, y: 0.26743096, z: 0.75753194, w: 0.33959767} + scale: {x: 0.9999999, y: 0.99999994, z: 1} + - name: DB_Hair_F3_02_R_end + parentName: DB_Hair_F3_02_R + position: {x: -0, y: 0.043163467, z: 0} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: DB_Hair_S2_01_R + parentName: CH_HairRoot + position: {x: -0.028588654, y: -0.09171347, z: -0.047888234} + rotation: {x: 0.10078835, y: 0.65323323, z: 0.6886672, w: 0.29810333} + scale: {x: 0.99999994, y: 0.9999999, z: 1} + - name: DB_Hair_S2_02_R + parentName: DB_Hair_S2_01_R + position: {x: -0.06538262, y: -0.0035510769, z: 0.016678328} + rotation: {x: 0.9167256, y: 0.12555085, z: -0.12861982, w: -0.3568027} + scale: {x: 1, y: 0.9999999, z: 0.9999999} + - name: DB_Hair_S2_03_R + parentName: DB_Hair_S2_02_R + position: {x: -0.04668216, y: -0.017778108, z: -0.011948963} + rotation: {x: 0.90631807, y: 0.09186826, z: 0.19777018, w: 0.3619872} + scale: {x: 0.99999994, y: 0.99999994, z: 1} + - name: DB_Hair_S2_03_R_end + parentName: DB_Hair_S2_03_R + position: {x: -0, y: 0.05136217, z: 0} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: DB_Hair_S4_01_R + parentName: DB_Hair_S2_01_R + position: {x: -0.01368458, y: 0.032540515, z: -0.008590757} + rotation: {x: 0.017483542, y: 0.2846338, z: 0.20225787, w: 0.93689364} + scale: {x: 1.0000001, y: 1.0000002, z: 1} + - name: DB_Hair_S4_02_R + parentName: DB_Hair_S4_01_R + position: {x: -0.008308558, y: 0.019928548, z: -0.008190398} + rotation: {x: 0.09752138, y: -0.24453498, z: -0.609021, w: 0.74818826} + scale: {x: 1.0000001, y: 1, z: 1.0000002} + - name: DB_Hair_S4_02_R_end + parentName: DB_Hair_S4_02_R + position: {x: -0, y: 0.023092402, z: 0} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: DB_Hair_S3_02_R + parentName: DB_Hair_S2_01_R + position: {x: -0.053408917, y: 0.019262014, z: 0.0020285498} + rotation: {x: 0.03860505, y: 0.0036029941, z: -0.16787569, w: 0.98504543} + scale: {x: 1.0000001, y: 1.0000001, z: 1.0000001} + - name: DB_Hair_S3_03_R + parentName: DB_Hair_S3_02_R + position: {x: -0.028766662, y: 0.0014681387, z: 0.0002216579} + rotation: {x: -0.05523268, y: -0.0009354825, z: -0.13675581, w: 0.9890634} + scale: {x: 0.9999999, y: 1, z: 1} + - name: DB_Hair_S3_03_R_end + parentName: DB_Hair_S3_03_R + position: {x: -0, y: 0.028805094, z: 0} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: DB_HairPonny_E_01 + parentName: CH_HairRoot + position: {x: -0.076593205, y: -0.00000007631247, z: 0.1200824} + rotation: {x: -0.4518244, y: 0.000000019738934, z: 0.8921069, w: 0.000000038989693} + scale: {x: 0.99999976, y: 1, z: 0.9999998} + - name: DB_HairPonny_E_02 + parentName: DB_HairPonny_E_01 + position: {x: -0.015404844, y: 0.0000000023629063, z: 0.018801402} + rotation: {x: -0.000000037458047, y: 0.31132665, z: -0.00000016296224, w: 0.95030296} + scale: {x: 1, y: 1, z: 1} + - name: DB_HairPonny_B_01 + parentName: DB_HairPonny_E_02 + position: {x: -0.030487511, y: 0.06311817, z: -0.00020403988} + rotation: {x: 0.22563586, y: -0.13498113, z: 0.11822663, w: 0.95754427} + scale: {x: 1.0000001, y: 0.99999994, z: 1} + - name: DB_HairPonny_B_02 + parentName: DB_HairPonny_B_01 + position: {x: -0.0677792, y: 0.05507448, z: 0.00058921333} + rotation: {x: -0.28047216, y: 0.10022667, z: -0.2812756, w: 0.91223574} + scale: {x: 1.0000001, y: 1.0000001, z: 1.0000001} + - name: DB_HairPonny_B_03 + parentName: DB_HairPonny_B_02 + position: {x: -0.1008447, y: -0.000000019073486, z: -0.00000053584574} + rotation: {x: 0.04653713, y: -0.001043574, z: 0.046271287, w: 0.9978438} + scale: {x: 0.9999998, y: 1, z: 0.9999998} + - name: DB_HairPonny_B_04 + parentName: DB_HairPonny_B_03 + position: {x: -0.13735363, y: 0.0000000047683715, z: 0.00000050276515} + rotation: {x: 0.043263245, y: 0.007867728, z: 0.042844687, w: 0.9981136} + scale: {x: 0.99999994, y: 0.99999976, z: 0.99999994} + - name: DB_HairPonny_B_05 + parentName: DB_HairPonny_B_04 + position: {x: -0.1275559, y: 0.000000085830685, z: 0.0000000333786} + rotation: {x: 0.07223201, y: 0.022419963, z: 0.07054564, w: 0.9946372} + scale: {x: 1.0000002, y: 1, z: 1} + - name: DB_HairPonny_B_06 + parentName: DB_HairPonny_B_05 + position: {x: -0.05926093, y: -0.000000011920928, z: -0.000000007152557} + rotation: {x: -0.0000008771457, y: 0.00000004516914, z: -0.00000022945459, w: 1} + scale: {x: 1, y: 1.0000001, z: 1.0000001} + - name: DB_HairPonny_B_06_end + parentName: DB_HairPonny_B_06 + position: {x: -0, y: 0.05926101, z: 0} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: DB_HairPonny_C_01 + parentName: DB_HairPonny_E_02 + position: {x: -0.035185028, y: 0.031058721, z: -0.000032242842} + rotation: {x: -0.10873754, y: -0.22070637, z: 0.959001, w: -0.14064851} + scale: {x: 1.0000004, y: 1, z: 1.0000002} + - name: DB_HairPonny_C_02 + parentName: DB_HairPonny_C_01 + position: {x: 0.10580997, y: -0.058940616, z: 0.0035568618} + rotation: {x: 0.24596307, y: -0.0785421, z: -0.23920205, w: 0.93601054} + scale: {x: 1.0000004, y: 1.0000001, z: 1.0000004} + - name: DB_HairPonny_C_03 + parentName: DB_HairPonny_C_02 + position: {x: 0.19330133, y: 0.0000001168251, z: -0.0000007882714} + rotation: {x: -0.06542371, y: 0.0000032108858, z: 0.09619262, w: 0.9932103} + scale: {x: 1.0000001, y: 1.0000002, z: 1.0000002} + - name: DB_HairPonny_C_04 + parentName: DB_HairPonny_C_03 + position: {x: 0.20366955, y: -0.026317017, z: -0.0008639145} + rotation: {x: -0.044628434, y: -0.0055368403, z: 0.09611654, w: 0.9943537} + scale: {x: 0.9999998, y: 0.9999998, z: 0.9999996} + - name: DB_HairPonny_C_05 + parentName: DB_HairPonny_C_04 + position: {x: 0.19776306, y: -0.043082256, z: -0.0023708176} + rotation: {x: 0.108746506, y: -0.0058536273, z: -0.10703975, w: 0.9882725} + scale: {x: 1, y: 1.0000001, z: 1.0000001} + - name: DB_HairPonny_C_05_end + parentName: DB_HairPonny_C_05 + position: {x: -0, y: 0.20241505, z: 0} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: DB_HairPonny_R_01 + parentName: DB_HairPonny_E_02 + position: {x: -0.03397737, y: 0.030513538, z: -0.0000000020680442} + rotation: {x: -0.13481951, y: -0.29193133, z: 0.9050875, w: -0.27823818} + scale: {x: 1.0000005, y: 1.0000004, z: 1.0000001} + - name: DB_HairPonny_R_02 + parentName: DB_HairPonny_R_01 + position: {x: 0.09520173, y: -0.07487118, z: 0.0036545396} + rotation: {x: 0.31161192, y: -0.122890264, z: -0.30340883, w: 0.8920421} + scale: {x: 1, y: 1.0000001, z: 1.0000001} + - name: DB_HairPonny_R_03 + parentName: DB_HairPonny_R_02 + position: {x: 0.19330154, y: 0.000000047683713, z: -0.00000016614794} + rotation: {x: 0.0000009291107, y: -0.00000047113275, z: 0.000000025058398, w: 1} + scale: {x: 1.0000001, y: 0.99999994, z: 1.0000001} + - name: DB_HairPonny_R_04 + parentName: DB_HairPonny_R_03 + position: {x: 0.20536458, y: 0.000000023841856, z: -0.0000011861324} + rotation: {x: 0.0000011089725, y: -0.0000017062997, z: -0.000000352884, w: 1} + scale: {x: 0.9999998, y: 0.99999994, z: 0.99999994} + - name: DB_HairPonny_R_05 + parentName: DB_HairPonny_R_04 + position: {x: 0.20241499, y: 0.00000021934508, z: -0.000000008791685} + rotation: {x: -0.0000002695015, y: 0.0000035446137, z: 0.00000017951245, w: 1} + scale: {x: 1, y: 0.99999976, z: 1} + - name: DB_HairPonny_R_06 + parentName: DB_HairPonny_R_05 + position: {x: 0.15935068, y: 0.000000076293944, z: 0.0000001603365} + rotation: {x: -0.00000044138864, y: -0.00000256038, z: -0.00000040221488, w: 1} + scale: {x: 1.0000002, y: 1.0000001, z: 1.0000001} + - name: DB_HairPonny_R_06_end + parentName: DB_HairPonny_R_06 + position: {x: -0, y: 0.1593509, z: 0} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: DB_HairPonny_E_03 + parentName: DB_HairPonny_E_02 + position: {x: -0.03397736, y: -0.000000037964142, z: 0.017013572} + rotation: {x: 0.0000007290279, y: -0.23003776, z: 0.0000003042932, w: 0.9731817} + scale: {x: 1.0000001, y: 1, z: 1} + - name: DB_HairPonny_E_04 + parentName: DB_HairPonny_E_03 + position: {x: -0.1083464, y: -0.000000009533905, z: 0.054253176} + rotation: {x: -0.00000013284787, y: 0.230036, z: -0.00000043942063, w: 0.97318214} + scale: {x: 1, y: 1, z: 1} + - name: DB_HairPonny_E_05 + parentName: DB_HairPonny_E_04 + position: {x: -0.19330136, y: -1.0618351e-11, z: 0.0000008250285} + rotation: {x: -0.000000007257256, y: 0.0000019455329, z: 0.00000013692186, w: 1} + scale: {x: 1, y: 1, z: 1} + - 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} + 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} + scale: {x: 1, y: 1, z: 1} + - name: DB_HairPonny_E_08 + parentName: DB_HairPonny_E_07 + position: {x: -0.15935099, y: -3.2014213e-12, z: 0.000000019172244} + rotation: {x: 8.3466567e-13, y: 0.0000010160729, z: -5.8440364e-11, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: DB_HairPonny_E_08_end + parentName: DB_HairPonny_E_08 + position: {x: -0, y: 0.15935089, z: 0} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: DB_HairPonny_D_01 + parentName: DB_HairPonny_E_02 + position: {x: -0.033977345, y: -0.000000014100426, z: -0.01103328} + rotation: {x: 0.016233122, y: 0.122253954, z: 0.035176937, w: 0.99174243} + scale: {x: 1, y: 0.99999994, z: 0.99999994} + - name: DB_HairPonny_D_02 + parentName: DB_HairPonny_D_01 + position: {x: -0.11640387, y: 0.0038259223, z: -0.033434466} + rotation: {x: -0.01912243, y: -0.13901094, z: -0.018632984, w: 0.98993087} + scale: {x: 0.9999999, y: 0.99999994, z: 0.99999994} + - name: DB_HairPonny_D_03 + parentName: DB_HairPonny_D_02 + position: {x: -0.1933014, y: -0.0000000020861626, z: 0.0000009214996} + rotation: {x: 0.00000008922146, y: 0.0000038673716, z: 0.00000015285693, w: 1} + scale: {x: 1.0000002, y: 1, z: 1} + - name: DB_HairPonny_D_04 + parentName: DB_HairPonny_D_03 + position: {x: -0.20536436, y: -0.000000020861625, z: 0.0000002304108} + rotation: {x: -0.0000025832887, y: 0.0000015817075, z: 0.00000028815703, w: 1} + scale: {x: 1, y: 0.99999994, z: 0.9999998} + - name: DB_HairPonny_D_05 + parentName: DB_HairPonny_D_04 + position: {x: -0.20241575, y: 0.00000013411045, z: -0.0000002967932} + rotation: {x: -0.0000004515385, y: -0.0000044915355, z: -0.00000030900992, w: 1} + scale: {x: 0.99999994, y: 1, z: 1.0000001} + - name: DB_HairPonny_D_06 + parentName: DB_HairPonny_D_05 + position: {x: -0.15935072, y: 0.000000022649765, z: -0.00000053849504} + rotation: {x: 0.00000238543, y: 0.000001792688, z: 0.00000032581374, w: 1} + scale: {x: 1, y: 1.0000001, z: 1.0000001} + - name: DB_HairPonny_D_06_end + parentName: DB_HairPonny_D_06 + position: {x: -0, y: 0.15935075, z: 0} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: DB_HairPonny_A_01 + parentName: DB_HairPonny_E_02 + position: {x: -0.032159887, y: -0.04864208, z: 0.00024610577} + rotation: {x: -0.34053177, y: -0.13434239, z: -0.2023523, w: 0.90831923} + scale: {x: 1, y: 1.0000001, z: 1.0000001} + - name: DB_HairPonny_A_02 + parentName: DB_HairPonny_A_01 + position: {x: -0.060427006, y: -0.057195153, z: 0.0015233612} + rotation: {x: 0.38153645, y: 0.08539931, z: 0.32513162, w: 0.86106116} + scale: {x: 1.0000002, y: 1, z: 1.0000001} + - name: DB_HairPonny_A_03 + parentName: DB_HairPonny_A_02 + position: {x: -0.10396774, y: -0.001286521, z: -0.000004790425} + rotation: {x: -0.02355242, y: 0.0009919491, z: -0.023307087, w: 0.9994504} + scale: {x: 0.9999998, y: 1, z: 0.99999976} + - name: DB_HairPonny_A_04 + parentName: DB_HairPonny_A_03 + position: {x: -0.13334043, y: -0.0000013965368, z: -0.00000037036835} + rotation: {x: -0.016839607, y: -0.0059545627, z: -0.016580204, w: 0.999703} + scale: {x: 1.0000001, y: 1.0000002, z: 1.0000001} + - name: DB_HairPonny_A_05 + parentName: DB_HairPonny_A_04 + position: {x: -0.13329972, y: 0, z: -0.0000006523728} + rotation: {x: -0.012541608, y: -0.025554592, z: -0.012928888, w: 0.9995112} + scale: {x: 0.99999994, y: 0.9999998, z: 0.99999976} + - name: DB_HairPonny_A_06 + parentName: DB_HairPonny_A_05 + position: {x: -0.10290304, y: -0.000000047683713, z: -0.00000046253203} + rotation: {x: 0.0000005918554, y: 0.00000011036171, z: -0.000000102212645, w: 1} + scale: {x: 1, y: 1.0000001, z: 1.0000002} + - name: DB_HairPonny_A_06_end + parentName: DB_HairPonny_A_06 + position: {x: -0, y: 0.102903135, z: 0} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: DB_HairPonny_L_01 + parentName: DB_HairPonny_E_02 + position: {x: -0.03397739, y: -0.030513402, z: 0.0000000014796052} + rotation: {x: -0.29188433, y: -0.11182668, z: -0.2533033, w: 0.9154976} + scale: {x: 1, y: 0.9999999, z: 0.99999976} + - name: DB_HairPonny_L_02 + parentName: DB_HairPonny_L_01 + position: {x: -0.09749372, y: -0.07195403, z: 0.0000005674362} + rotation: {x: 0.2969104, y: 0.09770134, z: 0.29690993, w: 0.90229887} + scale: {x: 1.0000001, y: 1.0000001, z: 1.0000002} + - name: DB_HairPonny_L_03 + parentName: DB_HairPonny_L_02 + position: {x: -0.19330142, y: 0.000000044107438, z: 0.0000006964048} + rotation: {x: 0.00000029348203, y: 0.0000012077221, z: 0.0000001961271, w: 1} + scale: {x: 1, y: 0.9999997, z: 0.9999999} + - name: DB_HairPonny_L_04 + parentName: DB_HairPonny_L_03 + position: {x: -0.20536473, y: 0.0000000923872, z: 0.00000050125306} + rotation: {x: -0.0000011663931, y: 0.00000074995114, z: -0.00000041768004, w: 1} + scale: {x: 1, y: 0.9999998, z: 1} + - name: DB_HairPonny_L_05 + parentName: DB_HairPonny_L_04 + position: {x: -0.20241515, y: -0.000000076293944, z: -0.00000088384604} + rotation: {x: 0.0000022095112, y: -0.0000017900721, z: 0.0000004180764, w: 1} + scale: {x: 1.0000002, y: 1.0000002, z: 1} + - name: DB_HairPonny_L_06 + parentName: DB_HairPonny_L_05 + position: {x: -0.15935083, y: 0.00000012934207, z: 0.0000006139952} + rotation: {x: -0.0000008710208, y: 0.0000009949636, z: 0.00000045876016, w: 1} + scale: {x: 0.9999998, y: 0.99999976, z: 0.99999994} + - name: DB_HairPonny_L_06_end + parentName: DB_HairPonny_L_06 + position: {x: -0, y: 0.1593509, z: 0} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: CH_Shou_L + parentName: CH_Chest + position: {x: -0.012281971, y: 0.23065643, z: -0.023482827} + rotation: {x: 0.014697773, y: -0.009911863, z: 0.0014211069, w: 0.99984187} + scale: {x: 0.99999994, y: 0.99999994, z: 0.9999999} + - name: CH_Uppe_L + parentName: CH_Shou_L + position: {x: -0.109260835, y: -0.0060280543, z: -0.0054961955} + rotation: {x: -0.07411655, y: -0.0069532236, z: -0.024625355, w: 0.99692124} + scale: {x: 1, y: 1, z: 0.99999994} + - name: CH_For_L + parentName: CH_Uppe_L + position: {x: -0.24869129, y: -0.008231178, z: 0.0065248893} + rotation: {x: 0.07697588, y: 0.01682714, z: 0.027497811, w: 0.99651164} + scale: {x: 1, y: 1, z: 1.0000001} + - name: CH_Hand_L + parentName: CH_For_L + position: {x: -0.21798696, y: 0.0024355208, z: -0.001611712} + rotation: {x: -0.06779544, y: -0.01867086, z: 0.0018385081, w: 0.9975229} + scale: {x: 0.9999999, y: 0.9999999, z: 1} + - name: CH_FingerTh0_L + parentName: CH_Hand_L + position: {x: -0.0064078174, y: -0.012739353, z: 0.020646686} + rotation: {x: 0.7523961, y: 0.27812934, z: -0.282658, w: 0.525974} + scale: {x: 1.0000001, y: 1.0000001, z: 1.0000001} + - name: CH_FingerTh1_L + parentName: CH_FingerTh0_L + position: {x: -0.040618904, y: 0.00044472812, z: -0.00085017324} + rotation: {x: -0.03575346, y: -0.035349116, z: 0.05900386, w: 0.99699086} + scale: {x: 1, y: 0.99999994, z: 0.9999999} + - name: CH_FingerTh2_L + parentName: CH_FingerTh1_L + position: {x: -0.022189535, y: 0.0012206697, z: 0.00036219208} + rotation: {x: -0.012374924, y: 0.024664043, z: 0.68249154, w: 0.7303724} + scale: {x: 0.9999999, y: 0.99999994, z: 0.99999994} + - name: CH_FingerTh2_L_end + parentName: CH_FingerTh2_L + position: {x: -0, y: 0.022226112, z: 0} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: CH_FingerIn0_L + parentName: CH_Hand_L + position: {x: -0.06406116, y: 0.007037236, z: 0.03002478} + rotation: {x: 0.07969865, y: 0.063763246, z: 0.0037595606, w: 0.99477047} + scale: {x: 0.9999998, y: 1, z: 0.99999994} + - name: CH_FingerIn1_L + parentName: CH_FingerIn0_L + position: {x: -0.038648907, y: 0.0006460066, z: -0.0008567846} + rotation: {x: -0.01450446, y: -0.0106268395, z: 0.014400414, w: 0.99973464} + scale: {x: 1, y: 1, z: 1} + - name: CH_FingerIn2_L + parentName: CH_FingerIn1_L + position: {x: -0.019822689, y: 0.0007674566, z: -0.00000007867813} + rotation: {x: -0.000010812651, y: 0.000008268279, z: 0.68969834, w: 0.72409683} + scale: {x: 1, y: 0.99999994, z: 1.0000002} + - name: CH_FingerIn2_L_end + parentName: CH_FingerIn2_L + position: {x: -0, y: 0.019837333, z: 0} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: CH_FingerP0_L + parentName: CH_Hand_L + position: {x: -0.052998576, y: 0.00446907, z: -0.027333174} + rotation: {x: -0.09557177, y: 0.0049860994, z: -0.018023178, w: 0.99524695} + scale: {x: 0.9999999, y: 1, z: 0.9999999} + - name: CH_FingerP1_L + parentName: CH_FingerP0_L + position: {x: -0.03074476, y: 0.0013185358, z: 0.0003040218} + rotation: {x: -0.014836681, y: 0.0056708795, z: 0.0041301586, w: 0.99986535} + scale: {x: 0.9999999, y: 0.9999999, z: 0.99999994} + - name: CH_FingerP2_L + parentName: CH_FingerP1_L + position: {x: -0.016266566, y: 0.0007143402, z: -0.00000027656554} + rotation: {x: -0.00210764, y: 0.0021708312, z: 0.68771875, w: 0.7259709} + scale: {x: 1, y: 0.9999998, z: 0.99999994} + - name: CH_FingerP2_L_end + parentName: CH_FingerP2_L + position: {x: -0, y: 0.016282415, z: 0} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: CH_FingerR0_L + parentName: CH_Hand_L + position: {x: -0.06365903, y: 0.010941673, z: -0.011445877} + rotation: {x: -0.041732516, y: 0.011810722, z: 0.0091352295, w: 0.9990173} + scale: {x: 1, y: 1, z: 0.99999976} + - name: CH_FingerR1_L + parentName: CH_FingerR0_L + position: {x: -0.0377971, y: 0.0028271007, z: -0.0000045108795} + rotation: {x: -0.026200145, y: 0.0016578037, z: -0.01384464, w: 0.99955946} + scale: {x: 0.9999998, y: 0.99999976, z: 0.99999994} + - name: CH_FingerR2_L + parentName: CH_FingerR1_L + position: {x: -0.019330274, y: 0.0006054902, z: -0.0000016498566} + rotation: {x: -0.0035992144, y: 0.0036179835, z: 0.6928014, w: 0.72111034} + scale: {x: 0.99999994, y: 1.0000002, z: 1.0000001} + - name: CH_FingerR2_L_end + parentName: CH_FingerR2_L + position: {x: -0, y: 0.01933992, z: 0} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: CH_FingerMid0_L + parentName: CH_Hand_L + position: {x: -0.06557485, y: 0.01104105, z: 0.008100617} + rotation: {x: 0.05079656, y: 0.020697264, z: -0.0005694582, w: 0.9984944} + scale: {x: 1, y: 1.0000002, z: 0.99999994} + - name: CH_FingerMid1_L + parentName: CH_FingerMid0_L + position: {x: -0.041175857, y: 0.001160005, z: -0.00007615566} + rotation: {x: 0.019365929, y: -0.0014335193, z: 0.016425578, w: 0.9996765} + scale: {x: 0.9999999, y: 0.9999999, z: 1} + - name: CH_FingerMid2_L + parentName: CH_FingerMid1_L + position: {x: -0.0216646, y: 0.0010436233, z: -0.00004650235} + rotation: {x: -0.0013041307, y: -0.00015591593, z: 0.68631154, w: 0.7273065} + scale: {x: 0.99999994, y: 1, z: 0.9999998} + - name: CH_FingerMid2_L_end + parentName: CH_FingerMid2_L + position: {x: -0, y: 0.021689612, z: 0} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: DB_Sode_Twist_L + parentName: CH_For_L + position: {x: -0.07072553, y: 0.0012443771, z: 0.004065677} + rotation: {x: -0.7070428, y: 0.0025758967, z: -0.0027394951, w: 0.7071608} + scale: {x: 0.99999994, y: 1, z: 1} + - name: DB_Sode_B_01_L + parentName: DB_Sode_Twist_L + position: {x: 0.07515088, y: -0.00000006259258, z: 0.00000079365947} + rotation: {x: 0.5000002, y: 0.49999982, z: -0.49999985, w: 0.5000002} + scale: {x: 1, y: 1, z: 1.0000001} + - name: DB_Sode_B_02_L + parentName: DB_Sode_B_01_L + position: {x: 0.00000013556924, y: -0.000000053831403, z: -0.041921053} + rotation: {x: 0.50000006, y: 0.5000001, z: -0.49999997, w: -0.49999988} + scale: {x: 1, y: 0.99999994, z: 1} + - 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} + scale: {x: 1, y: 1, z: 1} + - name: DB_Sode_B_04_L + parentName: DB_Sode_B_03_L + position: {x: 0.000000008950094, y: 0.20569701, z: 0.00000005475743} + rotation: {x: -0.0000014510006, y: 0.00000047640458, z: -0.00000047733556, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: DB_Sode_B_05_L + parentName: DB_Sode_B_04_L + position: {x: -0.000000017032507, y: 0.20018175, z: 0.000000035189622} + rotation: {x: 0.0000029280782, y: -0.0000006263043, z: 0.0000006202216, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: DB_Sode_B_06_L + parentName: DB_Sode_B_05_L + position: {x: 0.00000003035513, y: 0.13229717, z: -0.000000066826814} + rotation: {x: -0.0000031776726, y: 0.00000029980117, z: -0.00000028831255, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: DB_Sode_B_06_L_end + parentName: DB_Sode_B_06_L + position: {x: -0, y: 0.13229713, z: 0} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: DB_Sode_A_01_L + parentName: DB_Sode_Twist_L + position: {x: -0.07054015, y: 0.000000031305326, z: -0.0000005795574} + rotation: {x: 0.5000002, y: -0.49999982, z: 0.49999985, w: 0.5000002} + scale: {x: 1, y: 1, z: 1.0000001} + - name: DB_Sode_A_02_L + parentName: DB_Sode_A_01_L + position: {x: -0.00000018392808, y: 0.00000004780384, z: -0.062379215} + rotation: {x: 0.5000001, y: -0.5000001, z: 0.50000757, w: -0.49999225} + scale: {x: 1, y: 0.99999994, z: 1} + - name: DB_Sode_A_03_L + parentName: DB_Sode_A_02_L + position: {x: 0.000000028639041, y: 0.14331773, z: 0.00000008029514} + rotation: {x: 0.00000010064001, y: -0.000007730376, z: 0.00000016145212, w: 1} + scale: {x: 1, y: 0.99999994, z: 1} + - name: DB_Sode_A_04_L + parentName: DB_Sode_A_03_L + position: {x: 0.000000007277849, y: 0.20569688, z: -0.00000012074027} + rotation: {x: 0.0000011185168, y: 0.00000024678076, z: -0.00000007896757, w: 1} + scale: {x: 1, y: 0.9999999, z: 0.99999994} + - 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} + 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} + scale: {x: 1, y: 1, z: 1} + - name: DB_Sode_A_06_L_end + parentName: DB_Sode_A_06_L + position: {x: -0, y: 0.104189925, z: 0} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: DB_Sode_C_01_L + parentName: CH_Uppe_L + position: {x: -0.15429343, y: 0.037458476, z: 0.0076287184} + rotation: {x: -0.60594916, y: -0.16883437, z: 0.19716953, w: 0.7519607} + scale: {x: 1.0000001, y: 1.0000004, z: 1.0000002} + - name: DB_Sode_C_02_L + parentName: DB_Sode_C_01_L + position: {x: -0.07601813, y: 0.0045141396, z: 0.049572352} + rotation: {x: -0.020481449, y: 0.26066628, z: -0.019464942, w: 0.9650154} + scale: {x: 0.9999998, y: 0.9999998, z: 1} + - name: DB_Sode_C_02_L_end + parentName: DB_Sode_C_02_L + position: {x: -0, y: 0.09086549, z: 0} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: CH_Shou_R + parentName: CH_Chest + position: {x: 0.012124489, y: 0.23065645, z: -0.0234831} + rotation: {x: 0.00043337568, y: 0.99987835, z: 0.014768094, w: -0.0050086207} + scale: {x: 1, y: 1.0000002, z: 1} + - name: CH_Uppe_R + parentName: CH_Shou_R + position: {x: -0.109188795, y: -0.0062610856, z: 0.0065627876} + rotation: {x: 0.06908981, y: 0.011750795, z: -0.024362924, w: 0.9972437} + scale: {x: 0.9999999, y: 0.99999994, z: 1.0000004} + - name: CH_For_R + parentName: CH_Uppe_R + position: {x: -0.24868745, y: -0.008401483, z: -0.0064525628} + rotation: {x: -0.07200974, y: -0.016691286, z: 0.02790731, w: 0.99687374} + scale: {x: 1, y: 1.0000004, z: 0.9999999} + - name: CH_Hand_R + parentName: CH_For_R + position: {x: -0.21798757, y: 0.0024348153, z: 0.0016114794} + rotation: {x: 0.06779566, y: 0.018671023, z: 0.0018410026, w: 0.99752283} + scale: {x: 1, y: 1, z: 1} + - name: CH_FingerTh0_R + parentName: CH_Hand_R + position: {x: -0.006407766, y: -0.012739203, z: -0.020646522} + rotation: {x: -0.28265387, y: -0.5259759, z: 0.75239724, w: -0.2781271} + scale: {x: 1.0000004, y: 1.0000006, z: 1.0000006} + - name: CH_FingerTh1_R + parentName: CH_FingerTh0_R + position: {x: 0.04061907, y: 0.00044467687, z: -0.00085032044} + rotation: {x: -0.035751946, y: 0.035347506, z: -0.059002396, w: 0.99699104} + scale: {x: 1.0000001, y: 0.9999999, z: 0.9999998} + - name: CH_FingerTh2_R + parentName: CH_FingerTh1_R + position: {x: 0.022189597, y: 0.0012205862, z: 0.00036210386} + rotation: {x: 0.68249387, y: 0.73037034, z: -0.012374707, w: 0.024662556} + scale: {x: 1, y: 1.0000001, z: 1.0000001} + - name: CH_FingerTh2_R_end + parentName: CH_FingerTh2_R + position: {x: -0, y: 0.02222597, z: 0} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: CH_FingerIn0_R + parentName: CH_Hand_R + position: {x: -0.06406104, y: 0.0070373523, z: -0.030024698} + rotation: {x: -0.0037601765, y: 0.99477065, z: -0.07969837, w: 0.06376127} + scale: {x: 1, y: 1.0000001, z: 1} + - name: CH_FingerIn1_R + parentName: CH_FingerIn0_R + position: {x: 0.03864901, y: 0.00064615294, z: -0.00085680245} + rotation: {x: 0.0144177945, y: 0.9997345, z: -0.014499862, w: -0.010622344} + scale: {x: 1.0000001, y: 0.9999999, z: 1.0000002} + - name: CH_FingerIn2_R + parentName: CH_FingerIn1_R + position: {x: -0.019822806, y: 0.00076747005, z: 0.00000019073485} + rotation: {x: 0.000014294293, y: -0.000007946972, z: 0.68970054, w: 0.7240947} + scale: {x: 1, y: 0.99999994, z: 1} + - name: CH_FingerIn2_R_end + parentName: CH_FingerIn2_R + position: {x: -0, y: 0.019837638, z: 0} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: CH_FingerR0_R + parentName: CH_Hand_R + position: {x: -0.06365899, y: 0.010941697, z: 0.011445911} + rotation: {x: -0.0091353385, y: 0.99901736, z: 0.041730713, w: 0.0118083395} + scale: {x: 1, y: 1.0000001, z: 0.99999976} + - name: CH_FingerR1_R + parentName: CH_FingerR0_R + position: {x: 0.037796896, y: 0.0028271053, z: -0.0000045490265} + rotation: {x: -0.0138390055, y: 0.9995598, z: -0.026189053, w: 0.0016663147} + scale: {x: 1, y: 1, z: 1} + - name: CH_FingerR2_R + parentName: CH_FingerR1_R + position: {x: -0.019330401, y: 0.000605638, z: 0.0000017547607} + rotation: {x: 0.003605214, y: -0.0036217193, z: 0.69279695, w: 0.72111464} + scale: {x: 0.9999999, y: 0.99999994, z: 1} + - name: CH_FingerR2_R_end + parentName: CH_FingerR2_R + position: {x: -0, y: 0.019339915, z: 0} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: CH_FingerP0_R + parentName: CH_Hand_R + position: {x: -0.052998446, y: 0.0044688727, z: 0.027333299} + rotation: {x: 0.01802347, y: 0.9952471, z: 0.09557006, w: 0.004981065} + scale: {x: 0.99999976, y: 1, z: 0.99999976} + - name: CH_FingerP1_R + parentName: CH_FingerP0_R + position: {x: 0.030745046, y: 0.0013184547, z: 0.00030395508} + rotation: {x: 0.00413538, y: 0.9998654, z: -0.014828406, w: 0.0056751473} + scale: {x: 1.0000002, y: 1, z: 1} + - name: CH_FingerP2_R + parentName: CH_FingerP1_R + position: {x: -0.016266353, y: 0.00071466924, z: 0.00000032424927} + rotation: {x: 0.0021126827, y: -0.002169545, z: 0.6877082, w: 0.72598094} + scale: {x: 1, y: 1.0000001, z: 1.0000002} + - name: CH_FingerP2_R_end + parentName: CH_FingerP2_R + position: {x: -0, y: 0.016281962, z: 0} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: CH_FingerMid0_R + parentName: CH_Hand_R + position: {x: -0.06557463, y: 0.011041118, z: -0.00809997} + rotation: {x: 0.0005642458, y: 0.99849457, z: -0.050796404, w: 0.020691592} + scale: {x: 1, y: 1.0000004, z: 1} + - name: CH_FingerMid1_R + parentName: CH_FingerMid0_R + position: {x: 0.04117568, y: 0.0011602625, z: -0.000076138975} + rotation: {x: 0.01642544, y: 0.9996765, z: 0.019367091, w: -0.0014327726} + scale: {x: 1.0000001, y: 1.0000001, z: 1.0000001} + - name: CH_FingerMid2_R + parentName: CH_FingerMid1_R + position: {x: -0.021664495, y: 0.0010435178, z: 0.00004654884} + rotation: {x: 0.0013057459, y: 0.00015577854, z: 0.6863129, w: 0.7273053} + scale: {x: 0.99999994, y: 1, z: 0.9999999} + - name: CH_FingerMid2_R_end + parentName: CH_FingerMid2_R + position: {x: -0, y: 0.021689605, z: 0} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: DB_Sode_Twist_R + parentName: CH_For_R + position: {x: -0.0707259, y: 0.001245186, z: -0.0040661404} + rotation: {x: 0.70704305, y: -0.0025753796, z: -0.0027401797, w: 0.70716053} + scale: {x: 1.0000001, y: 1.0000001, z: 0.99999994} + - name: DB_Sode_A_01_R + parentName: DB_Sode_Twist_R + position: {x: -0.07054018, y: 0.000000019160511, z: 0.0000011134423} + rotation: {x: -0.5039202, y: 0.49604595, z: 0.50392306, w: 0.49604887} + scale: {x: 0.99999994, y: 0.9999998, z: 1} + - name: DB_Sode_A_02_R + parentName: DB_Sode_A_01_R + position: {x: -0.000000102927224, y: 0.00000007994764, z: 0.06237919} + rotation: {x: 0.49999756, y: -0.4999977, z: -0.50000125, w: 0.5000035} + scale: {x: 1, y: 0.9999998, z: 0.9999999} + - name: DB_Sode_A_03_R + parentName: DB_Sode_A_02_R + position: {x: -0.000000027283749, y: 0.14331758, z: 0.0000000045852357} + rotation: {x: 0.0000039525153, y: -0.0000007035201, z: 0.00000030958725, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: DB_Sode_A_04_R + parentName: DB_Sode_A_03_R + position: {x: -0.00000005695081, y: 0.2056968, z: -0.00000008667848} + rotation: {x: -0.000001151127, y: -0.00000047408884, z: -0.00000022679427, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: DB_Sode_A_05_R + parentName: DB_Sode_A_04_R + position: {x: 0.000000023280444, y: 0.1882643, z: -0.000000077367545} + rotation: {x: -0.0000020712544, y: 0.00000036774742, z: 0.00000012400066, w: 1} + scale: {x: 1, y: 1, z: 1.0000001} + - name: DB_Sode_A_06_R + parentName: DB_Sode_A_05_R + position: {x: 3.8970027e-10, y: 0.104189634, z: 0.00000014024864} + rotation: {x: 0.0000010654262, y: -0.00000023841983, z: 6.6368244e-10, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: DB_Sode_A_06_R_end + parentName: DB_Sode_A_06_R + position: {x: -0, y: 0.10418984, z: 0} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: DB_Sode_B_01_R + parentName: DB_Sode_Twist_R + position: {x: 0.07515107, y: 0.00000007838026, z: -0.00000013202978} + rotation: {x: -0.49812663, y: -0.5018625, z: -0.49813053, w: 0.50186646} + scale: {x: 1.0000001, y: 1, z: 1.0000001} + - name: DB_Sode_B_02_R + parentName: DB_Sode_B_01_R + position: {x: -0.000000047871534, y: -0.000000029715883, z: 0.041921005} + rotation: {x: 0.49999803, y: 0.49999794, z: 0.5000028, w: 0.50000125} + scale: {x: 1, y: 0.99999994, z: 0.99999994} + - name: DB_Sode_B_03_R + parentName: DB_Sode_B_02_R + position: {x: 0.000000030147493, y: 0.16377567, z: 0.0000010480799} + rotation: {x: 0.00000057740147, y: -0.00000048672365, z: 0.00000019854585, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: DB_Sode_B_04_R + parentName: DB_Sode_B_03_R + position: {x: -0.000000009375799, y: 0.2056968, z: -0.000000070580974} + rotation: {x: 0.0000030118667, y: -0.00000080360417, z: -0.00000054368763, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: DB_Sode_B_05_R + parentName: DB_Sode_B_04_R + position: {x: -0.00000005803653, y: 0.20018135, z: 0.0000012537765} + rotation: {x: -0.0000030193087, y: 0.0000010308081, z: 0.0000005335727, w: 1} + scale: {x: 1, y: 0.99999994, z: 1} + - name: DB_Sode_B_06_R + parentName: DB_Sode_B_05_R + position: {x: -0.000000017018756, y: 0.1322969, z: -0.000000110429426} + rotation: {x: 0.0000028815002, y: -0.0000003269356, z: 0.00000014373873, w: 1} + scale: {x: 1, y: 0.99999994, z: 0.99999994} + - name: DB_Sode_B_06_R_end + parentName: DB_Sode_B_06_R + position: {x: -0, y: 0.132297, z: 0} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: DB_Sode_C_01_R + parentName: CH_Uppe_R + position: {x: -0.1544906, y: 0.037378874, z: -0.007165909} + rotation: {x: 0.60965884, y: 0.1683714, z: 0.19816935, w: 0.74879646} + scale: {x: 1, y: 1, z: 1.0000001} + - name: DB_Sode_C_02_R + parentName: DB_Sode_C_01_R + position: {x: -0.07601836, y: 0.004513822, z: -0.049571924} + rotation: {x: 0.02048045, y: -0.26065883, z: -0.019462926, w: 0.9650175} + scale: {x: 0.99999994, y: 1, z: 0.99999976} + - name: DB_Sode_C_02_R_end + parentName: DB_Sode_C_02_R + position: {x: -0, y: 0.09086549, z: 0} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: DB_Yui_01 + parentName: CH_Chest + position: {x: -0.00007873828, y: -0.0055533135, z: 0.09300276} + rotation: {x: 0.012621869, y: -0.012622002, z: 0.7069941, w: 0.7069941} + scale: {x: 1.0000001, y: 0.9999993, z: 1.0000001} + - name: DB_Yui_01_end + parentName: DB_Yui_01 + position: {x: -0, y: 0.15502922, z: 0} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: DB_Se_A_01_L + parentName: CH_Chest + position: {x: -0.035720672, y: -0.027678194, z: -0.10499585} + rotation: {x: 0.37955755, y: 0.6959062, z: -0.5971699, w: 0.12263277} + scale: {x: 1, y: 0.9999998, z: 1} + - name: DB_Se_A_02_L + parentName: DB_Se_A_01_L + position: {x: 0.0061411737, y: 0.012879329, z: 0.075529404} + rotation: {x: -0.24811666, y: 0.72953796, z: 0.14364325, w: 0.62095016} + scale: {x: 1.0000001, y: 0.9999998, z: 1.0000001} + - name: DB_Se_A_02_L_end + parentName: DB_Se_A_02_L + position: {x: -0, y: 0.076865315, z: 0} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: DB_Ribbon_01_L + parentName: CH_Chest + position: {x: -0.02973076, y: 0.038719244, z: -0.11095828} + rotation: {x: 0.47502026, y: 0.5103168, z: 0.5036692, w: 0.5101469} + scale: {x: 1, y: 0.99999994, z: 0.99999994} + - name: DB_Ribbon_02_L + parentName: DB_Ribbon_01_L + position: {x: 0.006333625, y: -0.028709888, z: -0.06914581} + rotation: {x: 0.5488721, y: 0.64759505, z: 0.2970563, w: -0.43717} + scale: {x: 1.0000001, y: 1, z: 0.9999998} + - name: DB_Ribbon_02_L_end + parentName: DB_Ribbon_02_L + position: {x: -0, y: 0.07513666, z: 0} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: DB_Wing_01_L + parentName: CH_Chest + position: {x: -0.09459109, y: 0.019864999, z: -0.11785887} + rotation: {x: -0.03509301, y: 0.54361415, z: 0.8148731, w: -0.19807579} + scale: {x: 1.0000001, y: 1.0000001, z: 1} + - name: DB_Wing_02_L + parentName: DB_Wing_01_L + position: {x: 0.08566747, y: -0.009382233, z: -0.10407833} + rotation: {x: 0.33157405, y: 0.64837986, z: 0.62494457, w: -0.28125867} + scale: {x: 0.9999999, y: 1, z: 0.99999976} + - name: DB_Wing_03_L + parentName: DB_Wing_02_L + position: {x: -0.21784946, y: 0.01103724, z: -0.0012900734} + rotation: {x: 0.12758519, y: 0.15889907, z: 0.12734312, w: 0.9706992} + scale: {x: 1.0000001, y: 1.0000002, z: 1.0000004} + - name: DB_Wing_04_L + parentName: DB_Wing_03_L + position: {x: -0.24561739, y: 0.051883504, z: -0.049193997} + rotation: {x: -0.7049644, y: 0.09990609, z: 0.11619699, w: 0.6924899} + scale: {x: 1, y: 0.99999994, z: 1} + - name: DB_Wing_05_L + parentName: DB_Wing_04_L + position: {x: -0.1814758, y: 0.06948755, z: 0.017430376} + rotation: {x: 0.65725267, y: -0.08469431, z: -0.15790564, w: 0.7320599} + scale: {x: 1, y: 0.9999999, z: 0.99999994} + - name: DB_Wing_05_L_end + parentName: DB_Wing_05_L + position: {x: -0, y: 0.19510457, z: 0} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: DB_Se_A_01_R + parentName: CH_Chest + position: {x: 0.035563193, y: -0.027678115, z: -0.10499586} + rotation: {x: -0.5984501, y: 0.12135365, z: 0.37896076, w: 0.6953558} + scale: {x: 1, y: 1, z: 1.0000001} + - name: DB_Se_A_02_R + parentName: DB_Se_A_01_R + position: {x: 0.006114845, y: 0.013139727, z: -0.07548661} + rotation: {x: 0.24994868, y: -0.7295034, z: 0.14315614, w: 0.62036824} + scale: {x: 0.9999999, y: 1.0000001, z: 1.0000001} + - name: DB_Se_A_02_R_end + parentName: DB_Se_A_02_R + position: {x: -0, y: 0.07686509, z: 0} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: DB_Ribbon_01_R + parentName: CH_Chest + position: {x: 0.02957328, y: 0.038719166, z: -0.11095828} + rotation: {x: 0.50431395, y: 0.5088831, z: 0.4749981, w: 0.51096207} + scale: {x: 1, y: 0.9999997, z: 0.9999999} + - name: DB_Ribbon_02_R + parentName: DB_Ribbon_01_R + position: {x: 0.0064747725, y: -0.028799247, z: 0.06909559} + rotation: {x: 0.5491629, y: 0.64797735, z: -0.29766905, w: 0.4358194} + scale: {x: 1, y: 0.9999997, z: 1.0000001} + - name: DB_Ribbon_02_R_end + parentName: DB_Ribbon_02_R + position: {x: -0, y: 0.07513666, z: 0} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: DB_Wing_01_R + parentName: CH_Chest + position: {x: 0.09457092, y: 0.019297248, z: -0.11766987} + rotation: {x: 0.81443703, y: -0.195344, z: -0.036799707, w: 0.54514116} + scale: {x: 1.0000002, y: 1.0000002, z: 1.0000001} + - name: DB_Wing_02_R + parentName: DB_Wing_01_R + position: {x: 0.08528502, y: -0.009584007, z: 0.10372579} + rotation: {x: 0.3303919, y: 0.6504693, z: -0.62272114, w: 0.28275302} + scale: {x: 1, y: 1.0000002, z: 1.0000001} + - name: DB_Wing_03_R + parentName: DB_Wing_02_R + position: {x: -0.21784933, y: 0.011036229, z: 0.0012900209} + rotation: {x: -0.12757559, y: -0.15889944, z: 0.12734507, w: 0.9707001} + scale: {x: 1, y: 0.99999976, z: 0.9999998} + - name: DB_Wing_04_R + parentName: DB_Wing_03_R + position: {x: -0.24561688, y: 0.051883724, z: 0.049193278} + rotation: {x: 0.7049765, y: -0.09990848, z: 0.116198815, w: 0.6924769} + scale: {x: 1.0000001, y: 1.0000002, z: 1.0000002} + - name: DB_Wing_05_R + parentName: DB_Wing_04_R + position: {x: -0.18147565, y: 0.069487825, z: -0.017431352} + rotation: {x: -0.6572682, y: 0.08469687, z: -0.15790655, w: 0.73204535} + scale: {x: 0.99999994, y: 0.9999999, z: 0.99999964} + - name: DB_Wing_05_R_end + parentName: DB_Wing_05_R + position: {x: -0, y: 0.19510466, z: 0} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: DB_Bust_01_L + parentName: CH_Chest + position: {x: -0.045915846, y: 0.13167338, z: 0.008157868} + rotation: {x: 0.6831262, y: 0.1243552, z: 0.71066463, w: -0.11327015} + scale: {x: 0.9999992, y: 1, z: 1.0000001} + - name: DB_Bust_02_L + parentName: DB_Bust_01_L + position: {x: 0.04555152, y: 0.0007748288, z: -0.015781386} + rotation: {x: -0.033195987, y: 0.9703462, z: -0.17722182, w: -0.16099273} + scale: {x: 0.9999998, y: 1.0000002, z: 0.99999994} + - name: DB_Bust_02_L_end + parentName: DB_Bust_02_L + position: {x: -0, y: 0.048214015, z: 0} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: DB_Bust_01_R + parentName: CH_Chest + position: {x: 0.045758367, y: 0.13167323, z: 0.008157874} + rotation: {x: -0.68313026, y: 0.12435394, z: 0.7106616, w: 0.113266855} + scale: {x: 1.0000008, y: 1.0000002, z: 1} + - name: DB_Bust_02_R + parentName: DB_Bust_01_R + position: {x: -0.045551334, y: 0.00077503204, z: -0.015781404} + rotation: {x: 0.033200588, y: 0.9703504, z: -0.17722109, w: 0.16096777} + scale: {x: 0.9999999, y: 0.9999996, z: 0.9999998} + - name: DB_Bust_02_R_end + parentName: DB_Bust_02_R + position: {x: -0, y: 0.048213854, z: 0} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: DB_Skirt_Root + parentName: CH_Spine + position: {x: -0.00007874018, y: 0.10784568, z: 0.008305135} + rotation: {x: 0.5065588, y: 0.4933541, z: -0.5065587, w: -0.49335402} + scale: {x: 0.9999998, y: 0.99999964, z: 0.9999996} + - name: DB_Skirt_A_00_L + parentName: DB_Skirt_Root + position: {x: -0.005919308, y: -0.081187926, z: 0.037028134} + rotation: {x: 0.9886333, y: 0.068873234, z: -0.06886442, w: 0.11453576} + scale: {x: 1.0000018, y: 0.99999994, z: 1.0000037} + - name: DB_Skirt_A_01_L + parentName: DB_Skirt_A_00_L + position: {x: -0.048206225, y: -0.00000002503395, z: 0.00000026106835} + rotation: {x: -0.5190421, y: -0.13519114, z: -0.08883795, w: 0.8393012} + scale: {x: 1.0000001, y: 1.0000001, z: 0.9999998} + - name: DB_Skirt_A_02_L + parentName: DB_Skirt_A_01_L + position: {x: -0.04316255, y: -0.00000019192696, z: 0.00000007867813} + rotation: {x: 0.6788012, y: 0.16176912, z: -0.028153837, w: 0.7157284} + scale: {x: 1.0000001, y: 1.0000001, z: 1} + - name: DB_Skirt_A_03_L + parentName: DB_Skirt_A_02_L + position: {x: -0.07563619, y: 0.00000017166137, z: 0.00000030755996} + rotation: {x: -0.30099624, y: -0.06077376, z: 0.021307869, w: 0.9514483} + scale: {x: 0.9999999, y: 1.0000001, z: 0.9999999} + - name: DB_Skirt_A_04_L + parentName: DB_Skirt_A_03_L + position: {x: -0.06269684, y: -0.000000038146972, z: 0.0000003480911} + rotation: {x: 0.12105323, y: 0.027283242, z: -0.0041861553, w: 0.9922622} + scale: {x: 0.9999999, y: 0.99999976, z: 0.99999964} + - name: DB_Skirt_A_05_L + parentName: DB_Skirt_A_04_L + position: {x: -0.068666436, y: -0.0000000667572, z: 0.00000034332274} + rotation: {x: 0.0000002160668, y: -0.00000008475034, z: 0.000000051222738, w: 1} + scale: {x: 1, y: 1.0000001, z: 1.0000002} + - name: DB_Skirt_A_05_L_end + parentName: DB_Skirt_A_05_L + position: {x: -0, y: 0.06866649, z: 0} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: DB_Skirt_B_01_L + parentName: DB_Skirt_Root + position: {x: -0.026402013, y: -0.0495657, z: 0.09382382} + rotation: {x: 0.84656805, y: 0.12749854, z: -0.12749875, w: 0.5008102} + scale: {x: 1.0000001, y: 1.0000002, z: 0.9999998} + - name: DB_Skirt_B_02_L + parentName: DB_Skirt_B_01_L + position: {x: -0.061201446, y: 0.00000005483627, z: -0.000000014305114} + rotation: {x: -0.11362099, y: -0.010648978, z: 0.04229765, w: 0.9925663} + scale: {x: 0.99999994, y: 0.9999998, z: 0.9999998} + - name: DB_Skirt_B_03_L + parentName: DB_Skirt_B_02_L + position: {x: -0.06120112, y: -0.000000044107438, z: -0.0000000037439167} + rotation: {x: 0.113623716, y: 0.010649163, z: -0.0422995, w: 0.9925659} + scale: {x: 1, y: 1.0000001, z: 1.0000001} + - name: DB_Skirt_B_04_L + parentName: DB_Skirt_B_03_L + position: {x: -0.061201286, y: -0.00000004053116, z: 0.000000009536743} + rotation: {x: 0.00000006798655, y: -0.000000013969839, z: 0.0000005578622, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: DB_Skirt_B_04_L_end + parentName: DB_Skirt_B_04_L + position: {x: -0, y: 0.06120149, z: 0} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: DB_Skirt_C_01_L + parentName: DB_Skirt_Root + position: {x: -0.015127751, y: 0.0036500238, z: 0.11416566} + rotation: {x: 0.62223047, y: 0.16748916, z: -0.16748913, w: 0.7461394} + scale: {x: 1.0000001, y: 1.0000001, z: 0.99999976} + - name: DB_Skirt_C_02_L + parentName: DB_Skirt_C_01_L + position: {x: -0.061201252, y: 0.000000060945744, z: -0.00000000834465} + rotation: {x: -0.025608357, y: -0.010111154, z: 0.042430107, w: 0.99872005} + scale: {x: 1, y: 1, z: 1.0000001} + - name: DB_Skirt_C_03_L + parentName: DB_Skirt_C_02_L + position: {x: -0.061201274, y: -0.00000005841255, z: -0.0000000023841857} + rotation: {x: 0.025599128, y: 0.010109475, z: -0.042431254, w: 0.9987202} + scale: {x: 0.99999976, y: 0.9999998, z: 0.99999976} + - name: DB_Skirt_C_04_L + parentName: DB_Skirt_C_03_L + position: {x: -0.06120142, y: 0.00000006407499, z: -0.000000013113022} + rotation: {x: -0.000000059604645, y: 2.3283064e-10, z: 0.00000012564124, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: DB_Skirt_C_04_L_end + parentName: DB_Skirt_C_04_L + position: {x: -0, y: 0.061201546, z: 0} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: DB_Skirt_E_01_L + parentName: DB_Skirt_Root + position: {x: -0.017052164, y: 0.09371286, z: 0.027265651} + rotation: {x: -0.4943337, y: 0.17446516, z: -0.17446527, w: 0.8335215} + scale: {x: 1, y: 1.0000002, z: 1} + - name: DB_Skirt_E_02_L + parentName: DB_Skirt_E_01_L + position: {x: -0.061201446, y: -0.000000028610229, z: -0.000000022649765} + rotation: {x: 0.009058533, y: -0.04163055, z: 0.01301367, w: 0.9990072} + scale: {x: 0.9999999, y: 0.9999996, z: 0.99999994} + - name: DB_Skirt_E_03_L + parentName: DB_Skirt_E_02_L + position: {x: -0.06120128, y: -0.00000007867813, z: 0.000000077486035} + rotation: {x: 0.002835001, y: -0.011104343, z: 0.003562789, w: 0.999928} + scale: {x: 1, y: 0.99999994, z: 0.99999994} + - 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} + scale: {x: 0.99999994, y: 1.0000002, z: 1.0000001} + - name: DB_Skirt_E_04_L_end + parentName: DB_Skirt_E_04_L + position: {x: -0, y: 0.061201345, z: 0} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: DB_Skirt_D_01_L + parentName: DB_Skirt_Root + position: {x: -0.014013145, y: 0.06532121, z: 0.07861873} + rotation: {x: -0.028069327, y: 0.1858796, z: -0.18587953, w: 0.9644219} + scale: {x: 1.0000001, y: 0.99999976, z: 1.0000001} + - name: DB_Skirt_D_02_L + parentName: DB_Skirt_D_01_L + position: {x: -0.061201207, y: -0.000000005960464, z: -0.000000032717363} + rotation: {x: -0.0033062762, y: -0.03233883, z: 0.029271381, w: 0.9990428} + scale: {x: 0.99999994, y: 1.0000001, z: 0.9999999} + - name: DB_Skirt_D_03_L + parentName: DB_Skirt_D_02_L + position: {x: -0.06120122, y: 0.000000028610229, z: -0.000000027120112} + rotation: {x: 0.0033009183, y: 0.032339223, z: -0.029273093, w: 0.99904275} + scale: {x: 0.99999976, y: 0.99999964, z: 0.9999997} + - 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} + scale: {x: 1, y: 1, z: 1} + - name: DB_Skirt_D_04_L_end + parentName: DB_Skirt_D_04_L + position: {x: -0, y: 0.06120126, z: 0} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: DB_Skirt_F_01_C + parentName: DB_Skirt_Root + position: {x: -0.02845147, y: -0.07837399, z: 0.00000000941017} + rotation: {x: -0.7064357, y: -0.030843785, z: 0.030844036, w: 0.70643187} + scale: {x: 0.99999994, y: 1.0000002, z: 0.9999998} + - name: DB_Skirt_F_02_C + parentName: DB_Skirt_F_01_C + position: {x: -0.06276076, y: 0.000000028611911, z: 0.000000009116139} + rotation: {x: 0.000001963571, y: -0.043618415, z: -0.00000031387654, w: 0.9990483} + scale: {x: 0.9999998, y: 1, z: 0.9999999} + - name: DB_Skirt_F_03_C + parentName: DB_Skirt_F_02_C + position: {x: -0.06276092, y: 0.000000009541815, z: -0.00000001918153} + rotation: {x: 0.000001945809, y: -0.04362011, z: -0.0000005032294, w: 0.99904823} + scale: {x: 0.99999994, y: 1, z: 0.99999994} + - name: DB_Skirt_F_04_C + parentName: DB_Skirt_F_03_C + position: {x: -0.06276066, y: -0.000000019085018, z: -0.00000003795007} + rotation: {x: -6.883383e-14, y: 0.000000014901158, z: 1.021405e-14, w: 1} + scale: {x: 0.99999994, y: 1, z: 0.99999994} + - name: DB_Skirt_F_04_C_end + parentName: DB_Skirt_F_04_C + position: {x: -0, y: 0.06276062, z: 0} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: DB_Skirt_D_01_R + parentName: DB_Skirt_Root + position: {x: -0.014013141, y: 0.0653212, z: -0.07861875} + rotation: {x: 0.9644182, y: -0.18589155, z: 0.18588704, w: -0.028071372} + scale: {x: 1.0000021, y: 1.0000002, z: 1.0000004} + - name: DB_Skirt_D_02_R + parentName: DB_Skirt_D_01_R + position: {x: -0.06120126, y: 0.00000004887581, z: 0.00000004546251} + rotation: {x: 0.0033094892, y: -0.032338366, z: -0.029269652, w: 0.99904287} + scale: {x: 1, y: 1.0000002, z: 1.0000002} + - name: DB_Skirt_D_03_R + parentName: DB_Skirt_D_02_R + position: {x: -0.06120096, y: -0.0000000011920929, z: 0.00000007659197} + rotation: {x: -0.0032966628, y: 0.032337006, z: 0.029272333, w: 0.99904287} + scale: {x: 0.9999998, y: 0.99999994, z: 0.9999999} + - 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} + scale: {x: 1, y: 0.9999998, z: 0.9999999} + - name: DB_Skirt_D_04_R_end + parentName: DB_Skirt_D_04_R + position: {x: -0, y: 0.06120142, z: 0} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: DB_Skirt_E_01_R + parentName: DB_Skirt_Root + position: {x: -0.017052162, y: 0.093712874, z: -0.027265625} + rotation: {x: 0.8335211, y: -0.17446595, z: 0.17446627, w: -0.49433368} + scale: {x: 0.99999994, y: 1.0000002, z: 1} + - name: DB_Skirt_E_02_R + parentName: DB_Skirt_E_01_R + position: {x: -0.06120119, y: -0.000000076293944, z: 0.000000102519984} + rotation: {x: -0.009059916, y: -0.041632082, z: -0.013013172, w: 0.99900717} + scale: {x: 1.0000001, y: 1.0000001, z: 1.0000001} + - name: DB_Skirt_E_03_R + parentName: DB_Skirt_E_02_R + position: {x: -0.061201505, y: 0.00000021934508, z: -0.000000102519984} + rotation: {x: -0.0030704609, y: -0.0110883545, z: -0.0036108461, w: 0.9999273} + scale: {x: 0.99999976, y: 1, z: 1} + - 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} + scale: {x: 1.0000001, y: 1.0000001, z: 1.0000001} + - name: DB_Skirt_E_04_R_end + parentName: DB_Skirt_E_04_R + position: {x: -0, y: 0.06120141, z: 0} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: DB_Skirt_C_01_R + parentName: DB_Skirt_Root + position: {x: -0.015127669, y: 0.0036500357, z: -0.11416563} + rotation: {x: 0.7461397, y: -0.16748993, z: 0.16748971, w: 0.62222975} + scale: {x: 1, y: 1.0000001, z: 0.99999976} + - name: DB_Skirt_C_02_R + parentName: DB_Skirt_C_01_R + position: {x: -0.061201356, y: 0.00000007599592, z: 0.000000027418135} + rotation: {x: 0.025609408, y: -0.010111335, z: -0.042431355, w: 0.99872} + scale: {x: 1, y: 1.0000001, z: 1} + - name: DB_Skirt_C_03_R + parentName: DB_Skirt_C_02_R + position: {x: -0.061201304, y: -0.00000003516674, z: 0.0000000047683715} + rotation: {x: -0.025590483, y: 0.010107933, z: 0.04243304, w: 0.9987204} + scale: {x: 0.9999999, y: 1.0000001, z: 1.0000002} + - 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} + scale: {x: 1, y: 1, z: 1.0000001} + - name: DB_Skirt_C_04_R_end + parentName: DB_Skirt_C_04_R + position: {x: -0, y: 0.061201405, z: 0} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: DB_Skirt_B_01_R + parentName: DB_Skirt_Root + position: {x: -0.02640216, y: -0.049565695, z: -0.09382382} + rotation: {x: 0.5008093, y: -0.12749927, z: 0.12749895, w: 0.84656835} + scale: {x: 1, y: 1.0000002, z: 1} + - name: DB_Skirt_B_02_R + parentName: DB_Skirt_B_01_R + position: {x: -0.06120146, y: 0.0000000166893, z: 0.000000023841856} + rotation: {x: 0.11361794, y: -0.010647971, z: -0.042299516, w: 0.9925666} + scale: {x: 0.9999998, y: 1, z: 0.99999994} + - name: DB_Skirt_B_03_R + parentName: DB_Skirt_B_02_R + position: {x: -0.06120115, y: -0.000000059604645, z: 0.000000011743977} + rotation: {x: -0.113616526, y: 0.010647851, z: 0.042300668, w: 0.9925667} + scale: {x: 0.9999999, y: 0.99999994, z: 1} + - 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} + scale: {x: 1, y: 1.0000001, z: 1.0000001} + - name: DB_Skirt_B_04_R_end + parentName: DB_Skirt_B_04_R + position: {x: -0, y: 0.061201423, z: 0} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: DB_Skirt_A_00_R + parentName: DB_Skirt_Root + position: {x: -0.005919383, y: -0.08118793, z: -0.037028152} + rotation: {x: 0.114535645, y: -0.068863116, z: 0.06886332, w: 0.9886341} + scale: {x: 0.99999994, y: 0.9999999, z: 1.0000002} + - name: DB_Skirt_A_01_R + parentName: DB_Skirt_A_00_R + position: {x: -0.048206396, y: 0.000000022053719, z: -0.0000000011920929} + rotation: {x: 0.51904047, y: -0.13519132, z: 0.08883778, w: 0.8393022} + scale: {x: 1.0000001, y: 0.9999999, z: 0.9999996} + - name: DB_Skirt_A_02_R + parentName: DB_Skirt_A_01_R + position: {x: -0.043162618, y: -0.00000007033348, z: 0.000000020861625} + rotation: {x: -0.6787974, y: 0.16176796, z: 0.028152978, w: 0.7157322} + scale: {x: 1.0000001, y: 1.0000004, z: 1} + - name: DB_Skirt_A_03_R + parentName: DB_Skirt_A_02_R + position: {x: -0.075636156, y: -0.000000034570693, z: -0.000000005960464} + rotation: {x: 0.3009944, y: -0.060773686, z: -0.021306733, w: 0.9514489} + scale: {x: 1, y: 1.0000004, z: 1.0000004} + - name: DB_Skirt_A_04_R + parentName: DB_Skirt_A_03_R + position: {x: -0.06269685, y: 0.000000052452087, z: 0} + rotation: {x: -0.12105262, y: 0.02728288, z: 0.0041858335, w: 0.9922623} + scale: {x: 0.99999994, y: 0.99999964, z: 0.99999946} + - 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} + scale: {x: 1.0000001, y: 1, z: 1.0000001} + - name: DB_Skirt_A_05_R_end + parentName: DB_Skirt_A_05_R + position: {x: -0, y: 0.06866663, z: 0} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: BodyTop.005 + parentName: UnityCHanKAGURA_B(Clone) + position: {x: 0.028763741, y: 0.0000000141331675, z: 0.02928832} + rotation: {x: 0.000000011641534, y: 4.6566306e-10, z: -0.0000000018626443, w: 1} + scale: {x: 1, y: 0.9999999, z: 0.9999999} + - name: BodyTop.004 + parentName: UnityCHanKAGURA_B(Clone) + position: {x: 0.028763741, y: 0.0000000141331675, z: 0.02928832} + rotation: {x: 0.000000011641534, y: 4.6566306e-10, z: -0.0000000018626443, w: 1} + scale: {x: 1, y: 0.9999999, z: 0.9999999} + - name: BodyTop.003 + parentName: UnityCHanKAGURA_B(Clone) + position: {x: 0.028763741, y: 0.0000000141331675, z: 0.02928832} + rotation: {x: 0.000000011641534, y: 4.6566306e-10, z: -0.0000000018626443, w: 1} + scale: {x: 1, y: 0.9999999, z: 0.9999999} + - name: BodyTop.002 + parentName: UnityCHanKAGURA_B(Clone) + position: {x: 0.028763741, y: 0.0000000141331675, z: 0.02928832} + rotation: {x: 0.000000011641534, y: 4.6566306e-10, z: -0.0000000018626443, w: 1} + scale: {x: 1, y: 0.9999999, z: 0.9999999} + - name: BodyTop.001 + parentName: UnityCHanKAGURA_B(Clone) + position: {x: 0.028763741, y: 0.0000000141331675, z: 0.02928832} + rotation: {x: 0.000000011641534, y: 4.6566306e-10, z: -0.0000000018626443, w: 1} + scale: {x: 1, y: 0.9999999, z: 0.9999999} + - name: head_Def + parentName: UnityCHanKAGURA_B(Clone) + position: {x: -0.0000000047683715, y: 0.00000003665686, z: -0.00000000476837} + rotation: {x: 0.000000011641534, y: 4.6566306e-10, z: -0.0000000018626443, w: 1} + scale: {x: 1, y: 0.9999999, z: 0.9999999} + - name: Headgear + parentName: UnityCHanKAGURA_B(Clone) + position: {x: -0.0000000047683715, y: 0.00000003665686, z: -0.00000000476837} + rotation: {x: 0.000000011641534, y: 4.6566306e-10, z: -0.0000000018626443, w: 1} + scale: {x: 1, y: 0.9999999, z: 0.9999999} + - name: Hontai + parentName: UnityCHanKAGURA_B(Clone) + position: {x: 0.028763741, y: 0.0000000141331675, z: 0.02928832} + rotation: {x: 0.000000011641534, y: 4.6566306e-10, z: -0.0000000018626443, w: 1} + scale: {x: 1, y: 0.9999999, z: 0.9999999} + - name: HairB01 + parentName: UnityCHanKAGURA_B(Clone) + position: {x: 0.028763741, y: 0.0000000141331675, z: 0.02928832} + rotation: {x: 0.000000011641534, y: 4.6566306e-10, z: -0.0000000018626443, w: 1} + scale: {x: 1, y: 0.9999999, z: 0.9999999} + - name: Gohei + parentName: UnityCHanKAGURA_B(Clone) + position: {x: 0.028763741, y: 0.0000000141331675, z: 0.02928832} + rotation: {x: 0.000000011641534, y: 4.6566306e-10, z: -0.0000000018626443, w: 1} + scale: {x: 1, y: 0.9999999, z: 0.9999999} + - name: BodyTop + parentName: UnityCHanKAGURA_B(Clone) + position: {x: 0.028763741, y: 0.0000000141331675, z: 0.02928832} + rotation: {x: 0.000000011641534, y: 4.6566306e-10, z: -0.0000000018626443, w: 1} + scale: {x: 1, y: 0.9999999, z: 0.9999999} + - name: BodyBottom + parentName: UnityCHanKAGURA_B(Clone) + position: {x: 0.028763741, y: 0.0000000141331675, z: 0.02928832} + rotation: {x: 0.000000011641534, y: 4.6566306e-10, z: -0.0000000018626443, w: 1} + scale: {x: 1, y: 0.9999999, z: 0.9999999} + - name: RibbonF + parentName: UnityCHanKAGURA_B(Clone) + position: {x: 0.028763741, y: 0.0000000141331675, z: 0.02928832} + rotation: {x: 0.000000011641534, y: 4.6566306e-10, z: -0.0000000018626443, w: 1} + scale: {x: 1, y: 0.9999999, z: 0.9999999} + - name: Skirt + parentName: UnityCHanKAGURA_B(Clone) + position: {x: 0.028763741, y: 0.0000000141331675, z: 0.02928832} + rotation: {x: 0.000000011641534, y: 4.6566306e-10, z: -0.0000000018626443, w: 1} + scale: {x: 1, y: 0.9999999, z: 0.9999999} + - name: EyeNose + parentName: UnityCHanKAGURA_B(Clone) + position: {x: 0.028763741, y: 0.0000000141331675, z: 0.02928832} + rotation: {x: 0.000000011641534, y: 4.6566306e-10, z: -0.0000000018626443, w: 1} + scale: {x: 1, y: 0.9999999, z: 0.9999999} + - name: HairS01 + parentName: UnityCHanKAGURA_B(Clone) + position: {x: 0.028763741, y: 0.0000000141331675, z: 0.02928832} + rotation: {x: 0.000000011641534, y: 4.6566306e-10, z: -0.0000000018626443, w: 1} + scale: {x: 1, y: 0.9999999, z: 0.9999999} + - name: HairP02 + parentName: UnityCHanKAGURA_B(Clone) + position: {x: 0.028763741, y: 0.0000000141331675, z: 0.02928832} + rotation: {x: 0.000000011641534, y: 4.6566306e-10, z: -0.0000000018626443, w: 1} + scale: {x: 1, y: 0.9999999, z: 0.9999999} + - name: Back + parentName: UnityCHanKAGURA_B(Clone) + position: {x: 0.028763741, y: 0.0000000141331675, z: 0.02928832} + rotation: {x: 0.000000011641534, y: 4.6566306e-10, z: -0.0000000018626443, w: 1} + scale: {x: 1, y: 0.9999999, z: 0.9999999} + - name: Lamp + parentName: UnityCHanKAGURA_B(Clone) + position: {x: -4.0762453, y: 5.903862, z: -1.005454} + rotation: {x: 0.52327543, y: -0.34203398, z: 0.72694236, w: 0.28416628} + scale: {x: 100.00001, y: 100, z: 100} + - name: Camera + parentName: UnityCHanKAGURA_B(Clone) + position: {x: -7.4811316, y: 5.343665, z: 6.5076394} + rotation: {x: 0.0906284, y: 0.8937962, z: -0.20997299, w: 0.38577998} + scale: {x: 100, y: 100.00001, z: 99.99999} + armTwist: 0.5 + foreArmTwist: 0.5 + upperLegTwist: 0.5 + legTwist: 0.5 + armStretch: 0.05 + legStretch: 0.05 + feetSpacing: 0 + globalScale: 1 + rootMotionBoneName: + hasTranslationDoF: 0 + hasExtraRoot: 1 + skeletonHasParents: 1 + lastHumanDescriptionAvatarSource: {instanceID: 0} + autoGenerateAvatarMappingIfUnspecified: 1 + animationType: 3 + humanoidOversampling: 1 + avatarSetup: 1 + addHumanoidExtraRootOnlyWhenUsingAvatar: 1 + importBlendShapeDeformPercent: 1 + remapMaterialsIfMaterialImportModeIsNone: 0 + additionalBone: 0 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/UnityCHanKAGURA.fbx + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/UnityCHanKAGURA_MC2.prefab b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/UnityCHanKAGURA_MC2.prefab new file mode 100644 index 00000000..59845608 --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/UnityCHanKAGURA_MC2.prefab @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:14cdc785604144bb02b06bc56d2439eafe6035c3aa279ca90edc94824ab1c3c1 +size 1050073 diff --git a/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/UnityCHanKAGURA_MC2.prefab.meta b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/UnityCHanKAGURA_MC2.prefab.meta new file mode 100644 index 00000000..bf816ebb --- /dev/null +++ b/Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/UnityCHanKAGURA_MC2.prefab.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: c221ca113bd2c6847887aae336c65708 +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/UnityCHanKAGURA_MC2.prefab + uploadId: 893596 diff --git a/Assets/MagicaCloth2/MagicaCloth2.asmdef b/Assets/MagicaCloth2/MagicaCloth2.asmdef new file mode 100644 index 00000000..b08ade0b --- /dev/null +++ b/Assets/MagicaCloth2/MagicaCloth2.asmdef @@ -0,0 +1,37 @@ +{ + "name": "MagicaClothV2", + "rootNamespace": "", + "references": [ + "Unity.Burst", + "Unity.Collections", + "Unity.Mathematics" + ], + "includePlatforms": [], + "excludePlatforms": [], + "allowUnsafeCode": true, + "overrideReferences": false, + "precompiledReferences": [], + "autoReferenced": true, + "defineConstraints": [ + "MC2_BURST", + "MC2_COLLECTIONS" + ], + "versionDefines": [ + { + "name": "com.unity.burst", + "expression": "1.8.1", + "define": "MC2_BURST" + }, + { + "name": "com.unity.collections", + "expression": "1.4.0", + "define": "MC2_COLLECTIONS" + }, + { + "name": "com.unity.collections", + "expression": "2.0.0", + "define": "MC2_COLLECTIONS_200" + } + ], + "noEngineReferences": false +} \ No newline at end of file diff --git a/Assets/MagicaCloth2/MagicaCloth2.asmdef.meta b/Assets/MagicaCloth2/MagicaCloth2.asmdef.meta new file mode 100644 index 00000000..8616d025 --- /dev/null +++ b/Assets/MagicaCloth2/MagicaCloth2.asmdef.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: 406190ab8ee569c46bc05a890e5127a0 +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/MagicaCloth2.asmdef + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Readme.txt b/Assets/MagicaCloth2/Readme.txt new file mode 100644 index 00000000..8c387a30 --- /dev/null +++ b/Assets/MagicaCloth2/Readme.txt @@ -0,0 +1,60 @@ +/------------------------------------------------------------------------------ +// Magica Cloth 2 +// Copyright (c) Magica Soft, 2023 +// https://magicasoft.jp +//------------------------------------------------------------------------------ + +### Overview +MagicaCloth2 is a general-purpose cloth simulation that can be used in Unity. + + +### Support Unity versions +Unity2021.3.20 or higher + + +### Required Unity package +Burst 1.8.2 or higher +Collections 1.4.0 or higher +Mathematics 1.2.6 or higher + + +### Feature +* Fast cloth simulation with DOTS +* Works on all platforms except WebGL +* Supports both BoneCloth driven by bones (Transform) and MeshCloth driven by mesh vertices +* MeshCloth is also available for skinning meshes +* Not affected by render pipeline or shader +* With full source code + + +### Install +The necessary packages are automatically installed when importing Magica Cloth. +If you get an error, manually install the Burst/Collections/Mathematics package. +See [Required Unity package] for each package version. + + +### Documentation +Since it is an online manual, please refer to the following URL for details. +https://magicasoft.jp/en/magica-cloth-2-2/ + + +### Support +Support email. +support@magicasoft.jp + +Unity Forum. +https://forum.unity.com/threads/coming-soon-magicacloth2-hybrid-cloth-simulation.1395865/ + +It would be helpful if you could include the versions of the Unity editor and MagicaCloth2 you are using to facilitate support. +You can check the version of MagicaCloth from the menu [Tools->Magica Cloth2->About]. + + +### License +MagicaCloth2 uses Unity-chan as a key image and sample. +© Unity Technologies Japan/UCL +https://unity-chan.com/ + + +### Release Notes +https://magicasoft.jp/en/mc2_releasenote/ + diff --git a/Assets/MagicaCloth2/Readme.txt.meta b/Assets/MagicaCloth2/Readme.txt.meta new file mode 100644 index 00000000..96791033 --- /dev/null +++ b/Assets/MagicaCloth2/Readme.txt.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: c7df889e086412e46a2da4fb58d8fd0b +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Readme.txt + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Readme_jpn.txt b/Assets/MagicaCloth2/Readme_jpn.txt new file mode 100644 index 00000000..8ea4dc00 --- /dev/null +++ b/Assets/MagicaCloth2/Readme_jpn.txt @@ -0,0 +1,60 @@ +/------------------------------------------------------------------------------ +// Magica Cloth 2 +// Copyright (c) Magica Soft, 2023 +// https://magicasoft.jp +//------------------------------------------------------------------------------ + +■概要 +MagicaCloth2はUnityで利用できる汎用的なクロスシミュレーションです。 + + +■要求Unityバージョン +Unity2021.3.20以上 + + +■要求パッケージ +Burst 1.8.2以上 +Collections 1.4.0以上 +Mathematics 1.2.6以上 + + +■機能 +* DOTSによる高速なクロスシミュレーション +* WebGLを除くすべてのプラットフォームで動作可能 +* ボーン(Transform)で駆動するBoneClothとメッシュ頂点で駆動するMeshClothの両方に対応 +* MeshClothはスキニングメッシュでも利用可能 +* レンダーパイプラインやシェーダーに影響されません +* フルソースコード付き + + +■インストール +Magica Clothインポート時に必要なパッケージは自動でインストールされます。 +もしエラーが発生する場合はBurst / Collections / Mathematicsパッケージを手動でインストールしてください。 +各パッケージバージョンは[要求パッケージ]を参照してください。 + + +■マニュアル +オンラインマニュアルとなっていますので、詳しくは次のURLを参照してください。 +https://magicasoft.jp/magica-cloth-2/ + + +■サポート窓口 +サポートメール +support@magicasoft.jp + +Unityフォーラム +https://forum.unity.com/threads/coming-soon-magicacloth2-hybrid-cloth-simulation.1395865/ + +サポートを円滑に進めるために使用しているUnityエディターとMagicaCloth2のバージョンを記載していただくと助かります。 +MagicaClothのバージョンはメニュー[Tools->Magica Cloth2->About]から確認可能です。 + + +■ライセンス +MagicaCloth2はキー画像およびサンプルとしてUnityちゃんを使用しています +© Unity Technologies Japan/UCL +https://unity-chan.com/ + + +■更新履歴 +https://magicasoft.jp/mc2_releasenote/ + diff --git a/Assets/MagicaCloth2/Readme_jpn.txt.meta b/Assets/MagicaCloth2/Readme_jpn.txt.meta new file mode 100644 index 00000000..bde28ce7 --- /dev/null +++ b/Assets/MagicaCloth2/Readme_jpn.txt.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: 73816f2cd0da25345afb170423318b5d +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Readme_jpn.txt + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Res.meta b/Assets/MagicaCloth2/Res.meta new file mode 100644 index 00000000..21c2a352 --- /dev/null +++ b/Assets/MagicaCloth2/Res.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: d6123dfb6786202488da533186450913 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/MagicaCloth2/Res/Icon.meta b/Assets/MagicaCloth2/Res/Icon.meta new file mode 100644 index 00000000..79c83063 --- /dev/null +++ b/Assets/MagicaCloth2/Res/Icon.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: b423dff8e87989b4a97592892c3a6df4 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/MagicaCloth2/Res/Icon/icon-cloth.png b/Assets/MagicaCloth2/Res/Icon/icon-cloth.png new file mode 100644 index 00000000..fa721a09 --- /dev/null +++ b/Assets/MagicaCloth2/Res/Icon/icon-cloth.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0f8369c86b1695a0a80f25375715200b922a2c20ec6f3292be71ce23d6923421 +size 931 diff --git a/Assets/MagicaCloth2/Res/Icon/icon-cloth.png.meta b/Assets/MagicaCloth2/Res/Icon/icon-cloth.png.meta new file mode 100644 index 00000000..01e673ed --- /dev/null +++ b/Assets/MagicaCloth2/Res/Icon/icon-cloth.png.meta @@ -0,0 +1,131 @@ +fileFormatVersion: 2 +guid: cf7e3400035e987478c3a19e57b4cf75 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 12 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMasterTextureLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: 4 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Server + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + spritePackingTag: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Res/Icon/icon-cloth.png + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Res/Icon/icon-collider.png b/Assets/MagicaCloth2/Res/Icon/icon-collider.png new file mode 100644 index 00000000..c3f77357 --- /dev/null +++ b/Assets/MagicaCloth2/Res/Icon/icon-collider.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9c87f0c91057a13f60265155b0b340f5535c6fc210f5a8dc80883e4ca2c819ef +size 4475 diff --git a/Assets/MagicaCloth2/Res/Icon/icon-collider.png.meta b/Assets/MagicaCloth2/Res/Icon/icon-collider.png.meta new file mode 100644 index 00000000..24f07b42 --- /dev/null +++ b/Assets/MagicaCloth2/Res/Icon/icon-collider.png.meta @@ -0,0 +1,143 @@ +fileFormatVersion: 2 +guid: db1f683d4db92254e93d234d88f6cd1d +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 12 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMasterTextureLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 1 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: 4 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Server + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Android + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + spritePackingTag: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Res/Icon/icon-collider.png + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Res/Icon/icon-settings.png b/Assets/MagicaCloth2/Res/Icon/icon-settings.png new file mode 100644 index 00000000..8dfa9610 --- /dev/null +++ b/Assets/MagicaCloth2/Res/Icon/icon-settings.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fe828b360d4c32e569f13e8919d4b6a0a1a4de8d12d2b47bb99f5d361023f02e +size 3507 diff --git a/Assets/MagicaCloth2/Res/Icon/icon-settings.png.meta b/Assets/MagicaCloth2/Res/Icon/icon-settings.png.meta new file mode 100644 index 00000000..c95e9377 --- /dev/null +++ b/Assets/MagicaCloth2/Res/Icon/icon-settings.png.meta @@ -0,0 +1,142 @@ +fileFormatVersion: 2 +guid: 4b0d1adb21ff82e4e8e9ea02f486a85f +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 12 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMasterTextureLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + cookieLightType: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: 4 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Server + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Android + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Res/Icon/icon-settings.png + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Res/Icon/icon-wind.png b/Assets/MagicaCloth2/Res/Icon/icon-wind.png new file mode 100644 index 00000000..64781b82 --- /dev/null +++ b/Assets/MagicaCloth2/Res/Icon/icon-wind.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:573222aa068255bd58533a19e667a3a1f941a32589fd5961ff11658aba507892 +size 10349 diff --git a/Assets/MagicaCloth2/Res/Icon/icon-wind.png.meta b/Assets/MagicaCloth2/Res/Icon/icon-wind.png.meta new file mode 100644 index 00000000..3af6840f --- /dev/null +++ b/Assets/MagicaCloth2/Res/Icon/icon-wind.png.meta @@ -0,0 +1,142 @@ +fileFormatVersion: 2 +guid: 28008cd7b4b7bb24482a4260fbe8c25e +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 12 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMasterTextureLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + cookieLightType: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: 4 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Server + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Android + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Res/Icon/icon-wind.png + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Res/Preset.meta b/Assets/MagicaCloth2/Res/Preset.meta new file mode 100644 index 00000000..183744cb --- /dev/null +++ b/Assets/MagicaCloth2/Res/Preset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 1855ce0df2330234dbaf3ab95ef26ba6 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/MagicaCloth2/Res/Preset/MC2_Preset_Accessory.json b/Assets/MagicaCloth2/Res/Preset/MC2_Preset_Accessory.json new file mode 100644 index 00000000..4435d0d0 --- /dev/null +++ b/Assets/MagicaCloth2/Res/Preset/MC2_Preset_Accessory.json @@ -0,0 +1 @@ +{"clothType":0,"sourceRenderers":[],"meshWriteMode":0,"paintMode":0,"paintMaps":[],"rootBones":[],"connectionMode":0,"rotationalInterpolation":0.5,"rootRotation":0.5,"updateMode":10,"animationPoseRatio":0.0,"reductionSetting":{"simpleDistance":0.0,"shapeDistance":0.0},"customSkinningSetting":{"enable":false,"skinningBones":[]},"normalAlignmentSetting":{"alignmentMode":0,"adjustmentTransform":{"instanceID":0}},"cullingSettings":{"cameraCullingMode":30,"cameraCullingMethod":0,"cameraCullingRenderers":[],"distanceCullingLength":{"value":30.0,"use":false},"distanceCullingFadeRatio":0.20000000298023225,"distanceCullingReferenceObject":{"instanceID":0}},"normalAxis":1,"gravity":0.0,"gravityDirection":{"x":0.0,"y":-1.0,"z":0.0},"gravityFalloff":0.0,"stablizationTimeAfterReset":0.10000000149011612,"blendWeight":1.0,"damping":{"value":0.10000000149011612,"useCurve":false,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}},"radius":{"value":0.019999999552965165,"useCurve":false,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}},"inertiaConstraint":{"anchor":{"instanceID":0},"anchorInertia":0.0,"worldInertia":1.0,"movementInertiaSmoothing":0.4000000059604645,"movementSpeedLimit":{"value":5.0,"use":true},"rotationSpeedLimit":{"value":720.0,"use":true},"localInertia":1.0,"localMovementSpeedLimit":{"value":5.0,"use":false},"localRotationSpeedLimit":{"value":720.0,"use":false},"depthInertia":0.0,"centrifualAcceleration":0.0,"particleSpeedLimit":{"value":4.0,"use":true},"teleportMode":0,"teleportDistance":0.5,"teleportRotation":90.0},"tetherConstraint":{"distanceCompression":0.10000000149011612},"distanceConstraint":{"stiffness":{"value":1.0,"useCurve":false,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":1.0,"inSlope":0.0,"outSlope":-0.5,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":0.5,"inSlope":-0.5,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}}},"triangleBendingConstraint":{"stiffness":1.0},"angleRestorationConstraint":{"useAngleRestoration":true,"stiffness":{"value":0.15000000596046449,"useCurve":false,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":1.0,"inSlope":0.0,"outSlope":-0.699999988079071,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":0.30000001192092898,"inSlope":-0.699999988079071,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}},"velocityAttenuation":0.6000000238418579,"gravityFalloff":0.0},"angleLimitConstraint":{"useAngleLimit":true,"limitAngle":{"value":45.0,"useCurve":false,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":0.0,"inSlope":0.0,"outSlope":1.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":1.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}},"stiffness":1.0},"motionConstraint":{"useMaxDistance":false,"maxDistance":{"value":0.30000001192092898,"useCurve":false,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}},"useBackstop":false,"backstopRadius":10.0,"backstopDistance":{"value":0.0,"useCurve":false,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}},"stiffness":1.0},"colliderCollisionConstraint":{"mode":1,"friction":0.05000000074505806,"colliderList":[],"collisionBones":[],"limitDistance":{"value":0.05000000074505806,"useCurve":false,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}}},"selfCollisionConstraint":{"selfMode":0,"surfaceThickness":{"value":0.004999999888241291,"useCurve":false,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":0.5,"inSlope":0.0,"outSlope":0.5,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":0.5,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}},"syncMode":0,"syncPartner":{"instanceID":0},"clothMass":0.0},"wind":{"influence":1.0,"frequency":1.0,"turbulence":1.0,"blend":0.699999988079071,"synchronization":0.699999988079071,"depthWeight":0.0,"movingWind":0.0},"springConstraint":{"useSpring":true,"springPower":0.03999999910593033,"limitDistance":0.10000000149011612,"normalLimitRatio":1.0,"springNoise":0.0}} \ No newline at end of file diff --git a/Assets/MagicaCloth2/Res/Preset/MC2_Preset_Accessory.json.meta b/Assets/MagicaCloth2/Res/Preset/MC2_Preset_Accessory.json.meta new file mode 100644 index 00000000..3a5893ce --- /dev/null +++ b/Assets/MagicaCloth2/Res/Preset/MC2_Preset_Accessory.json.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: 42bb4454dd53bc541be9d7166cbbf61e +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Res/Preset/MC2_Preset_Accessory.json + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Res/Preset/MC2_Preset_Cape.json b/Assets/MagicaCloth2/Res/Preset/MC2_Preset_Cape.json new file mode 100644 index 00000000..197a287c --- /dev/null +++ b/Assets/MagicaCloth2/Res/Preset/MC2_Preset_Cape.json @@ -0,0 +1 @@ +{"clothType":0,"sourceRenderers":[],"meshWriteMode":0,"paintMode":0,"paintMaps":[],"rootBones":[],"connectionMode":0,"rotationalInterpolation":0.5,"rootRotation":0.5,"updateMode":10,"animationPoseRatio":0.0,"reductionSetting":{"simpleDistance":0.0,"shapeDistance":0.0},"customSkinningSetting":{"enable":false,"skinningBones":[]},"normalAlignmentSetting":{"alignmentMode":0,"adjustmentTransform":{"instanceID":0}},"cullingSettings":{"cameraCullingMode":30,"cameraCullingMethod":0,"cameraCullingRenderers":[],"distanceCullingLength":{"value":30.0,"use":false},"distanceCullingFadeRatio":0.20000000298023225,"distanceCullingReferenceObject":{"instanceID":0}},"normalAxis":1,"gravity":7.0,"gravityDirection":{"x":0.0,"y":-1.0,"z":0.0},"gravityFalloff":0.0,"stablizationTimeAfterReset":0.10000000149011612,"blendWeight":1.0,"damping":{"value":0.10000000149011612,"useCurve":false,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}},"radius":{"value":0.019999999552965165,"useCurve":false,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}},"inertiaConstraint":{"anchor":{"instanceID":0},"anchorInertia":0.0,"worldInertia":1.0,"movementInertiaSmoothing":0.4000000059604645,"movementSpeedLimit":{"value":5.0,"use":true},"rotationSpeedLimit":{"value":720.0,"use":true},"localInertia":1.0,"localMovementSpeedLimit":{"value":5.0,"use":false},"localRotationSpeedLimit":{"value":720.0,"use":false},"depthInertia":0.699999988079071,"centrifualAcceleration":0.0,"particleSpeedLimit":{"value":4.0,"use":true},"teleportMode":0,"teleportDistance":0.5,"teleportRotation":90.0},"tetherConstraint":{"distanceCompression":0.5},"distanceConstraint":{"stiffness":{"value":1.0,"useCurve":false,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":1.0,"inSlope":0.0,"outSlope":-0.5,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":0.5,"inSlope":-0.5,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}}},"triangleBendingConstraint":{"stiffness":1.0},"angleRestorationConstraint":{"useAngleRestoration":true,"stiffness":{"value":0.15000000596046449,"useCurve":true,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":0.09678345918655396,"inSlope":-0.699999988079071,"outSlope":-0.699999988079071,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}},"velocityAttenuation":0.800000011920929,"gravityFalloff":0.0},"angleLimitConstraint":{"useAngleLimit":true,"limitAngle":{"value":45.0,"useCurve":true,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":0.0,"inSlope":2.0,"outSlope":2.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}},"stiffness":1.0},"motionConstraint":{"useMaxDistance":false,"maxDistance":{"value":0.30000001192092898,"useCurve":false,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}},"useBackstop":false,"backstopRadius":10.0,"backstopDistance":{"value":0.0,"useCurve":false,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}},"stiffness":1.0},"colliderCollisionConstraint":{"mode":1,"friction":0.10000000149011612,"colliderList":[],"collisionBones":[],"limitDistance":{"value":0.05000000074505806,"useCurve":false,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}}},"selfCollisionConstraint":{"selfMode":0,"surfaceThickness":{"value":0.004999999888241291,"useCurve":false,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":0.5,"inSlope":0.0,"outSlope":0.5,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":0.5,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}},"syncMode":0,"syncPartner":{"instanceID":0},"clothMass":0.0},"wind":{"influence":1.0,"frequency":1.0,"turbulence":1.0,"blend":0.699999988079071,"synchronization":0.699999988079071,"depthWeight":0.0,"movingWind":0.0},"springConstraint":{"useSpring":true,"springPower":0.03999999910593033,"limitDistance":0.10000000149011612,"normalLimitRatio":1.0,"springNoise":0.0}} \ No newline at end of file diff --git a/Assets/MagicaCloth2/Res/Preset/MC2_Preset_Cape.json.meta b/Assets/MagicaCloth2/Res/Preset/MC2_Preset_Cape.json.meta new file mode 100644 index 00000000..c42c0475 --- /dev/null +++ b/Assets/MagicaCloth2/Res/Preset/MC2_Preset_Cape.json.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: 72735c72edd9bb340b389ee4f7ccc363 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Res/Preset/MC2_Preset_Cape.json + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Res/Preset/MC2_Preset_FrontHair.json b/Assets/MagicaCloth2/Res/Preset/MC2_Preset_FrontHair.json new file mode 100644 index 00000000..755a3676 --- /dev/null +++ b/Assets/MagicaCloth2/Res/Preset/MC2_Preset_FrontHair.json @@ -0,0 +1 @@ +{"clothType":0,"sourceRenderers":[],"meshWriteMode":0,"paintMode":0,"paintMaps":[],"rootBones":[],"connectionMode":0,"rotationalInterpolation":0.5,"rootRotation":0.5,"updateMode":10,"animationPoseRatio":0.0,"reductionSetting":{"simpleDistance":0.0,"shapeDistance":0.0},"customSkinningSetting":{"enable":false,"skinningBones":[]},"normalAlignmentSetting":{"alignmentMode":0,"adjustmentTransform":{"instanceID":0}},"cullingSettings":{"cameraCullingMode":30,"cameraCullingMethod":0,"cameraCullingRenderers":[],"distanceCullingLength":{"value":30.0,"use":false},"distanceCullingFadeRatio":0.20000000298023225,"distanceCullingReferenceObject":{"instanceID":0}},"normalAxis":1,"gravity":4.0,"gravityDirection":{"x":0.0,"y":-1.0,"z":0.0},"gravityFalloff":0.800000011920929,"stablizationTimeAfterReset":0.10000000149011612,"blendWeight":1.0,"damping":{"value":0.10000000149011612,"useCurve":false,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}},"radius":{"value":0.019999999552965165,"useCurve":false,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}},"inertiaConstraint":{"anchor":{"instanceID":0},"anchorInertia":0.0,"worldInertia":1.0,"movementInertiaSmoothing":0.4000000059604645,"movementSpeedLimit":{"value":3.0,"use":true},"rotationSpeedLimit":{"value":360.0,"use":true},"localInertia":1.0,"localMovementSpeedLimit":{"value":5.0,"use":false},"localRotationSpeedLimit":{"value":720.0,"use":false},"depthInertia":0.0,"centrifualAcceleration":0.0,"particleSpeedLimit":{"value":2.0,"use":true},"teleportMode":0,"teleportDistance":0.5,"teleportRotation":90.0},"tetherConstraint":{"distanceCompression":0.10000000149011612},"distanceConstraint":{"stiffness":{"value":1.0,"useCurve":false,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":1.0,"inSlope":0.0,"outSlope":-0.5,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":0.5,"inSlope":-0.5,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}}},"triangleBendingConstraint":{"stiffness":1.0},"angleRestorationConstraint":{"useAngleRestoration":true,"stiffness":{"value":0.15000000596046449,"useCurve":true,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":1.0,"inSlope":0.0,"outSlope":-0.699999988079071,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":0.30000001192092898,"inSlope":-0.699999988079071,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}},"velocityAttenuation":0.699999988079071,"gravityFalloff":0.5},"angleLimitConstraint":{"useAngleLimit":true,"limitAngle":{"value":15.0,"useCurve":true,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":0.0,"inSlope":0.0,"outSlope":1.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":1.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}},"stiffness":0.5},"motionConstraint":{"useMaxDistance":false,"maxDistance":{"value":0.30000001192092898,"useCurve":false,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}},"useBackstop":false,"backstopRadius":10.0,"backstopDistance":{"value":0.0,"useCurve":false,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}},"stiffness":1.0},"colliderCollisionConstraint":{"mode":1,"friction":0.05000000074505806,"colliderList":[],"collisionBones":[],"limitDistance":{"value":0.05000000074505806,"useCurve":false,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}}},"selfCollisionConstraint":{"selfMode":0,"surfaceThickness":{"value":0.004999999888241291,"useCurve":false,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":0.5,"inSlope":0.0,"outSlope":0.5,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":0.5,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}},"syncMode":0,"syncPartner":{"instanceID":0},"clothMass":0.0},"wind":{"influence":1.0,"frequency":1.0,"turbulence":1.0,"blend":0.699999988079071,"synchronization":0.699999988079071,"depthWeight":0.0,"movingWind":0.0},"springConstraint":{"useSpring":true,"springPower":0.03999999910593033,"limitDistance":0.10000000149011612,"normalLimitRatio":1.0,"springNoise":0.0}} \ No newline at end of file diff --git a/Assets/MagicaCloth2/Res/Preset/MC2_Preset_FrontHair.json.meta b/Assets/MagicaCloth2/Res/Preset/MC2_Preset_FrontHair.json.meta new file mode 100644 index 00000000..392bcbdb --- /dev/null +++ b/Assets/MagicaCloth2/Res/Preset/MC2_Preset_FrontHair.json.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: 59cdb0fe679574d4fbd4caba5eef451b +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Res/Preset/MC2_Preset_FrontHair.json + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Res/Preset/MC2_Preset_HardSpring.json b/Assets/MagicaCloth2/Res/Preset/MC2_Preset_HardSpring.json new file mode 100644 index 00000000..dd41edb0 --- /dev/null +++ b/Assets/MagicaCloth2/Res/Preset/MC2_Preset_HardSpring.json @@ -0,0 +1 @@ +{"clothType":0,"sourceRenderers":[],"paintMode":0,"paintMaps":[],"rootBones":[],"connectionMode":0,"rotationalInterpolation":0.5,"rootRotation":0.5,"updateMode":10,"animationPoseRatio":0.0,"reductionSetting":{"simpleDistance":0.0,"shapeDistance":0.0},"customSkinningSetting":{"enable":false,"skinningBones":[]},"normalAlignmentSetting":{"alignmentMode":0,"adjustmentTransform":{"instanceID":0}},"cullingSettings":{"cameraCullingMode":30,"cameraCullingMethod":0,"cameraCullingRenderers":[]},"normalAxis":1,"gravity":0.0,"gravityDirection":{"x":0.0,"y":-1.0,"z":0.0},"gravityFalloff":0.0,"stablizationTimeAfterReset":0.10000000149011612,"damping":{"value":0.30000001192092898,"useCurve":false,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}},"radius":{"value":0.019999999552965165,"useCurve":false,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}},"inertiaConstraint":{"anchor":{"instanceID":0},"anchorInertia":0.0,"worldInertia":1.0,"movementInertiaSmoothing":0.4000000059604645,"movementSpeedLimit":{"value":1.0,"use":true},"rotationSpeedLimit":{"value":360.0,"use":true},"localInertia":1.0,"localMovementSpeedLimit":{"value":1.0,"use":true},"localRotationSpeedLimit":{"value":360.0,"use":true},"depthInertia":0.0,"centrifualAcceleration":0.0,"particleSpeedLimit":{"value":4.0,"use":true},"teleportMode":0,"teleportDistance":0.5,"teleportRotation":90.0},"tetherConstraint":{"distanceCompression":0.0989999994635582},"distanceConstraint":{"stiffness":{"value":0.24199999868869782,"useCurve":false,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":1.0,"inSlope":0.0,"outSlope":-0.5,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":0.5,"inSlope":-0.5,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}}},"triangleBendingConstraint":{"stiffness":0.2409999966621399},"angleRestorationConstraint":{"useAngleRestoration":true,"stiffness":{"value":0.6000000238418579,"useCurve":true,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":0.5023223757743836,"inSlope":-0.800000011920929,"outSlope":-0.800000011920929,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}},"velocityAttenuation":0.4000000059604645,"gravityFalloff":0.0},"angleLimitConstraint":{"useAngleLimit":false,"limitAngle":{"value":15.0,"useCurve":false,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":0.0,"inSlope":0.0,"outSlope":1.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":1.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}},"stiffness":0.5},"motionConstraint":{"useMaxDistance":false,"maxDistance":{"value":0.30000001192092898,"useCurve":false,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}},"useBackstop":false,"backstopRadius":10.0,"backstopDistance":{"value":0.0,"useCurve":false,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}},"stiffness":1.0},"colliderCollisionConstraint":{"mode":1,"friction":0.20000000298023225,"colliderList":[],"collisionBones":[],"limitDistance":{"value":0.05000000074505806,"useCurve":false,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}}},"selfCollisionConstraint":{"selfMode":0,"surfaceThickness":{"value":0.004999999888241291,"useCurve":false,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":0.5,"inSlope":0.0,"outSlope":0.5,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":0.5,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}},"syncMode":0,"syncPartner":{"instanceID":0},"clothMass":0.0},"wind":{"influence":0.20000000298023225,"frequency":1.0,"turbulence":1.0,"blend":0.699999988079071,"synchronization":0.699999988079071,"depthWeight":0.0,"movingWind":0.0},"springConstraint":{"useSpring":true,"springPower":0.05999999865889549,"limitDistance":0.05000000074505806,"normalLimitRatio":1.0,"springNoise":0.0}} \ No newline at end of file diff --git a/Assets/MagicaCloth2/Res/Preset/MC2_Preset_HardSpring.json.meta b/Assets/MagicaCloth2/Res/Preset/MC2_Preset_HardSpring.json.meta new file mode 100644 index 00000000..784db491 --- /dev/null +++ b/Assets/MagicaCloth2/Res/Preset/MC2_Preset_HardSpring.json.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: 7c6ab357392efc7428b1f002db37b9f2 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Res/Preset/MC2_Preset_HardSpring.json + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Res/Preset/MC2_Preset_LongHair.json b/Assets/MagicaCloth2/Res/Preset/MC2_Preset_LongHair.json new file mode 100644 index 00000000..116e3da8 --- /dev/null +++ b/Assets/MagicaCloth2/Res/Preset/MC2_Preset_LongHair.json @@ -0,0 +1 @@ +{"clothType":0,"sourceRenderers":[],"meshWriteMode":0,"paintMode":0,"paintMaps":[],"rootBones":[],"connectionMode":0,"rotationalInterpolation":0.5,"rootRotation":0.5,"updateMode":10,"animationPoseRatio":0.0,"reductionSetting":{"simpleDistance":0.0,"shapeDistance":0.0},"customSkinningSetting":{"enable":false,"skinningBones":[]},"normalAlignmentSetting":{"alignmentMode":0,"adjustmentTransform":{"instanceID":0}},"cullingSettings":{"cameraCullingMode":30,"cameraCullingMethod":0,"cameraCullingRenderers":[],"distanceCullingLength":{"value":30.0,"use":false},"distanceCullingFadeRatio":0.20000000298023225,"distanceCullingReferenceObject":{"instanceID":0}},"normalAxis":1,"gravity":5.0,"gravityDirection":{"x":0.0,"y":-1.0,"z":0.0},"gravityFalloff":0.0,"stablizationTimeAfterReset":0.10000000149011612,"blendWeight":1.0,"damping":{"value":0.10000000149011612,"useCurve":false,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}},"radius":{"value":0.019999999552965165,"useCurve":false,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}},"inertiaConstraint":{"anchor":{"instanceID":0},"anchorInertia":0.0,"worldInertia":1.0,"movementInertiaSmoothing":0.4000000059604645,"movementSpeedLimit":{"value":5.0,"use":true},"rotationSpeedLimit":{"value":720.0,"use":true},"localInertia":1.0,"localMovementSpeedLimit":{"value":3.0,"use":true},"localRotationSpeedLimit":{"value":360.0,"use":true},"depthInertia":0.0,"centrifualAcceleration":0.0,"particleSpeedLimit":{"value":3.0,"use":true},"teleportMode":0,"teleportDistance":0.5,"teleportRotation":90.0},"tetherConstraint":{"distanceCompression":0.4000000059604645},"distanceConstraint":{"stiffness":{"value":1.0,"useCurve":false,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":1.0,"inSlope":0.0,"outSlope":-0.5,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":0.5,"inSlope":-0.5,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}}},"triangleBendingConstraint":{"stiffness":1.0},"angleRestorationConstraint":{"useAngleRestoration":true,"stiffness":{"value":0.20000000298023225,"useCurve":true,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":1.0,"inSlope":-2.279167652130127,"outSlope":-2.279167652130127,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.022117581218481065},{"serializedVersion":"3","time":1.0,"value":0.10624390840530396,"inSlope":-0.4003539979457855,"outSlope":-0.4003539979457855,"tangentMode":0,"weightedMode":0,"inWeight":0.03681504726409912,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}},"velocityAttenuation":0.800000011920929,"gravityFalloff":0.5},"angleLimitConstraint":{"useAngleLimit":true,"limitAngle":{"value":75.0,"useCurve":true,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":0.20166015625,"inSlope":1.901634693145752,"outSlope":1.901634693145752,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.03710045665502548},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":0.3574032187461853,"outSlope":0.3574032187461853,"tangentMode":0,"weightedMode":0,"inWeight":0.039668917655944827,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}},"stiffness":0.30000001192092898},"motionConstraint":{"useMaxDistance":false,"maxDistance":{"value":0.30000001192092898,"useCurve":false,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}},"useBackstop":false,"backstopRadius":10.0,"backstopDistance":{"value":0.0,"useCurve":false,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}},"stiffness":1.0},"colliderCollisionConstraint":{"mode":1,"friction":0.05000000074505806,"colliderList":[],"collisionBones":[],"limitDistance":{"value":0.05000000074505806,"useCurve":false,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}}},"selfCollisionConstraint":{"selfMode":0,"surfaceThickness":{"value":0.004999999888241291,"useCurve":false,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":0.5,"inSlope":0.0,"outSlope":0.5,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":0.5,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}},"syncMode":0,"syncPartner":{"instanceID":0},"clothMass":0.0},"wind":{"influence":0.20000000298023225,"frequency":1.0,"turbulence":1.0,"blend":0.699999988079071,"synchronization":0.699999988079071,"depthWeight":0.0,"movingWind":0.0},"springConstraint":{"useSpring":true,"springPower":0.05999999865889549,"limitDistance":0.05000000074505806,"normalLimitRatio":1.0,"springNoise":0.0}} \ No newline at end of file diff --git a/Assets/MagicaCloth2/Res/Preset/MC2_Preset_LongHair.json.meta b/Assets/MagicaCloth2/Res/Preset/MC2_Preset_LongHair.json.meta new file mode 100644 index 00000000..a3dc30bc --- /dev/null +++ b/Assets/MagicaCloth2/Res/Preset/MC2_Preset_LongHair.json.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: b688db48dba7a4b4f8c485ce7bd853aa +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Res/Preset/MC2_Preset_LongHair.json + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Res/Preset/MC2_Preset_MiddleSpring.json b/Assets/MagicaCloth2/Res/Preset/MC2_Preset_MiddleSpring.json new file mode 100644 index 00000000..7572dcad --- /dev/null +++ b/Assets/MagicaCloth2/Res/Preset/MC2_Preset_MiddleSpring.json @@ -0,0 +1 @@ +{"clothType":0,"sourceRenderers":[],"paintMode":0,"paintMaps":[],"rootBones":[],"connectionMode":0,"rotationalInterpolation":0.5,"rootRotation":0.5,"updateMode":10,"animationPoseRatio":0.0,"reductionSetting":{"simpleDistance":0.0,"shapeDistance":0.0},"customSkinningSetting":{"enable":false,"skinningBones":[]},"normalAlignmentSetting":{"alignmentMode":0,"adjustmentTransform":{"instanceID":0}},"cullingSettings":{"cameraCullingMode":30,"cameraCullingMethod":0,"cameraCullingRenderers":[]},"normalAxis":1,"gravity":0.0,"gravityDirection":{"x":0.0,"y":-1.0,"z":0.0},"gravityFalloff":0.0,"stablizationTimeAfterReset":0.10000000149011612,"damping":{"value":0.30000001192092898,"useCurve":false,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}},"radius":{"value":0.019999999552965165,"useCurve":false,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}},"inertiaConstraint":{"anchor":{"instanceID":0},"anchorInertia":0.0,"worldInertia":1.0,"movementInertiaSmoothing":0.4000000059604645,"movementSpeedLimit":{"value":1.0,"use":true},"rotationSpeedLimit":{"value":360.0,"use":true},"localInertia":1.0,"localMovementSpeedLimit":{"value":1.0,"use":true},"localRotationSpeedLimit":{"value":360.0,"use":true},"depthInertia":0.0,"centrifualAcceleration":0.0,"particleSpeedLimit":{"value":4.0,"use":true},"teleportMode":0,"teleportDistance":0.5,"teleportRotation":90.0},"tetherConstraint":{"distanceCompression":0.0989999994635582},"distanceConstraint":{"stiffness":{"value":0.24199999868869782,"useCurve":false,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":1.0,"inSlope":0.0,"outSlope":-0.5,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":0.5,"inSlope":-0.5,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}}},"triangleBendingConstraint":{"stiffness":0.2409999966621399},"angleRestorationConstraint":{"useAngleRestoration":true,"stiffness":{"value":0.4000000059604645,"useCurve":true,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":0.5023223757743836,"inSlope":-0.800000011920929,"outSlope":-0.800000011920929,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}},"velocityAttenuation":0.6000000238418579,"gravityFalloff":0.0},"angleLimitConstraint":{"useAngleLimit":false,"limitAngle":{"value":15.0,"useCurve":false,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":0.0,"inSlope":0.0,"outSlope":1.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":1.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}},"stiffness":0.5},"motionConstraint":{"useMaxDistance":false,"maxDistance":{"value":0.30000001192092898,"useCurve":false,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}},"useBackstop":false,"backstopRadius":10.0,"backstopDistance":{"value":0.0,"useCurve":false,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}},"stiffness":1.0},"colliderCollisionConstraint":{"mode":1,"friction":0.20000000298023225,"colliderList":[],"collisionBones":[],"limitDistance":{"value":0.05000000074505806,"useCurve":false,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}}},"selfCollisionConstraint":{"selfMode":0,"surfaceThickness":{"value":0.004999999888241291,"useCurve":false,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":0.5,"inSlope":0.0,"outSlope":0.5,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":0.5,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}},"syncMode":0,"syncPartner":{"instanceID":0},"clothMass":0.0},"wind":{"influence":0.20000000298023225,"frequency":1.0,"turbulence":1.0,"blend":0.699999988079071,"synchronization":0.699999988079071,"depthWeight":0.0,"movingWind":0.0},"springConstraint":{"useSpring":true,"springPower":0.029999999329447748,"limitDistance":0.05000000074505806,"normalLimitRatio":1.0,"springNoise":0.0}} \ No newline at end of file diff --git a/Assets/MagicaCloth2/Res/Preset/MC2_Preset_MiddleSpring.json.meta b/Assets/MagicaCloth2/Res/Preset/MC2_Preset_MiddleSpring.json.meta new file mode 100644 index 00000000..c47eca62 --- /dev/null +++ b/Assets/MagicaCloth2/Res/Preset/MC2_Preset_MiddleSpring.json.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: 68a74e7b24d750e498085ac9fe297e4f +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Res/Preset/MC2_Preset_MiddleSpring.json + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Res/Preset/MC2_Preset_ShortHair.json b/Assets/MagicaCloth2/Res/Preset/MC2_Preset_ShortHair.json new file mode 100644 index 00000000..63cacf26 --- /dev/null +++ b/Assets/MagicaCloth2/Res/Preset/MC2_Preset_ShortHair.json @@ -0,0 +1 @@ +{"clothType":0,"sourceRenderers":[],"meshWriteMode":0,"paintMode":0,"paintMaps":[],"rootBones":[],"connectionMode":0,"rotationalInterpolation":0.5,"rootRotation":0.5,"updateMode":10,"animationPoseRatio":0.0,"reductionSetting":{"simpleDistance":0.0,"shapeDistance":0.0},"customSkinningSetting":{"enable":false,"skinningBones":[]},"normalAlignmentSetting":{"alignmentMode":0,"adjustmentTransform":{"instanceID":0}},"cullingSettings":{"cameraCullingMode":30,"cameraCullingMethod":0,"cameraCullingRenderers":[],"distanceCullingLength":{"value":30.0,"use":false},"distanceCullingFadeRatio":0.20000000298023225,"distanceCullingReferenceObject":{"instanceID":0}},"normalAxis":1,"gravity":2.0,"gravityDirection":{"x":0.0,"y":-1.0,"z":0.0},"gravityFalloff":1.0,"stablizationTimeAfterReset":0.10000000149011612,"blendWeight":1.0,"damping":{"value":0.10000000149011612,"useCurve":false,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}},"radius":{"value":0.019999999552965165,"useCurve":false,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}},"inertiaConstraint":{"anchor":{"instanceID":0},"anchorInertia":0.0,"worldInertia":1.0,"movementInertiaSmoothing":0.4000000059604645,"movementSpeedLimit":{"value":5.0,"use":true},"rotationSpeedLimit":{"value":720.0,"use":true},"localInertia":1.0,"localMovementSpeedLimit":{"value":1.0,"use":true},"localRotationSpeedLimit":{"value":360.0,"use":true},"depthInertia":1.0,"centrifualAcceleration":0.0,"particleSpeedLimit":{"value":4.0,"use":true},"teleportMode":0,"teleportDistance":0.5,"teleportRotation":90.0},"tetherConstraint":{"distanceCompression":0.20000000298023225},"distanceConstraint":{"stiffness":{"value":1.0,"useCurve":false,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":1.0,"inSlope":0.0,"outSlope":-0.5,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":0.5,"inSlope":-0.5,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}}},"triangleBendingConstraint":{"stiffness":1.0},"angleRestorationConstraint":{"useAngleRestoration":true,"stiffness":{"value":0.15000000596046449,"useCurve":true,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":1.0,"inSlope":0.0,"outSlope":-0.699999988079071,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":0.30000001192092898,"inSlope":-0.699999988079071,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}},"velocityAttenuation":0.6000000238418579,"gravityFalloff":0.0},"angleLimitConstraint":{"useAngleLimit":true,"limitAngle":{"value":45.0,"useCurve":true,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":0.19974899291992188,"inSlope":0.8002510070800781,"outSlope":0.8002510070800781,"tangentMode":34,"weightedMode":0,"inWeight":0.0,"outWeight":0.3333333432674408},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":0.8002510070800781,"outSlope":0.8002510070800781,"tangentMode":34,"weightedMode":0,"inWeight":0.3333333432674408,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}},"stiffness":1.0},"motionConstraint":{"useMaxDistance":false,"maxDistance":{"value":0.30000001192092898,"useCurve":false,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}},"useBackstop":false,"backstopRadius":10.0,"backstopDistance":{"value":0.0,"useCurve":false,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}},"stiffness":1.0},"colliderCollisionConstraint":{"mode":1,"friction":0.05000000074505806,"colliderList":[],"collisionBones":[],"limitDistance":{"value":0.05000000074505806,"useCurve":false,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}}},"selfCollisionConstraint":{"selfMode":0,"surfaceThickness":{"value":0.004999999888241291,"useCurve":false,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":0.5,"inSlope":0.0,"outSlope":0.5,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":0.5,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}},"syncMode":0,"syncPartner":{"instanceID":0},"clothMass":0.0},"wind":{"influence":0.20000000298023225,"frequency":1.0,"turbulence":1.0,"blend":0.699999988079071,"synchronization":0.699999988079071,"depthWeight":0.0,"movingWind":0.0},"springConstraint":{"useSpring":true,"springPower":0.029999999329447748,"limitDistance":0.05000000074505806,"normalLimitRatio":1.0,"springNoise":0.0}} \ No newline at end of file diff --git a/Assets/MagicaCloth2/Res/Preset/MC2_Preset_ShortHair.json.meta b/Assets/MagicaCloth2/Res/Preset/MC2_Preset_ShortHair.json.meta new file mode 100644 index 00000000..62fa5bc5 --- /dev/null +++ b/Assets/MagicaCloth2/Res/Preset/MC2_Preset_ShortHair.json.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: 60b35931200639b4a834d868c78aef6a +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Res/Preset/MC2_Preset_ShortHair.json + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Res/Preset/MC2_Preset_Skirt.json b/Assets/MagicaCloth2/Res/Preset/MC2_Preset_Skirt.json new file mode 100644 index 00000000..e5be0843 --- /dev/null +++ b/Assets/MagicaCloth2/Res/Preset/MC2_Preset_Skirt.json @@ -0,0 +1 @@ +{"clothType":0,"sourceRenderers":[],"meshWriteMode":0,"paintMode":0,"paintMaps":[],"rootBones":[],"connectionMode":0,"rotationalInterpolation":0.5,"rootRotation":0.5,"updateMode":10,"animationPoseRatio":0.0,"reductionSetting":{"simpleDistance":0.0,"shapeDistance":0.0},"customSkinningSetting":{"enable":false,"skinningBones":[]},"normalAlignmentSetting":{"alignmentMode":0,"adjustmentTransform":{"instanceID":0}},"cullingSettings":{"cameraCullingMode":30,"cameraCullingMethod":0,"cameraCullingRenderers":[],"distanceCullingLength":{"value":30.0,"use":false},"distanceCullingFadeRatio":0.20000000298023225,"distanceCullingReferenceObject":{"instanceID":0}},"normalAxis":1,"gravity":5.0,"gravityDirection":{"x":0.0,"y":-1.0,"z":0.0},"gravityFalloff":0.0,"stablizationTimeAfterReset":0.10000000149011612,"blendWeight":1.0,"damping":{"value":0.10000000149011612,"useCurve":false,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}},"radius":{"value":0.019999999552965165,"useCurve":false,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}},"inertiaConstraint":{"anchor":{"instanceID":0},"anchorInertia":0.0,"worldInertia":1.0,"movementInertiaSmoothing":0.4000000059604645,"movementSpeedLimit":{"value":5.0,"use":true},"rotationSpeedLimit":{"value":720.0,"use":true},"localInertia":1.0,"localMovementSpeedLimit":{"value":3.0,"use":true},"localRotationSpeedLimit":{"value":360.0,"use":true},"depthInertia":0.699999988079071,"centrifualAcceleration":0.10000000149011612,"particleSpeedLimit":{"value":4.0,"use":true},"teleportMode":0,"teleportDistance":0.5,"teleportRotation":90.0},"tetherConstraint":{"distanceCompression":0.30000001192092898},"distanceConstraint":{"stiffness":{"value":1.0,"useCurve":true,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":1.0,"inSlope":0.0,"outSlope":-0.5,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":0.5,"inSlope":-0.5,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}}},"triangleBendingConstraint":{"stiffness":1.0},"angleRestorationConstraint":{"useAngleRestoration":true,"stiffness":{"value":0.20000000298023225,"useCurve":true,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":1.0,"inSlope":-0.7955245971679688,"outSlope":-0.7955245971679688,"tangentMode":34,"weightedMode":0,"inWeight":0.0,"outWeight":0.3333333432674408},{"serializedVersion":"3","time":1.0,"value":0.20447540283203126,"inSlope":-0.7955245971679688,"outSlope":-0.7955245971679688,"tangentMode":34,"weightedMode":0,"inWeight":0.3333333432674408,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}},"velocityAttenuation":0.699999988079071,"gravityFalloff":0.0},"angleLimitConstraint":{"useAngleLimit":true,"limitAngle":{"value":60.0,"useCurve":true,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":0.19974899291992188,"inSlope":0.8002510070800781,"outSlope":0.8002510070800781,"tangentMode":34,"weightedMode":0,"inWeight":0.0,"outWeight":0.3333333432674408},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":0.8002510070800781,"outSlope":0.8002510070800781,"tangentMode":34,"weightedMode":0,"inWeight":0.3333333432674408,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}},"stiffness":1.0},"motionConstraint":{"useMaxDistance":false,"maxDistance":{"value":0.30000001192092898,"useCurve":false,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}},"useBackstop":false,"backstopRadius":10.0,"backstopDistance":{"value":0.0,"useCurve":false,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}},"stiffness":1.0},"colliderCollisionConstraint":{"mode":1,"friction":0.05000000074505806,"colliderList":[],"collisionBones":[],"limitDistance":{"value":0.05000000074505806,"useCurve":false,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}}},"selfCollisionConstraint":{"selfMode":0,"surfaceThickness":{"value":0.004999999888241291,"useCurve":false,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":0.5,"inSlope":0.0,"outSlope":0.5,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":0.5,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}},"syncMode":0,"syncPartner":{"instanceID":0},"clothMass":0.0},"wind":{"influence":0.20000000298023225,"frequency":1.0,"turbulence":1.0,"blend":0.699999988079071,"synchronization":0.699999988079071,"depthWeight":0.0,"movingWind":0.0},"springConstraint":{"useSpring":true,"springPower":0.029999999329447748,"limitDistance":0.05000000074505806,"normalLimitRatio":1.0,"springNoise":0.0}} \ No newline at end of file diff --git a/Assets/MagicaCloth2/Res/Preset/MC2_Preset_Skirt.json.meta b/Assets/MagicaCloth2/Res/Preset/MC2_Preset_Skirt.json.meta new file mode 100644 index 00000000..19347ef0 --- /dev/null +++ b/Assets/MagicaCloth2/Res/Preset/MC2_Preset_Skirt.json.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: b94503c65e3e33243bd3dc5b47960b64 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Res/Preset/MC2_Preset_Skirt.json + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Res/Preset/MC2_Preset_SoftSkirt.json b/Assets/MagicaCloth2/Res/Preset/MC2_Preset_SoftSkirt.json new file mode 100644 index 00000000..b3815b6c --- /dev/null +++ b/Assets/MagicaCloth2/Res/Preset/MC2_Preset_SoftSkirt.json @@ -0,0 +1 @@ +{"clothType":0,"sourceRenderers":[],"meshWriteMode":0,"paintMode":0,"paintMaps":[],"rootBones":[],"connectionMode":0,"rotationalInterpolation":0.5,"rootRotation":0.5,"updateMode":10,"animationPoseRatio":0.0,"reductionSetting":{"simpleDistance":0.0,"shapeDistance":0.0},"customSkinningSetting":{"enable":false,"skinningBones":[]},"normalAlignmentSetting":{"alignmentMode":0,"adjustmentTransform":{"instanceID":0}},"cullingSettings":{"cameraCullingMode":30,"cameraCullingMethod":0,"cameraCullingRenderers":[],"distanceCullingLength":{"value":30.0,"use":false},"distanceCullingFadeRatio":0.20000000298023225,"distanceCullingReferenceObject":{"instanceID":0}},"normalAxis":1,"gravity":3.0,"gravityDirection":{"x":0.0,"y":-1.0,"z":0.0},"gravityFalloff":0.0,"stablizationTimeAfterReset":0.10000000149011612,"blendWeight":1.0,"damping":{"value":0.10000000149011612,"useCurve":false,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}},"radius":{"value":0.019999999552965165,"useCurve":false,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}},"inertiaConstraint":{"anchor":{"instanceID":0},"anchorInertia":0.0,"worldInertia":1.0,"movementInertiaSmoothing":0.4000000059604645,"movementSpeedLimit":{"value":5.0,"use":true},"rotationSpeedLimit":{"value":720.0,"use":true},"localInertia":1.0,"localMovementSpeedLimit":{"value":3.0,"use":true},"localRotationSpeedLimit":{"value":360.0,"use":true},"depthInertia":0.25,"centrifualAcceleration":0.10000000149011612,"particleSpeedLimit":{"value":4.0,"use":true},"teleportMode":0,"teleportDistance":0.5,"teleportRotation":90.0},"tetherConstraint":{"distanceCompression":0.30000001192092898},"distanceConstraint":{"stiffness":{"value":1.0,"useCurve":true,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":0.043365478515625,"inSlope":-0.20151586830615998,"outSlope":-0.20151586830615998,"tangentMode":0,"weightedMode":0,"inWeight":0.07299280166625977,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}}},"triangleBendingConstraint":{"stiffness":0.23000000417232514},"angleRestorationConstraint":{"useAngleRestoration":true,"stiffness":{"value":0.14000000059604646,"useCurve":true,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":1.0,"inSlope":-0.9402999877929688,"outSlope":-0.9402999877929688,"tangentMode":34,"weightedMode":0,"inWeight":0.0,"outWeight":0.3333333432674408},{"serializedVersion":"3","time":1.0,"value":0.05970001220703125,"inSlope":-0.28568774461746218,"outSlope":-0.28568774461746218,"tangentMode":0,"weightedMode":0,"inWeight":0.0834202766418457,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}},"velocityAttenuation":0.699999988079071,"gravityFalloff":0.0},"angleLimitConstraint":{"useAngleLimit":false,"limitAngle":{"value":60.0,"useCurve":true,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":0.19974899291992188,"inSlope":0.8002510070800781,"outSlope":0.8002510070800781,"tangentMode":34,"weightedMode":0,"inWeight":0.0,"outWeight":0.3333333432674408},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":0.8002510070800781,"outSlope":0.8002510070800781,"tangentMode":34,"weightedMode":0,"inWeight":0.3333333432674408,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}},"stiffness":1.0},"motionConstraint":{"useMaxDistance":false,"maxDistance":{"value":0.30000001192092898,"useCurve":false,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}},"useBackstop":false,"backstopRadius":10.0,"backstopDistance":{"value":0.0,"useCurve":false,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}},"stiffness":1.0},"colliderCollisionConstraint":{"mode":1,"friction":0.05000000074505806,"colliderList":[],"collisionBones":[],"limitDistance":{"value":0.05000000074505806,"useCurve":false,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}}},"selfCollisionConstraint":{"selfMode":0,"surfaceThickness":{"value":0.004999999888241291,"useCurve":false,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":0.5,"inSlope":0.0,"outSlope":0.5,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":0.5,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}},"syncMode":0,"syncPartner":{"instanceID":0},"clothMass":0.0},"wind":{"influence":0.20000000298023225,"frequency":1.0,"turbulence":1.0,"blend":0.699999988079071,"synchronization":0.699999988079071,"depthWeight":0.0,"movingWind":0.0},"springConstraint":{"useSpring":true,"springPower":0.029999999329447748,"limitDistance":0.05000000074505806,"normalLimitRatio":1.0,"springNoise":0.0}} \ No newline at end of file diff --git a/Assets/MagicaCloth2/Res/Preset/MC2_Preset_SoftSkirt.json.meta b/Assets/MagicaCloth2/Res/Preset/MC2_Preset_SoftSkirt.json.meta new file mode 100644 index 00000000..c810a45e --- /dev/null +++ b/Assets/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.18.1 + assetPath: Assets/MagicaCloth2/Res/Preset/MC2_Preset_SoftSkirt.json + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Res/Preset/MC2_Preset_SoftSpring.json b/Assets/MagicaCloth2/Res/Preset/MC2_Preset_SoftSpring.json new file mode 100644 index 00000000..4c8d57ab --- /dev/null +++ b/Assets/MagicaCloth2/Res/Preset/MC2_Preset_SoftSpring.json @@ -0,0 +1 @@ +{"clothType":0,"sourceRenderers":[],"paintMode":0,"paintMaps":[],"rootBones":[],"connectionMode":0,"rotationalInterpolation":0.5,"rootRotation":0.5,"updateMode":10,"animationPoseRatio":0.0,"reductionSetting":{"simpleDistance":0.0,"shapeDistance":0.0},"customSkinningSetting":{"enable":false,"skinningBones":[]},"normalAlignmentSetting":{"alignmentMode":0,"adjustmentTransform":{"instanceID":0}},"cullingSettings":{"cameraCullingMode":30,"cameraCullingMethod":0,"cameraCullingRenderers":[]},"normalAxis":1,"gravity":0.0,"gravityDirection":{"x":0.0,"y":-1.0,"z":0.0},"gravityFalloff":0.0,"stablizationTimeAfterReset":0.10000000149011612,"damping":{"value":0.20000000298023225,"useCurve":false,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}},"radius":{"value":0.019999999552965165,"useCurve":false,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}},"inertiaConstraint":{"anchor":{"instanceID":0},"anchorInertia":0.0,"worldInertia":1.0,"movementInertiaSmoothing":0.4000000059604645,"movementSpeedLimit":{"value":1.0,"use":true},"rotationSpeedLimit":{"value":360.0,"use":true},"localInertia":1.0,"localMovementSpeedLimit":{"value":1.0,"use":true},"localRotationSpeedLimit":{"value":360.0,"use":true},"depthInertia":0.0,"centrifualAcceleration":0.0,"particleSpeedLimit":{"value":4.0,"use":true},"teleportMode":0,"teleportDistance":0.5,"teleportRotation":90.0},"tetherConstraint":{"distanceCompression":0.0989999994635582},"distanceConstraint":{"stiffness":{"value":0.24199999868869782,"useCurve":false,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":1.0,"inSlope":0.0,"outSlope":-0.5,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":0.5,"inSlope":-0.5,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}}},"triangleBendingConstraint":{"stiffness":0.2409999966621399},"angleRestorationConstraint":{"useAngleRestoration":true,"stiffness":{"value":0.20000000298023225,"useCurve":true,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":0.5023223757743836,"inSlope":-0.800000011920929,"outSlope":-0.800000011920929,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}},"velocityAttenuation":0.800000011920929,"gravityFalloff":0.0},"angleLimitConstraint":{"useAngleLimit":false,"limitAngle":{"value":15.0,"useCurve":false,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":0.0,"inSlope":0.0,"outSlope":1.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":1.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}},"stiffness":1.0},"motionConstraint":{"useMaxDistance":false,"maxDistance":{"value":0.30000001192092898,"useCurve":false,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}},"useBackstop":false,"backstopRadius":10.0,"backstopDistance":{"value":0.0,"useCurve":false,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}},"stiffness":1.0},"colliderCollisionConstraint":{"mode":1,"friction":0.20000000298023225,"colliderList":[],"collisionBones":[],"limitDistance":{"value":0.05000000074505806,"useCurve":false,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}}},"selfCollisionConstraint":{"selfMode":0,"surfaceThickness":{"value":0.004999999888241291,"useCurve":false,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":0.5,"inSlope":0.0,"outSlope":0.5,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":0.5,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}},"syncMode":0,"syncPartner":{"instanceID":0},"clothMass":0.0},"wind":{"influence":0.20000000298023225,"frequency":1.0,"turbulence":1.0,"blend":0.699999988079071,"synchronization":0.699999988079071,"depthWeight":0.0,"movingWind":0.0},"springConstraint":{"useSpring":true,"springPower":0.009999999776482582,"limitDistance":0.05000000074505806,"normalLimitRatio":1.0,"springNoise":0.0}} \ No newline at end of file diff --git a/Assets/MagicaCloth2/Res/Preset/MC2_Preset_SoftSpring.json.meta b/Assets/MagicaCloth2/Res/Preset/MC2_Preset_SoftSpring.json.meta new file mode 100644 index 00000000..ff72eed2 --- /dev/null +++ b/Assets/MagicaCloth2/Res/Preset/MC2_Preset_SoftSpring.json.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: a53c4836c458cc34bbe7fc971a0e8198 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Res/Preset/MC2_Preset_SoftSpring.json + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Res/Preset/MC2_Preset_Tail.json b/Assets/MagicaCloth2/Res/Preset/MC2_Preset_Tail.json new file mode 100644 index 00000000..f49ac2b7 --- /dev/null +++ b/Assets/MagicaCloth2/Res/Preset/MC2_Preset_Tail.json @@ -0,0 +1 @@ +{"clothType":0,"sourceRenderers":[],"meshWriteMode":0,"paintMode":0,"paintMaps":[],"rootBones":[],"connectionMode":0,"rotationalInterpolation":0.5,"rootRotation":0.5,"updateMode":10,"animationPoseRatio":0.0,"reductionSetting":{"simpleDistance":0.0,"shapeDistance":0.0},"customSkinningSetting":{"enable":false,"skinningBones":[]},"normalAlignmentSetting":{"alignmentMode":0,"adjustmentTransform":{"instanceID":0}},"cullingSettings":{"cameraCullingMode":30,"cameraCullingMethod":0,"cameraCullingRenderers":[],"distanceCullingLength":{"value":30.0,"use":false},"distanceCullingFadeRatio":0.20000000298023225,"distanceCullingReferenceObject":{"instanceID":0}},"normalAxis":1,"gravity":0.0,"gravityDirection":{"x":0.0,"y":-1.0,"z":0.0},"gravityFalloff":0.0,"stablizationTimeAfterReset":0.10000000149011612,"blendWeight":1.0,"damping":{"value":0.05000000074505806,"useCurve":false,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}},"radius":{"value":0.019999999552965165,"useCurve":false,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}},"inertiaConstraint":{"anchor":{"instanceID":0},"anchorInertia":0.0,"worldInertia":1.0,"movementInertiaSmoothing":0.4000000059604645,"movementSpeedLimit":{"value":5.0,"use":true},"rotationSpeedLimit":{"value":720.0,"use":true},"localInertia":1.0,"localMovementSpeedLimit":{"value":3.0,"use":true},"localRotationSpeedLimit":{"value":360.0,"use":true},"depthInertia":0.0,"centrifualAcceleration":0.0,"particleSpeedLimit":{"value":4.0,"use":true},"teleportMode":0,"teleportDistance":0.5,"teleportRotation":90.0},"tetherConstraint":{"distanceCompression":0.5},"distanceConstraint":{"stiffness":{"value":1.0,"useCurve":false,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":1.0,"inSlope":0.0,"outSlope":-0.5,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":0.5,"inSlope":-0.5,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}}},"triangleBendingConstraint":{"stiffness":0.5},"angleRestorationConstraint":{"useAngleRestoration":true,"stiffness":{"value":0.10000000149011612,"useCurve":true,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":1.0,"inSlope":-1.5032808780670167,"outSlope":-1.5032808780670167,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.03353310376405716},{"serializedVersion":"3","time":1.0,"value":0.09733137488365174,"inSlope":-0.1739719808101654,"outSlope":-0.1739719808101654,"tangentMode":0,"weightedMode":0,"inWeight":0.045376718044281009,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}},"velocityAttenuation":0.5,"gravityFalloff":0.0},"angleLimitConstraint":{"useAngleLimit":false,"limitAngle":{"value":80.0,"useCurve":true,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":0.0,"inSlope":0.0,"outSlope":1.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":1.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}},"stiffness":1.0},"motionConstraint":{"useMaxDistance":false,"maxDistance":{"value":0.30000001192092898,"useCurve":false,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}},"useBackstop":false,"backstopRadius":10.0,"backstopDistance":{"value":0.0,"useCurve":false,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}},"stiffness":1.0},"colliderCollisionConstraint":{"mode":1,"friction":0.05000000074505806,"colliderList":[],"collisionBones":[],"limitDistance":{"value":0.05000000074505806,"useCurve":false,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}}},"selfCollisionConstraint":{"selfMode":0,"surfaceThickness":{"value":0.004999999888241291,"useCurve":false,"curve":{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":0.5,"inSlope":0.0,"outSlope":0.5,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":0.5,"outSlope":0.0,"tangentMode":0,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}},"syncMode":0,"syncPartner":{"instanceID":0},"clothMass":0.0},"wind":{"influence":0.20000000298023225,"frequency":1.0,"turbulence":1.0,"blend":0.699999988079071,"synchronization":0.699999988079071,"depthWeight":0.0,"movingWind":0.0},"springConstraint":{"useSpring":true,"springPower":0.009999999776482582,"limitDistance":0.05000000074505806,"normalLimitRatio":1.0,"springNoise":0.0}} \ No newline at end of file diff --git a/Assets/MagicaCloth2/Res/Preset/MC2_Preset_Tail.json.meta b/Assets/MagicaCloth2/Res/Preset/MC2_Preset_Tail.json.meta new file mode 100644 index 00000000..18c8150f --- /dev/null +++ b/Assets/MagicaCloth2/Res/Preset/MC2_Preset_Tail.json.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: 7caaf9c3e9b56af468785ce6ca87d2bc +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Res/Preset/MC2_Preset_Tail.json + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts.meta b/Assets/MagicaCloth2/Scripts.meta new file mode 100644 index 00000000..9557b29a --- /dev/null +++ b/Assets/MagicaCloth2/Scripts.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 4bcf05bcd5b995944867a92f1bc9e86d +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/MagicaCloth2/Scripts/Core.meta b/Assets/MagicaCloth2/Scripts/Core.meta new file mode 100644 index 00000000..deb2108d --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 59a207b400ba60d4781d33fac21726f1 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/MagicaCloth2/Scripts/Core/Cloth.meta b/Assets/MagicaCloth2/Scripts/Core/Cloth.meta new file mode 100644 index 00000000..ce4ce894 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Cloth.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: ab3867f2676a64143aaab90a3ac67059 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/MagicaCloth2/Scripts/Core/Cloth/CheckSliderSerializeData.cs b/Assets/MagicaCloth2/Scripts/Core/Cloth/CheckSliderSerializeData.cs new file mode 100644 index 00000000..9a32f936 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Cloth/CheckSliderSerializeData.cs @@ -0,0 +1,57 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using UnityEngine; + +namespace MagicaCloth2 +{ + [System.Serializable] + public class CheckSliderSerializeData + { + /// + /// slider value. + /// + public float value; + + /// + /// Use + /// + public bool use; + + public CheckSliderSerializeData() + { + } + + public CheckSliderSerializeData(bool use, float value) + { + this.use = use; + this.value = value; + } + + public float GetValue(float unusedValue) + { + return use ? value : unusedValue; + } + + public void SetValue(bool use, float value) + { + this.use = use; + this.value = value; + } + + public void DataValidate(float min, float max) + { + value = Mathf.Clamp(value, min, max); + } + + public CheckSliderSerializeData Clone() + { + var cdata = new CheckSliderSerializeData() + { + value = value, + use = use, + }; + return cdata; + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/Cloth/CheckSliderSerializeData.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Cloth/CheckSliderSerializeData.cs.meta new file mode 100644 index 00000000..ed08f7f3 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Cloth/CheckSliderSerializeData.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: ffc5377e82b4dda4e9276efa83bcd59e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Cloth/CheckSliderSerializeData.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Cloth/ClothBehaviour.cs b/Assets/MagicaCloth2/Scripts/Core/Cloth/ClothBehaviour.cs new file mode 100644 index 00000000..13c645cc --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Cloth/ClothBehaviour.cs @@ -0,0 +1,29 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using UnityEngine; + +namespace MagicaCloth2 +{ + /// + /// MagicaClothのMonoBehaviour基礎クラス + /// すべてのコンポーネントはここから派生する + /// + public abstract class ClothBehaviour : MonoBehaviour + { + /// + /// Hash code for checking changes when editing. + /// + /// + public virtual int GetMagicaHashCode() + { + return 0; + } + + /// + /// Gizmo display state. + /// + public bool IsGizmoVisible { get; set; } + protected virtual void OnDrawGizmos() => IsGizmoVisible = true; + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/Cloth/ClothBehaviour.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Cloth/ClothBehaviour.cs.meta new file mode 100644 index 00000000..d1ee0a41 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Cloth/ClothBehaviour.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: ad3b3cf159e43e1489f421d5b1f49fad +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Cloth/ClothBehaviour.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Cloth/ClothDisableMode.cs b/Assets/MagicaCloth2/Scripts/Core/Cloth/ClothDisableMode.cs new file mode 100644 index 00000000..a41135ba --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Cloth/ClothDisableMode.cs @@ -0,0 +1,22 @@ +// Magica Cloth 2. +// Copyright (c) 2026 MagicaSoft. +// https://magicasoft.jp + +namespace MagicaCloth2 +{ + /// + /// Simulation Disable Mode + /// + public enum ClothDisableMode + { + /// + /// Reset the simulation. + /// + Reset = 0, + + /// + /// Maintain the simulation. + /// + Keep = 1, + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/Cloth/ClothDisableMode.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Cloth/ClothDisableMode.cs.meta new file mode 100644 index 00000000..35806cb0 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Cloth/ClothDisableMode.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: b7f7df74e3431e84199fe50874a58668 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Cloth/ClothDisableMode.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Cloth/ClothForceMode.cs b/Assets/MagicaCloth2/Scripts/Core/Cloth/ClothForceMode.cs new file mode 100644 index 00000000..022f3869 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Cloth/ClothForceMode.cs @@ -0,0 +1,36 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp + +namespace MagicaCloth2 +{ + + public enum ClothForceMode + { + None, + + /// + /// 速度に加算(深さの影響を受ける) + /// Add to velocity (affected by depth). + /// + VelocityAdd, + + /// + /// 速度を変更(深さの影響を受ける) + /// Change velocity (affected by depth). + /// + VelocityChange, + + /// + /// 速度に加算(深さ無視) + /// Add to velocity (ignoring depth). + /// + VelocityAddWithoutDepth = 10, + + /// + /// 速度を変更(深さ無視) + /// Change velocity (ignoring depth). + /// + VelocityChangeWithoutDepth, + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/Cloth/ClothForceMode.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Cloth/ClothForceMode.cs.meta new file mode 100644 index 00000000..62460d04 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Cloth/ClothForceMode.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: f572ed4fa93dcd444a44e59253bd3913 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Cloth/ClothForceMode.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Cloth/ClothInitSerializeData.cs b/Assets/MagicaCloth2/Scripts/Core/Cloth/ClothInitSerializeData.cs new file mode 100644 index 00000000..a4a3b465 --- /dev/null +++ b/Assets/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/MagicaCloth2/Scripts/Core/Cloth/ClothInitSerializeData.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Cloth/ClothInitSerializeData.cs.meta new file mode 100644 index 00000000..33d8a4c5 --- /dev/null +++ b/Assets/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.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Cloth/ClothInitSerializeData.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Cloth/ClothMeshWriteMode.cs b/Assets/MagicaCloth2/Scripts/Core/Cloth/ClothMeshWriteMode.cs new file mode 100644 index 00000000..f32a33a7 --- /dev/null +++ b/Assets/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/MagicaCloth2/Scripts/Core/Cloth/ClothMeshWriteMode.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Cloth/ClothMeshWriteMode.cs.meta new file mode 100644 index 00000000..6d91cd18 --- /dev/null +++ b/Assets/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.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Cloth/ClothMeshWriteMode.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Cloth/ClothNormalAxis.cs b/Assets/MagicaCloth2/Scripts/Core/Cloth/ClothNormalAxis.cs new file mode 100644 index 00000000..7d63b35d --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Cloth/ClothNormalAxis.cs @@ -0,0 +1,27 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using UnityEngine; + +namespace MagicaCloth2 +{ + /// + /// Axis to use as normal. + /// 法線として利用する軸 + /// + public enum ClothNormalAxis + { + [InspectorName("Right (red)")] + Right = 0, + [InspectorName("Up (green)")] + Up = 1, + [InspectorName("Forward (blue)")] + Forward = 2, + [InspectorName("Inverse Right (red)")] + InverseRight = 3, + [InspectorName("Inverse Up (green)")] + InverseUp = 4, + [InspectorName("Inverse Forward (blue)")] + InverseForward = 5, + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/Cloth/ClothNormalAxis.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Cloth/ClothNormalAxis.cs.meta new file mode 100644 index 00000000..c34af11c --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Cloth/ClothNormalAxis.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 78c44c48c8886814eac01297e0df1b61 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Cloth/ClothNormalAxis.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Cloth/ClothParameters.cs b/Assets/MagicaCloth2/Scripts/Core/Cloth/ClothParameters.cs new file mode 100644 index 00000000..90ac7c2f --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Cloth/ClothParameters.cs @@ -0,0 +1,99 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using Unity.Mathematics; + +namespace MagicaCloth2 +{ + /// + /// ジョブで利用するためのクロスパラメータ構造体 + /// ジョブではclassを参照できないためunmanaged型に変換する必要がある + /// + public struct ClothParameters + { + /// + /// 1秒間の更新回数 + /// + //public int solverFrequency; + + /// + /// 重力 + /// + public float gravity; + + /// + /// 重力方向(ワールド空間) + /// + public float3 worldGravityDirection; + + /// + /// 初期姿勢での重力の減衰率(0.0 ~ 1.0) + /// 1.0にすることで初期姿勢では重力係数が0になる。 + /// 0.0では常にどの姿勢でも重力が100%発生する。 + /// 姿勢計算は慣性トランスフォームで行われる。 + /// + public float gravityFalloff; + + /// + /// リセット後の速度安定化時間(s) + /// + public float stablizationTimeAfterReset; + + /// + /// 元の姿勢とシミュレーション結果のブレンド割合(0.0 ~ 1.0) + /// + public float blendWeight; + + /// + /// 抵抗 + /// + public float4x4 dampingCurveData; + + /// + /// パーティクル半径 + /// + public float4x4 radiusCurveData; + + /// + /// 法線として利用する軸 + /// + public ClothNormalAxis normalAxis; + + // BoneCloth用 + public float rotationalInterpolation; + public float rootRotation; + + // カリング(Culling) + public CullingSettings.CullingParams culling; + + // 慣性制約(Inertia) + public InertiaConstraint.InertiaConstraintParams inertiaConstraint; + + // 最大距離制約(Tether) + public TetherConstraint.TetherConstraintParams tetherConstraint; + + // 距離制約(Distance) + public DistanceConstraint.DistanceConstraintParams distanceConstraint; + + // トライアングル曲げ制約(TriangleBending) + public TriangleBendingConstraint.TriangleBendingConstraintParams triangleBendingConstraint; + + // 角度復元/角度制限 + public AngleConstraint.AngleConstraintParams angleConstraint; + + // モーション(MaxDistance/Backstop) + public MotionConstraint.MotionConstraintParams motionConstraint; + + // コライダーコリジョン(Collider Collision) + public ColliderCollisionConstraint.ColliderCollisionConstraintParams colliderCollisionConstraint; + + // セルフコリジョン(Self Collision) + public SelfCollisionConstraint.SelfCollisionConstraintParams selfCollisionConstraint; + + // 風(Wind) + public WindParams wind; + + // スプリング(Spring) + public SpringConstraint.SpringConstraintParams springConstraint; + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/Cloth/ClothParameters.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Cloth/ClothParameters.cs.meta new file mode 100644 index 00000000..8b5728e1 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Cloth/ClothParameters.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 26334216fdc5aaa4ca50312fbad62c97 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Cloth/ClothParameters.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Cloth/ClothProcess.cs b/Assets/MagicaCloth2/Scripts/Core/Cloth/ClothProcess.cs new file mode 100644 index 00000000..389388b8 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Cloth/ClothProcess.cs @@ -0,0 +1,1588 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using System; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using Unity.Burst; +using Unity.Collections; +using Unity.Jobs; +using Unity.Mathematics; +using Unity.Profiling; +using UnityEngine; + +namespace MagicaCloth2 +{ + /// + /// MagicaClothコンポーネントの処理 + /// + public partial class ClothProcess + { + //========================================================================================= + static readonly ProfilerMarker initClothProfiler = new ProfilerMarker("InitCloth"); + + /// + /// 初期化(必ずアニメーションの実行前に行う) + /// + internal void Init() + { + Debug.Assert(cloth); + Develop.DebugLog($"Init start [{cloth.name}]"); + initClothProfiler.Begin(); + result.SetSuccess(); + InitDataResult.Clear(); + + try + { + // すでに破棄されている場合はエラーとする。再初期化はできない + if (isDestory) + { + 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()) + { + 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) + { + // 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; + + MagicaObjectId handle = AddRenderer(ren, setup, uniquePreBuildSetupData, initSetupData); + if (handle.IsValid() == false) + { + 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.GetMagicaId(), syncPartnerCloth.GetMagicaId()); + + // 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.GetMagicaId(), SyncTopCloth.GetMagicaId()); + } + + result.SetSuccess(); + SetState(State_Valid, true); + SetState(State_InitSuccess, true); + SetState(State_Verification, true); + + // この時点でクロスコンポーネントが非アクティブの場合は破棄監視リストに登録する + if (cloth.isActiveAndEnabled == false) + MagicaManager.Team.AddMonitoringProcess(this); + } + catch (OperationCanceledException) + { + } + catch (MagicaClothProcessingException) + { + } + catch (Exception exception) + { + Debug.LogException(exception); + result.SetError(Define.Result.ClothProcess_Exception); + } + + initClothProfiler.End(); + + if (result.IsSuccess()) + Develop.DebugLog($"Cloth Initialize Success! [{cloth.name}]"); + else + Develop.DebugLogError($"Cloth Initialize failure! [{cloth.name}] : {result.GetResultString()}"); + } + + /// + /// MeshClothの利用を登録する(メインスレッドのみ) + /// これはAwake()などのアニメーションの前に実行すること + /// + /// + /// レンダー情報ハンドル + MagicaObjectId AddRenderer( + Renderer ren, + RenderSetupData referenceSetupData, + RenderSetupData.UniqueSerializationData referenceUniqueSetupData, + RenderSetupSerializeData referenceInitSetupData + ) + { + if (ren == null) + return MagicaObjectId.Invalid; + if (renderHandleList == null) + return MagicaObjectId.Invalid; + + MagicaObjectId handle = ren.GetMagicaId(); + if (renderHandleList.Contains(handle) == false) + { + // レンダラーの利用開始 + handle = MagicaManager.Render.AddRenderer(ren, referenceSetupData, referenceUniqueSetupData, referenceInitSetupData); + if (handle.IsValid()) + { + lock (lockObject) + { + if (renderHandleList.Contains(handle) == false) + renderHandleList.Add(handle); + } + } + } + + return handle; + } + + /// + /// BoneClothの利用を開始する(メインスレッドのみ) + /// これはAwake()などのアニメーションの前に実行すること + /// + /// + /// + 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, + collisionBones, + connectionMode, + cloth.name + ); + } + + /// + /// 有効化 + /// + internal void StartUse() + { + if (MagicaManager.IsPlaying() == false) + return; + + SetState(State_Component, true); + UpdateUse(); + } + + /// + /// 無効化 + /// + internal void EndUse() + { + if (MagicaManager.IsPlaying() == false) + return; + + SetState(State_Component, false); + UpdateUse(); + } + + internal void UpdateUse() + { + // 有効状態判定 + bool now = IsState(State_Component) && IsState(State_Verification); + + // 切り替え + { + SetState(State_Enable, now); + + // チーム + MagicaManager.Team.SetEnable(this, TeamId, now); + + // レンダラー + if (renderHandleList != null) + { + foreach (MagicaObjectId renderHandle in renderHandleList) + { + if (now) + MagicaManager.Render.StartUse(this, renderHandle); + else + MagicaManager.Render.EndUse(this, renderHandle); + } + } + } + } + + /// + /// パラメータ/データの変更通知 + /// + internal void DataUpdate() + { + // パラメータ検証 + cloth.SerializeData.DataValidate(); + cloth.serializeData2.DataValidate(); + + // パラメータ変更(実行時のみ) + if (MagicaManager.IsPlaying()) + { + // ここでは変更フラグのみ立てる + //SetState(State_ParameterDirty, true); + MagicaManager.Team.parameterDirtyList.Add(this); + } + } + + //========================================================================================= + /// + /// 構築を開始し完了後に自動実行する + /// + internal bool StartRuntimeBuild() + { + // ビルド開始 + // -コンポーネントが有効であること + // -初期化済みであること + // -ビルドがまだ実行されていないこと + // -ベイクデータを利用しないこと + if (IsValid() && IsState(State_InitSuccess) && IsState(State_Build) == false && IsState(State_UsePreBuild) == false) + { + result.SetProcess(); + SetState(State_Build, true); + var _ = RuntimeBuildAsync(cts.Token); + return true; + } + else + { + if (result.IsError() == false) + result.SetError(Define.Result.CreateCloth_CanNotStart); + Develop.LogError($"Cloth runtime build failure! [{cloth.name}] : {result.GetResultString()}"); + return false; + } + } + + /// + /// 自動構築(コンポーネントのStart()で呼ばれる) + /// + /// + internal bool AutoBuild() + { + bool ret; + bool buildComplate = true; + + if (IsState(State_DisableAutoBuild)) + { + ret = false; + } + else + { + if (IsState(State_UsePreBuild)) + ret = PreBuildDataConstruction(); + else + { + ret = StartRuntimeBuild(); + if (ret) + buildComplate = false; // OnBuildCompleteはランタイム構築後に呼ばれる + } + } + + // ビルド完了イベント + if (buildComplate && cloth != null) + cloth.OnBuildComplete?.Invoke(cloth, ret); + + return ret; + } + + /// + /// 実行時構築タスク + /// + /// + /// + async Task RuntimeBuildAsync(CancellationToken ct) + { + isBuild = true; + Develop.DebugLog($"Build start : {Name}"); + result.SetProcess(); + + // 作成されたレンダラー情報 + var renderMeshInfos = new List(); + + // ProxyMesh + VirtualMesh proxyMesh = null; + + try + { + // ■メインスレッド + var sdata = cloth.SerializeData; + var sdata2 = cloth.GetSerializeData2(); + + // 少し時間を開けてから処理を開始する + await Task.Delay(5); + ct.ThrowIfCancellationRequested(); + + // 同期対象がいる場合は相手の一時停止カウンターを加算する + if (cloth.SyncPartnerCloth) + { + var sync = cloth.SyncPartnerCloth; + while (sync != cloth && sync != null) + { + sync.Process.IncrementSuspendCounter(); + 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(); + } + MagicaObjectId 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 && useManualVertexAttribute == false) + { + var ret = GeneratePaintMapDataList(paintMapDataList); + Develop.DebugLog($"Generate paint map data list. {ret.GetResultString()}"); + if (ret.IsError()) + { + result.Merge(ret); + throw new MagicaClothProcessingException(); + } + if (paintMapDataList.Count != renderHandleList.Count) + { + result.SetError(Define.Result.CreateCloth_PaintMapCountMismatch); + throw new MagicaClothProcessingException(); + } + usePaintMap = true; + } + + // セレクションデータ + // ペイントマップ指定もしくは頂点属性指定の場合は空で初期化 + SelectionData selectionData = (usePaintMap || useManualVertexAttribute) ? new SelectionData() : sdata2.selectionData.Clone(); + + // BoneCloth/BoneSpringでシリアライズ2にTransformと属性辞書がある場合はIDと属性の辞書に変換(スレッドではアクセスできないため) + Dictionary boneAttributeDict = null; + if (sdata2.boneAttributeDict.Count > 0) + { + boneAttributeDict = new Dictionary(sdata2.boneAttributeDict.Count); + foreach (var kv in sdata2.boneAttributeDict) + { + if (kv.Key) + { + boneAttributeDict.Add(kv.Key.GetMagicaId(), kv.Value); + } + } + } + + // ■スレッド + await Task.Run(() => + { + // 作業用メッシュ + VirtualMesh renderMesh = null; + + try + { + // プロキシメッシュ作成 + ct.ThrowIfCancellationRequested(); + proxyMesh = new VirtualMesh("Proxy"); + proxyMesh.result.SetProcess(); + List copyRenderHandleList = null; + if (clothType == ClothType.MeshCloth) + { + // MeshClothではクロストランスフォームを追加しておく + proxyMesh.SetTransform(clothTransformRecord); + + lock (lockObject) + { + copyRenderHandleList = new List(renderHandleList); + } + } + + // セレクションデータの有無 + bool isValidSelection = selectionData?.IsValid() ?? false; + + // MeshCloth/BoneClothで処理が一部異なる + if (clothType == ClothType.MeshCloth) + { + // ■MeshCloth + if (renderHandleList.Count == 0) + { + result.SetError(Define.Result.ClothProcess_InvalidRenderHandleList); + throw new MagicaClothProcessingException(); + } + + //-------------------------------------------------------------------- + // mesh import + selection + merge + for (int i = 0; i < copyRenderHandleList.Count; i++) + { + ct.ThrowIfCancellationRequested(); + + MagicaObjectId renderHandle = copyRenderHandleList[i]; + + // レンダーメッシュ作成 + var renderData = MagicaManager.Render.GetRendererData(renderHandle); + renderMesh = new VirtualMesh($"[{renderData.Name}]"); + renderMesh.result.SetProcess(); + + // import ------------------------------------------------- + renderMesh.ImportFrom(renderData, sdata.GetUvChannel()); + if (renderMesh.IsError) + { + result.Merge(renderMesh.result); + throw new MagicaClothProcessingException(); + } + Develop.DebugLog($"(IMPORT) {renderMesh}"); + + // selection ---------------------------------------------- + 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からセレクションデータ生成 + var ret = GenerateSelectionDataFromPaintMap(clothTransformRecord, renderMesh, paintMapDataList[i], out renderSelectionData); + Develop.DebugLog($"Generate selection from paint map. {ret.GetResultString()}"); + if (ret.IsError()) + { + result.Merge(ret); + throw new MagicaClothProcessingException(); + } + + // セレクションデータ結合 + selectionData.Merge(renderSelectionData); + } + isValidSelection = selectionData?.IsValid() ?? false; + + // メッシュの切り取り + ct.ThrowIfCancellationRequested(); + if (renderSelectionData?.IsValid() ?? false) + { + // 余白 + float mergin = renderMesh.CalcSelectionMergin(reductionSettings); + mergin = math.max(mergin, Define.System.MinimumGridSize); + + // セレクション情報から切り取りの実行 + // ペイントマップの場合はレンダラーごとのセレクションデータで切り取り + renderMesh.SelectionMesh(renderSelectionData, clothTransformRecord.localToWorldMatrix, mergin); + if (renderMesh.IsError) + { + result.Merge(renderMesh.result); + throw new MagicaClothProcessingException(); + } + Develop.DebugLog($"(SELECTION) {renderMesh}"); + } + ct.ThrowIfCancellationRequested(); + + // レンダーメッシュの作成完了 + renderMesh.result.SetSuccess(); + + // merge -------------------------------------------------- + proxyMesh.AddMesh(renderMesh); + + // レンダーメッシュ情報を作成 + var info = new RenderMeshInfo(); + //info.mixHash = mixHash; + info.renderHandle = renderHandle; + info.renderMeshContainer = new VirtualMeshContainer(renderMesh); + //info.renderMeshPositionAndNormalChunk = renderData.renderMeshPositionAndNormalChunk; + //info.renderMeshTangentChunk = renderData.renderMeshTangentChunk; + info.renderDataWorkIndex = renderData.renderDataWorkIndex; + renderMesh = null; + renderMeshInfos.Add(info); + } + Develop.DebugLog($"(MERGE) {proxyMesh}"); + } + else if (clothType == ClothType.BoneCloth || clothType == ClothType.BoneSpring) + { + // ■BoneCloth + // import + proxyMesh.ImportFrom(boneClothSetupData, 0); + if (proxyMesh.IsError) + { + result.Merge(proxyMesh.result); + throw new MagicaClothProcessingException(); + } + Develop.DebugLog($"(IMPORT) {proxyMesh}"); + + // セレクションデータが存在しない場合は簡易作成する + if (isValidSelection == false) + { + selectionData = new SelectionData(proxyMesh, float4x4.identity); + if (selectionData.Count > 0) + { + // まずすべて移動設定 + selectionData.Fill(VertexAttribute.Move); + + // 次にルートのみ固定 + foreach (MagicaObjectId id in boneClothSetupData.rootTransformIdList) + { + int rootIndex = boneClothSetupData.GetTransformIndexFromId(id); + selectionData.attributes[rootIndex] = VertexAttribute.Fixed; + } + isValidSelection = selectionData.IsValid(); + } + } + + // Transformと属性辞書がある場合はそれに従って属性を書き換える + if (boneAttributeDict != null) + { + foreach (var kv in boneAttributeDict) + { + int index = boneClothSetupData.GetTransformIndexFromId(kv.Key); + if (index >= 0) + { + selectionData.attributes[index] = kv.Value; + } + } + } + } + + //-------------------------------------------------------------------- + // reduction (MeshClothのみ) + if (clothType == ClothType.MeshCloth && proxyMesh.VertexCount > 1) + { + ct.ThrowIfCancellationRequested(); + if (reductionSettings.IsEnabled) + { + proxyMesh.Reduction(reductionSettings, ct); + if (proxyMesh.IsError) + { + result.Merge(proxyMesh.result); + throw new MagicaClothProcessingException(); + } + + Develop.DebugLog($"(REDUCTION) {proxyMesh}"); + } + } + if (proxyMesh.joinIndices.IsCreated == false) + { + // 元の頂点から結合頂点へのインデックスを初期化 + ct.ThrowIfCancellationRequested(); + proxyMesh.joinIndices = new Unity.Collections.NativeArray(proxyMesh.VertexCount, Unity.Collections.Allocator.Persistent); + JobUtility.SerialNumberRun(proxyMesh.joinIndices, proxyMesh.VertexCount); // 連番をつける + } + + //-------------------------------------------------------------------- + // optimization + ct.ThrowIfCancellationRequested(); + proxyMesh.Optimization(); + if (proxyMesh.IsError) + { + result.Merge(proxyMesh.result); + throw new MagicaClothProcessingException(); + } + Develop.DebugLog($"(OPTIMIZE) {proxyMesh}"); + + //-------------------------------------------------------------------- + // attribute + if (isValidSelection) + { + // セレクションデータから頂点属性を付与する + proxyMesh.ApplySelectionAttribute(selectionData); + if (proxyMesh.IsError) + { + result.Merge(proxyMesh.result); + throw new MagicaClothProcessingException(); + } + } + + //-------------------------------------------------------------------- + // proxy mesh(属性決定後に実行) + ct.ThrowIfCancellationRequested(); + { + proxyMesh.ConvertProxyMesh(sdata, clothTransformRecord, customSkinningBoneRecords, normalAdjustmentTransformRecord); + if (proxyMesh.IsError) + { + result.Merge(proxyMesh.result); + throw new MagicaClothProcessingException(); + } + Develop.DebugLog($"(PROXY) {proxyMesh}"); + } + + //-------------------------------------------------------------------- + // ProxyMeshの最終チェック + if (proxyMesh.VertexCount > Define.System.MaxProxyMeshVertexCount) + { + result.SetError(Define.Result.ProxyMesh_Over32767Vertices); + throw new MagicaClothProcessingException(); + } + if (proxyMesh.EdgeCount > Define.System.MaxProxyMeshEdgeCount) + { + result.SetError(Define.Result.ProxyMesh_Over32767Edges); + throw new MagicaClothProcessingException(); + } + if (proxyMesh.TriangleCount > Define.System.MaxProxyMeshTriangleCount) + { + result.SetError(Define.Result.ProxyMesh_Over32767Triangles); + throw new MagicaClothProcessingException(); + } + + //-------------------------------------------------------------------- + // finish + ct.ThrowIfCancellationRequested(); + if (proxyMesh.IsError) + { + result.Merge(proxyMesh.result); + throw new MagicaClothProcessingException(); + } + proxyMesh.result.SetSuccess(); + Develop.DebugLog("CreateProxyMesh finish!"); + + //------------------------------------------------------------------- + // Mapping(MeshClothのみ) + if (clothType == ClothType.MeshCloth) + { + foreach (var info in renderMeshInfos) + { + ct.ThrowIfCancellationRequested(); + var cmesh = info.renderMeshContainer; + var vmesh = cmesh.shareVirtualMesh; + vmesh.Mapping(proxyMesh); + if (vmesh.IsError) + { + result.Merge(vmesh.result); + throw new MagicaClothProcessingException(); + } + Develop.DebugLog($"(MAPPING) {vmesh}"); + } + } + } + catch (MagicaClothProcessingException) + { + throw; + } + catch (OperationCanceledException) + { + throw; + } + catch (Exception exception) + { + Debug.LogException(exception); + result.SetError(Define.Result.ClothProcess_Exception); + throw; + } + finally + { + // この時点で作業用renderMeshが存在する場合は中断されているので開放する + renderMesh?.Dispose(); + } + }, ct); + + // ■メインスレッド + // 同期対象がいる場合は相手の初期化完了を待つ + ct.ThrowIfCancellationRequested(); + if (cloth == null) + throw new OperationCanceledException(); // キャンセル扱いにする + var syncCloth = cloth.SyncPartnerCloth; + if (syncCloth != null) + { + int timeOutCount = 100; + while (syncCloth != null && syncCloth.Process.IsEnable == false && timeOutCount >= 0) + { + await Task.Delay(20); + ct.ThrowIfCancellationRequested(); + timeOutCount--; + } + if (syncCloth == null || syncCloth.Process.IsEnable == false) + { + syncCloth = null; + Develop.LogWarning($"Sync timeout! Is there a deadlock between synchronous cloths?"); + } + } + Develop.DebugLog($"Sync complete : {Name}"); + + // ■メインスレッド + ct.ThrowIfCancellationRequested(); + if (cloth == null) + throw new OperationCanceledException(); // キャンセル扱いにする + if (IsValid() == false) + { + result.SetError(Define.Result.ClothProcess_Invalid); + throw new MagicaClothProcessingException(); + } + if (MagicaManager.IsPlaying() == false) + { + result.SetError(Define.Result.ClothProcess_Invalid); + throw new MagicaClothProcessingException(); + } + + // パラメータ変更フラグ + //SetState(State_ParameterDirty, true); + + // ■スレッド + ct.ThrowIfCancellationRequested(); + await Task.Run(() => + { + // ■クロスデータの作成 + try + { + // 距離制約(Distance) + ct.ThrowIfCancellationRequested(); + distanceConstraintData = DistanceConstraint.CreateData(proxyMesh, parameters); + if (distanceConstraintData != null && distanceConstraintData.result.IsError()) + { + result.Merge(distanceConstraintData.result); + throw new MagicaClothProcessingException(); + } + + // 曲げ制約(Bending) + ct.ThrowIfCancellationRequested(); + bendingConstraintData = TriangleBendingConstraint.CreateData(proxyMesh, parameters); + if (bendingConstraintData != null && bendingConstraintData.result.IsError()) + { + result.Merge(bendingConstraintData.result); + throw new MagicaClothProcessingException(); + } + + // 慣性制約(Inertia) + ct.ThrowIfCancellationRequested(); + inertiaConstraintData = InertiaConstraint.CreateData(proxyMesh, parameters); + if (inertiaConstraintData != null && inertiaConstraintData.result.IsError()) + { + result.Merge(inertiaConstraintData.result); + throw new MagicaClothProcessingException(); + } + + if (result.IsError()) + throw new MagicaClothProcessingException(); + } + catch (MagicaClothProcessingException) + { + throw; + } + catch (OperationCanceledException) + { + throw; + } + catch (Exception exception) + { + Debug.LogException(exception); + result.SetError(Define.Result.Constraint_Exception); + throw; + } + }, ct); + + + // ■メインスレッド + ct.ThrowIfCancellationRequested(); + if (cloth == null) + throw new OperationCanceledException(); // キャンセル扱いにする + + // 登録 + lock (lockObject) + { + // ProxyMesh登録 + ProxyMeshContainer = new VirtualMeshContainer(proxyMesh); + proxyMesh = 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); + } + + // 制約データ登録 + ct.ThrowIfCancellationRequested(); + MagicaManager.Simulation.RegisterConstraint(this); + + lock (lockObject) + { + // マッピングメッシュ登録 + if (clothType == ClothType.MeshCloth) + { + foreach (var info in renderMeshInfos) + { + var renderMesh = info.renderMeshContainer.shareVirtualMesh; + + if (renderMesh.IsError == false && renderMesh.IsMapping) + { + // マッピングメッシュのデータ検証 + // ここまでの時間経過でRendererが消滅しているなどの状況があり得るため + if (renderMesh.IsValid()) + { + // MappingMesh登録 + info.mappingChunk = MagicaManager.VMesh.RegisterMappingMesh( + TeamId, + info.renderMeshContainer, + info.renderDataWorkIndex + ); + } + } + } + } + + // レンダラー情報を登録 + foreach (var info in renderMeshInfos) + { + renderMeshInfoList.Add(info); + } + renderMeshInfos.Clear(); + } + ct.ThrowIfCancellationRequested(); + + // チームの有効状態の設定 + UpdateUse(); + + // ビルド完了 + result.SetSuccess(); + SetState(State_Running, true); + + Develop.DebugLog($"Build Complate : {Name}, TeamId:{TeamId}"); + } + catch (MagicaClothProcessingException) + { + if (result.IsError() == false) + result.SetError(Define.Result.ClothProcess_UnknownError); + result.DebugLog(); + } + catch (OperationCanceledException) + { + result.SetCancel(); + result.DebugLog(); + //Debug.LogWarning($"Cancel!"); + } + catch (Exception exception) + { + Debug.LogException(exception); + result.SetError(Define.Result.ClothProcess_Exception); + } + finally + { + // この時点でデータが存在する場合は失敗しているので破棄する + foreach (var info in renderMeshInfos) + { + info?.renderMeshContainer?.Dispose(); + } + proxyMesh?.Dispose(); + + // 同期対象がいる場合は相手の一時停止カウンターを減算する + if (cloth != null && cloth.SyncPartnerCloth) + { + var sync = cloth.SyncPartnerCloth; + while (sync != cloth && sync != null) + { + sync.Process.DecrementSuspendCounter(); + sync = sync.SyncPartnerCloth; + } + } + + // ビルド完了 + isBuild = false; + + // この時点でコンポーネントが削除されている場合は破棄する + if (isDestory) + { + DisposeInternal(); + //Debug.LogWarning($"Delay Dispose!"); + } + else if (cloth != null) + { + if (result.IsFaild()) + Develop.LogError($"Cloth runtime build failure! [{cloth.name}] : {result.GetResultString()}"); + + // ビルド完了イベント + cloth.OnBuildComplete?.Invoke(cloth, result.IsSuccess()); + } + } + } + + /// + /// ペイントマップからセレクションデータを構築する + /// + /// + /// + /// + /// + /// + public ResultCode GenerateSelectionDataFromPaintMap( + TransformRecord clothTransformRecord, VirtualMesh renderMesh, PaintMapData paintMapData, out SelectionData selectionData + ) + { + ResultCode result = new ResultCode(); + result.SetProcess(); + selectionData = new SelectionData(); + + try + { + // ペイントマップのチェック + if (paintMapData == null) + { + result.SetError(Define.Result.CreateCloth_PaintMapCountMismatch); + throw new MagicaClothProcessingException(); + } + + // セレクションデータバッファ作成 + int vcnt = renderMesh.VertexCount; + using var positionList = new NativeArray(vcnt, Allocator.TempJob); + using var attributeList = new NativeArray(vcnt, Allocator.TempJob); + + // レンダーメッシュのUV値からペイントマップをフェッチしてセレクションデータを作成 + // 座標はクロス空間に変換する + var toM = MathUtility.Transform(renderMesh.initLocalToWorld, clothTransformRecord.worldToLocalMatrix); + int2 xySize = new int2(paintMapData.paintMapWidth, paintMapData.paintMapHeight); + using var paintData = new NativeArray(paintMapData.paintData, Allocator.TempJob); + + // Burstにより属性マップからセレクションデータを設定 + var job = new GenerateSelectionJob() + { + offset = 0, + positionList = positionList, + attributeList = attributeList, + + attributeMapWidth = paintMapData.paintMapWidth, + toM = toM, + xySize = xySize, + attributeReadFlag = paintMapData.paintReadFlag, + attributeMapData = paintData, + + uvs = renderMesh.uv.GetNativeArray(), // レンダーメッシュインポート直後は元のメッシュuvが入っている + vertexs = renderMesh.localPositions.GetNativeArray(), + }; + job.Run(vcnt); + + // セレクションデータ設定 + selectionData.positions = positionList.ToArray(); + selectionData.attributes = attributeList.ToArray(); + // 最大距離はプロキシメッシュの座標空間に変換する + 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_InvalidPaintMap); + result.DebugLog(); + } + catch (Exception e) + { + Debug.LogException(e); + result.SetError(Define.Result.CreateCloth_InvalidPaintMap); + } + + return result; + } + + [BurstCompile] + struct GenerateSelectionJob : IJobParallelFor + { + public int offset; + [NativeDisableParallelForRestriction] + [Unity.Collections.WriteOnly] + public NativeArray positionList; + [NativeDisableParallelForRestriction] + [Unity.Collections.WriteOnly] + public NativeArray attributeList; + + public int attributeMapWidth; + public float4x4 toM; + public int2 xySize; + public ExBitFlag8 attributeReadFlag; + [Unity.Collections.ReadOnly] + public NativeArray attributeMapData; + + [Unity.Collections.ReadOnly] + public NativeArray uvs; + [Unity.Collections.ReadOnly] + public NativeArray vertexs; + + public void Execute(int vindex) + { + float2 uv = uvs[vindex]; + + // uv値を(0.0 ~ 0.99999..)範囲に変換する + uv = (uv % 1.0f) + 1.0f; + uv = uv % 1.0f; + + int2 xy = (int2)(uv * xySize); + Color32 col = attributeMapData[xy.y * attributeMapWidth + xy.x]; + + // 属性判定 + const byte border = 32; // 127 + var attr = new VertexAttribute(); + if (attributeReadFlag.IsSet(PaintMapData.ReadFlag_Move) && col.g > border) + attr.SetFlag(VertexAttribute.Flag_Move, true); + else if (attributeReadFlag.IsSet(PaintMapData.ReadFlag_Fixed) && col.r > border) + attr.SetFlag(VertexAttribute.Flag_Fixed, true); + if (attributeReadFlag.IsSet(PaintMapData.ReadFlag_Limit) && col.b <= border) + attr.SetFlag(VertexAttribute.Flag_InvalidMotion, true); // 塗りつぶしていない箇所が無効 + + // 設定 + var pos = math.transform(toM, vertexs[vindex]); // クロスコンポーネント空間に変換 + positionList[offset + vindex] = pos; + attributeList[offset + vindex] = attr; + } + } + + /// + /// ペイントマップからテクスチャデータを取得してその情報をリストで返す + /// ミップマップが存在する場合は約128x128サイズ以下のミップマップを採用する + /// この処理はメインスレッドでしか動作せず、またそれなりの負荷がかかるので注意! + /// + /// + public ResultCode GeneratePaintMapDataList(List dataList) + { + var result = new ResultCode(); + result.SetProcess(); + + try + { + int mapCount = cloth.SerializeData.paintMaps.Count; + + // テクスチャ読み込みフラグ + var readFlag = new ExBitFlag8(PaintMapData.ReadFlag_Fixed | PaintMapData.ReadFlag_Move); + if (cloth.SerializeData.paintMode == ClothSerializeData.PaintMode.Texture_Fixed_Move_Limit) + readFlag.SetFlag(PaintMapData.ReadFlag_Limit, true); + + for (int i = 0; i < mapCount; i++) + { + var paintMap = cloth.SerializeData.paintMaps[i]; + if (paintMap == null) + { + result.SetError(Define.Result.Init_InvalidPaintMap); + throw new MagicaClothProcessingException(); + } + if (paintMap.isReadable == false) + { + result.SetError(Define.Result.Init_PaintMapNotReadable); + throw new MagicaClothProcessingException(); + } + int width = paintMap.width; + int height = paintMap.height; + int pixelCount = width * height; + int mip = 1; + while (mip < paintMap.mipmapCount && pixelCount > 16384) // 128 x 128 = 16384 + { + mip++; + pixelCount /= 4; + width /= 2; + height /= 2; + } + Develop.DebugLog($"[{paintMap.name}] target mipmap:{mip - 1} ,pixelCount:{pixelCount}, w:{width}, h:{height}"); + + // ピクセルデータの取得 + // !現状CPU側から圧縮テクスチャのピクセルデータを取得するにはこの方法しかない。 + // !GetPixelData()ではRGB32/RGBA32以外のフォーマットに対応できない。 + // !この関数はメインスレッドでしか動作せず、また処理負荷もそれなりにあるので注意!(128x128で0.3msほど) + var data = new PaintMapData(); + data.paintData = paintMap.GetPixels32(mip - 1); + Develop.DebugLog($"paintMapData:{data.paintData.Length}"); + data.paintMapWidth = width; + data.paintMapHeight = height; + data.paintReadFlag = readFlag; + dataList.Add(data); + } + + result.SetSuccess(); + } + catch (MagicaClothProcessingException) + { + result.DebugLog(); + } + catch (Exception e) + { + Debug.LogException(e); + result.SetError(Define.Result.Init_InvalidPaintMap); + } + + return result; + } + + /// + /// 頂点属性データ配列からセレクションデータを構築する + /// + /// + /// + /// + /// + /// + public ResultCode GenerateSelectionDataFromVertexAttributeData( + TransformRecord clothTransformRecord, VirtualMesh renderMesh, VertexAttribute[] vertexAttributeArray, out SelectionData selectionData + ) + { + 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; + + // レンダーハンドル + MagicaObjectId 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(); + } + + //========================================================================================= + /// + /// カリング連動アニメーターとレンダラーを更新 + /// + internal void UpdateCullingAnimatorAndRenderers() + { + var cullingSettings = cloth.SerializeData.cullingSettings; + + // 連動アニメーター更新 + if (cullingSettings.cameraCullingMode == CullingSettings.CameraCullingMode.AnimatorLinkage + || cullingSettings.cameraCullingMethod == CullingSettings.CameraCullingMethod.AutomaticRenderer + || cloth.SerializeData.updateMode == ClothUpdateMode.AnimatorLinkage) + { + interlockingAnimator = cloth.GetComponentInParent(); + } + + // 連動レンダラー更新 + if (cullingSettings.cameraCullingMethod == CullingSettings.CameraCullingMethod.AutomaticRenderer && interlockingAnimator) + { + // ★GetComponentsInChildrenのコストはキャラクタ100体で1msほど。 + // ★もしコストが問題となるようならばキャッシュする + interlockingAnimatorRenderers.Clear(); + interlockingAnimator.GetComponentsInChildren(interlockingAnimatorRenderers); + } + } + + /// + /// 保持しているレンダーデータに対して更新を指示する + /// + internal void UpdateRendererUse() + { + // 対応するレンダーデータに更新を指示する + renderHandleList.ForEach(handle => MagicaManager.Render.GetRendererData(handle).UpdateUse(this, 0)); + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/Cloth/ClothProcess.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Cloth/ClothProcess.cs.meta new file mode 100644 index 00000000..104f41c6 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Cloth/ClothProcess.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 704c6153c380ba94f8548d02490cfaf6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Cloth/ClothProcess.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Cloth/ClothProcessData.cs b/Assets/MagicaCloth2/Scripts/Core/Cloth/ClothProcessData.cs new file mode 100644 index 00000000..eb6a2239 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Cloth/ClothProcessData.cs @@ -0,0 +1,509 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using System; +using System.Collections.Generic; +using System.Threading; +using Unity.Collections; +using Unity.Mathematics; +using UnityEngine; + +namespace MagicaCloth2 +{ + /// + /// MagicaClothコンポーネント処理のデータ部分 + /// + public partial class ClothProcess : IDisposable, IValid, ITransform + { + 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_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; // 検証結果による有効状態 + + /// + /// 現在の状態 + /// + internal BitField32 stateFlag; + + /// + /// 初期クロスコンポーネントトランスフォーム状態 + /// + internal TransformRecord clothTransformRecord { get; private set; } = null; + + /// + /// レンダー情報へのハンドル + /// (レンダラーのセットアップデータ) + /// + internal List renderHandleList = new List(); + + /// + /// BoneClothのセットアップデータ + /// + internal RenderSetupData boneClothSetupData; + + /// + /// レンダーメッシュの管理 + /// + public class RenderMeshInfo + { + public MagicaObjectId renderHandle; + public VirtualMeshContainer renderMeshContainer; + public DataChunk mappingChunk; + //public DataChunk renderMeshPositionAndNormalChunk; + //public DataChunk renderMeshTangentChunk; + public int renderDataWorkIndex; + } + internal List renderMeshInfoList = new List(); + + /// + /// カスタムスキニングのボーン情報 + /// + internal List customSkinningBoneRecords = new List(); + + /// + /// 法線調整用のトランスフォーム状態 + /// + internal TransformRecord normalAdjustmentTransformRecord { get; private set; } = null; + + //========================================================================================= + /// + /// ペイントマップ情報 + /// + public class PaintMapData + { + public const byte ReadFlag_Fixed = 0x01; + public const byte ReadFlag_Move = 0x02; + public const byte ReadFlag_Limit = 0x04; + + public Color32[] paintData; + public int paintMapWidth; + public int paintMapHeight; + public ExBitFlag8 paintReadFlag; + } + + //========================================================================================= + /// + /// 処理結果 + /// + internal ResultCode result; + public ResultCode Result => result; + + /// + /// 初期化データ参照結果 + /// + public ResultCode InitDataResult { get; internal set; } + + /// + /// Cloth Type + /// + public enum ClothType + { + MeshCloth = 0, + BoneCloth = 1, + BoneSpring = 10, + } + internal ClothType clothType { get; private set; } + + /// + /// リダクション設定(外部から設定する) + /// + ReductionSettings reductionSettings; + + /// + /// シミュレーションパラメータ + /// + public ClothParameters parameters { get; private set; } + + /// + /// プロキシメッシュ + /// + public VirtualMeshContainer ProxyMeshContainer { get; private set; } = null; + + /// + /// 登録中のコライダー + /// int2 (メインコライダー・ローカルインデックス, シンメトリーコライダー・ローカルインデックス) + /// メインコライダーのインデックス0はあり得る + /// シンメトリーコライダーのインデックス0はシンメトリーが存在しないことを示す + /// + internal Dictionary colliderDict = new Dictionary(); + + //========================================================================================= + /// + /// チームID + /// + public int TeamId { get; private set; } = 0; + + /// + /// 慣性制約データ + /// + internal InertiaConstraint.ConstraintData inertiaConstraintData; + + /// + /// 距離制約データ + /// + internal DistanceConstraint.ConstraintData distanceConstraintData; + + /// + /// 曲げ制約データ + /// + internal TriangleBendingConstraint.ConstraintData bendingConstraintData; + + //========================================================================================= + /// + /// 連動アニメーター + /// ・カリング + /// ・更新モード + /// + internal Animator interlockingAnimator = null; + + /// + /// カリング用アニメーター配下のレンダラーリスト + /// + internal List interlockingAnimatorRenderers = new List(); + + /// + /// 現在アンカーとして設定されているTransformのインスタンスID + /// + internal MagicaObjectId anchorTransformId = MagicaObjectId.Invalid; + + /// + /// 現在距離カリングの参照として設定されているオブジェクトのインスタンスID + /// + internal MagicaObjectId distanceReferenceObjectId = MagicaObjectId.Invalid; + + /// + /// コンポーネントの登録TransformIndex + /// tdata.componentTransformIndexのコピー + /// + //internal int componentTransformIndex = 0; + + internal Animator cameraCullingAnimator = null; + internal List cameraCullingRenderers = null; + internal CullingSettings.CameraCullingMode cameraCullingMode; + internal bool cameraCullingOldInvisible = false; + + //========================================================================================= + /// + /// キャンセルトークン + /// + CancellationTokenSource cts = new CancellationTokenSource(); + volatile object lockObject = new object(); + //volatile object lockState = new object(); + + /// + /// 初期化待機カウンター + /// + //volatile int suspendCounter = 0; + + /// + /// 破棄フラグ + /// + volatile bool isDestory = false; + + /// + /// 内部データまで完全に破棄されたかどうか + /// + volatile bool isDestoryInternal = false; + + /// + /// 構築中フラグ + /// + volatile bool isBuild = false; + + public BitField32 GetStateFlag() + { + //lock (lockState) + { + // copy + var state = stateFlag; + return state; + } + } + + public bool IsState(int state) + { + //lock (lockState) + { + return stateFlag.IsSet(state); + } + } + + public void SetState(int state, bool sw) + { + //lock (lockState) + { + stateFlag.SetBits(state, sw); + } + } + + public bool IsValid() => IsState(State_Valid); + 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 + { + get + { + if (IsValid() == false || TeamId == 0) + return false; + return MagicaManager.Team.IsEnable(TeamId); + } + } + + public bool HasProxyMesh + { + get + { + if (IsValid() == false || TeamId == 0) + return false; + return ProxyMeshContainer?.shareVirtualMesh?.IsSuccess ?? false; + } + } + + public string Name => cloth != null ? cloth.name : "(none)"; + + //========================================================================================= + public ClothProcess() + { + // 初期状態 + result = ResultCode.Empty; + } + + public void Dispose() + { + lock (lockObject) + { + isDestory = true; + SetState(State_Valid, false); + result.Clear(); + cts.Cancel(); + } + + DisposeInternal(); + //Debug.Log($"ClothProcessData.Dispose()!"); + } + + void DisposeInternal() + { + lock (lockObject) + { + // すでに破棄完了ならば不要 + if (isDestoryInternal) + return; + + // ビルド中は破棄を保留する + if (isBuild) + return; + + // マネージャから削除 + MagicaManager.Simulation?.ExitProxyMesh(this); + MagicaManager.VMesh?.ExitProxyMesh(TeamId); // マッピングメッシュも解放される + MagicaManager.Collider?.Exit(this); + MagicaManager.Cloth?.RemoveCloth(this); + + // レンダーメッシュの破棄 + foreach (var info in renderMeshInfoList) + { + if (info == null) + continue; + + // 仮想メッシュ破棄 + info.renderMeshContainer?.Dispose(); + } + renderMeshInfoList.Clear(); + renderMeshInfoList = null; + + // レンダーデータの利用終了 + foreach (MagicaObjectId renderHandle in renderHandleList) + { + MagicaManager.Render?.RemoveRenderer(renderHandle); + } + renderHandleList.Clear(); + renderHandleList = null; + + // BoneClothセットアップデータ + boneClothSetupData?.Dispose(); + boneClothSetupData = null; + + // プロキシメッシュ破棄 + ProxyMeshContainer?.Dispose(); + ProxyMeshContainer = null; + + colliderDict.Clear(); + + interlockingAnimator = null; + interlockingAnimatorRenderers.Clear(); + + // PreBuildデータ解除 + MagicaManager.PreBuild?.UnregisterPreBuildData(cloth != null ? cloth.GetSerializeData2()?.preBuildData.GetSharePreBuildData() : null); + + // 作業バッファ破棄 + SyncTopCloth = null; + MagicaObjectId compId = cloth.GetMagicaId(); + MagicaManager.Team?.comp2SuspendCounterMap.Remove(compId); + MagicaManager.Team?.comp2TeamIdMap.Remove(compId); + MagicaManager.Team?.comp2SyncPartnerCompMap.Remove(compId); + MagicaManager.Team?.comp2SyncTopCompMap.Remove(compId); + + // 完全破棄フラグ + isDestoryInternal = true; + } + Develop.DebugLog($"Cloth dispose internal."); + + // 破棄監視リストから削除する + MagicaManager.Team?.RemoveMonitoringProcess(this); + } + + internal void IncrementSuspendCounter() + { + //suspendCounter++; + var tm = MagicaManager.Team; + MagicaObjectId compId = cloth.GetMagicaId(); + if (tm.comp2SuspendCounterMap.TryGetValue(compId, out int cnt)) + { + cnt++; + //tm.comp2SuspendCounterMap.Add(compId, cnt); + tm.comp2SuspendCounterMap[compId] = cnt; + } + else + tm.comp2SuspendCounterMap.Add(compId, 1); + } + + internal void DecrementSuspendCounter() + { + //suspendCounter--; + var tm = MagicaManager.Team; + MagicaObjectId compId = cloth.GetMagicaId(); + if (tm.comp2SuspendCounterMap.TryGetValue(compId, out int cnt)) + { + cnt--; + if (cnt > 0) + tm.comp2SuspendCounterMap[compId] = cnt; + else + tm.comp2SuspendCounterMap.Remove(compId); + } + } + + internal int GetSuspendCounter() + { + //return suspendCounter; + var tm = MagicaManager.Team; + MagicaObjectId compId = cloth.GetMagicaId(); + if (tm.comp2SuspendCounterMap.TryGetValue(compId, out int cnt)) + return cnt; + else + return 0; + } + + public RenderMeshInfo GetRenderMeshInfo(int index) + { + if (index >= 0 && index < renderMeshInfoList.Count) + return renderMeshInfoList[index]; + else + return null; + } + + internal void SyncParameters() + { + parameters = cloth.SerializeData.GetClothParameters(); + } + + 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)); + customSkinningBoneRecords.ForEach(rd => rd.ReplaceTransform(replaceDict)); + normalAdjustmentTransformRecord?.ReplaceTransform(replaceDict); + } + + internal void SetSkipWriting(bool sw) + { + // ここではフラグのみ更新する + // 実際の更新はチームのAlwaysTeamUpdate()で行われる + SetState(State_SkipWriting, sw); + //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/MagicaCloth2/Scripts/Core/Cloth/ClothProcessData.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Cloth/ClothProcessData.cs.meta new file mode 100644 index 00000000..25630786 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Cloth/ClothProcessData.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: cd76571c8c560a348bedf4b213ae34c2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Cloth/ClothProcessData.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Cloth/ClothProcessGeneration.cs b/Assets/MagicaCloth2/Scripts/Core/Cloth/ClothProcessGeneration.cs new file mode 100644 index 00000000..6533e44c --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Cloth/ClothProcessGeneration.cs @@ -0,0 +1,120 @@ +// 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(); + + // シリアライズデータ(1)の検証 + if (cloth.SerializeData.IsValid() == false) + { + if (cloth.SerializeData.VerificationResult == Define.Result.Empty) + result.SetError(Define.Result.CreateCloth_InvalidSerializeData); + else + result.SetError(cloth.SerializeData.VerificationResult); + return false; + } + cloth.SerializeData.DataValidate(); + cloth.serializeData2.DataValidate(); + + // 初期化実行 + Init(); + if (result.IsError()) + return false; + + return true; + } + + internal bool GenerateBoneClothSelection() + { + // セレクションデータの構築 + var setupData = boneClothSetupData; + int tcnt = setupData.skinBoneCount; // パーティクルトランスフォーム総数 + var selectionData = new SelectionData(tcnt); + for (int i = 0; i < tcnt; i++) + { + float3 lpos = math.transform(setupData.initRenderWorldtoLocal, setupData.transformPositions[i]); + selectionData.positions[i] = lpos; + selectionData.attributes[i] = VertexAttribute.Move; // 移動で初期化 + } + + // 最大接続距離 + float maxLength = 0; + for (int i = 0; i < tcnt; i++) + { + int pi = setupData.GetParentTransformIndex(i, true); + if (pi >= 0) + { + float length = math.distance(selectionData.positions[i], selectionData.positions[pi]); + maxLength = math.max(maxLength, length); + } + } + selectionData.maxConnectionDistance = maxLength; + + // ルートを固定に設定 + foreach (var rt in cloth.SerializeData.rootBones) + { + if (rt) + { + int index = setupData.GetTransformIndexFromId(rt.GetMagicaId()); + selectionData.attributes[index] = VertexAttribute.Fixed; + } + } + + selectionData.userEdit = true; // 念のため + cloth.GetSerializeData2().selectionData = selectionData; + + return true; + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/Cloth/ClothProcessGeneration.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Cloth/ClothProcessGeneration.cs.meta new file mode 100644 index 00000000..eca99bf7 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Cloth/ClothProcessGeneration.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 31501f387a912624eb66d16ddab79f29 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Cloth/ClothProcessGeneration.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Cloth/ClothSerializeData.cs b/Assets/MagicaCloth2/Scripts/Core/Cloth/ClothSerializeData.cs new file mode 100644 index 00000000..1d8cf9ad --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Cloth/ClothSerializeData.cs @@ -0,0 +1,278 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using System.Collections.Generic; +using Unity.Mathematics; +using UnityEngine; + +namespace MagicaCloth2 +{ + /// + /// Serialize data (1) + /// Contains all parameters that can be changed during execution. + /// The part that can be exported externally as Json. + /// + [System.Serializable] + public partial class ClothSerializeData + { + /// + /// simulation type. + /// [NG] Runtime changes. + /// [NG] Export/Import with Presets + /// + public ClothProcess.ClothType clothType = ClothProcess.ClothType.MeshCloth; + + /// + /// Renderer list used in MeshCloth. + /// [NG] Runtime changes. + /// [NG] Export/Import with Presets + /// + 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, + + [InspectorName("Texture Fixed(RD) Move(GR) Ignore(BK)")] + Texture_Fixed_Move = 1, + + [InspectorName("Texture Fixed(RD) Move(GR) Limit(BL) Ignore(BK)")] + Texture_Fixed_Move_Limit = 2, + } + + /// + /// vertex paint mode. + /// [NG] Runtime changes. + /// [NG] Export/Import with Presets + /// + public PaintMode paintMode = PaintMode.Manual; + + /// + /// texture for painting. + /// Sync to sourceRenderers. + /// [NG] Runtime changes. + /// [NG] Export/Import with Presets + /// + 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. + /// [NG] Export/Import with Presets + /// + public List rootBones = new List(); + + /// + /// BoneCloth connection method. + /// [NG] Runtime changes. + /// [NG] Export/Import with Presets + /// + public RenderSetupData.BoneConnectionMode connectionMode = RenderSetupData.BoneConnectionMode.Line; + + /// + /// Transform rotation interpolation rate in BoneCloth.(0.0 ~ 1.0) + /// (0.0=parent-based, 0.5=middle, 1.0=child-based) + /// [OK] Runtime changes. + /// [NG] Export/Import with Presets + /// + [Range(0.0f, 1.0f)] + public float rotationalInterpolation = 0.5f; + + /// + /// Rotation interpolation rate of Root Transform in BoneCloth.(0.0 ~ 1.0) + /// (0.0=does not rotate, 0.5=middle, 1.0=child-based) + /// [OK] Runtime changes. + /// [NG] Export/Import with Presets + /// + [Range(0.0f, 1.0f)] + public float rootRotation = 0.5f; + + /// + /// Set the update timing. + /// [OK] Runtime changes. + /// [NG] Export/Import with Presets + /// + public ClothUpdateMode updateMode = ClothUpdateMode.AnimatorLinkage; + + /// + /// Set the disable mode. + /// Component inactive behavior. + /// [OK] Runtime changes. + /// [NG] Export/Import with Presets + /// + public ClothDisableMode disableMode = ClothDisableMode.Reset; + + /// + /// Blend ratio between initial pose and animation pose. + /// [OK] Runtime changes. + /// [NG] Export/Import with Presets + /// + [Range(0.0f, 1.0f)] + public float animationPoseRatio = 0.0f; + + /// + /// vertex reduction parameters. + /// + public ReductionSettings reductionSetting = new ReductionSettings(); + + /// + /// custom skinning parameters. + /// + public CustomSkinningSettings customSkinningSetting = new CustomSkinningSettings(); + + /// + /// Normal definition. + /// + public NormalAlignmentSettings normalAlignmentSetting = new NormalAlignmentSettings(); + + /// + /// culling settings. + /// + public CullingSettings cullingSettings = new CullingSettings(); + + /// + /// axis to use as normal. + /// [OK] Runtime changes. + /// [NG] Export/Import with Presets + /// + public ClothNormalAxis normalAxis = ClothNormalAxis.Up; + + /// + /// Gravity. + /// [OK] Runtime changes. + /// [OK] Export/Import with Presets + /// + [Range(0.0f, 10.0f)] + public float gravity = 5.0f; + + /// + /// Gravity world direction. + /// [OK] Runtime changes. + /// [OK] Export/Import with Presets + /// + public float3 gravityDirection = new float3(0, -1, 0); + + /// + /// 初期姿勢での重力の減衰率(0.0 ~ 1.0) + /// 1.0にすることで初期姿勢では重力係数が0になる。 + /// 0.0では常にどの姿勢でも重力が100%発生する。 + /// + /// Attenuation rate of gravity at initial pose (0.0 ~ 1.0) + /// By setting it to 1.0, the gravity coefficient becomes 0 in the initial posture. + /// At 0.0, gravity is always 100% in any pose. + /// + /// [OK] Runtime changes. + /// [OK] Export/Import with Presets + /// + [Range(0.0f, 1.0f)] + public float gravityFalloff = 0.0f; + + /// + /// リセット後の速度安定化時間(s) + /// 急激な速度変化を抑えます。 + /// + /// Speed stabilization time after reset (s). + /// Avoid sudden speed changes. + /// + /// [OK] Runtime changes. + /// [NG] Export/Import with Presets + /// + [Range(0.0f, 1.0f)] + public float stablizationTimeAfterReset = 0.1f; + + /// + /// 元の姿勢とシミュレーション結果のブレンド割合(0.0 ~ 1.0) + /// + /// Blend ratio of original posture and simulation result (0.0 ~ 1.0). + /// + /// [OK] Runtime changes. + /// [NG] Export/Import with Presets + /// + [Range(0.0f, 1.0f)] + public float blendWeight = 1.0f; + + /// + /// air resistance. + /// [OK] Runtime changes. + /// [OK] Export/Import with Presets + /// + public CurveSerializeData damping = new CurveSerializeData(0.05f); + + /// + /// Particle radius. + /// [OK] Runtime changes. + /// [OK] Export/Import with Presets + /// + public CurveSerializeData radius = new CurveSerializeData(0.02f); + + /// + /// Inertia. + /// + public InertiaConstraint.SerializeData inertiaConstraint = new InertiaConstraint.SerializeData(); + + /// + /// Tether. + /// + public TetherConstraint.SerializeData tetherConstraint = new TetherConstraint.SerializeData(); + + /// + /// Distance restoration. + /// + public DistanceConstraint.SerializeData distanceConstraint = new DistanceConstraint.SerializeData(); + + /// + /// Triangle bending / volume. + /// + public TriangleBendingConstraint.SerializeData triangleBendingConstraint = new TriangleBendingConstraint.SerializeData(); + + /// + /// Angle restoration. + /// + public AngleConstraint.RestorationSerializeData angleRestorationConstraint = new AngleConstraint.RestorationSerializeData(); + + /// + /// Angle Limit. + /// + public AngleConstraint.LimitSerializeData angleLimitConstraint = new AngleConstraint.LimitSerializeData(); + + /// + /// Max distance / Backstop + /// + public MotionConstraint.SerializeData motionConstraint = new MotionConstraint.SerializeData(); + + /// + /// Collider collision. + /// + public ColliderCollisionConstraint.SerializeData colliderCollisionConstraint = new ColliderCollisionConstraint.SerializeData(); + + /// + /// Self collision + /// + public SelfCollisionConstraint.SerializeData selfCollisionConstraint = new SelfCollisionConstraint.SerializeData(); + + /// + /// Wind + /// + public WindSettings wind = new WindSettings(); + + /// + /// Spring + /// + public SpringConstraint.SerializeData springConstraint = new SpringConstraint.SerializeData(); + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/Cloth/ClothSerializeData.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Cloth/ClothSerializeData.cs.meta new file mode 100644 index 00000000..15d8d5fe --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Cloth/ClothSerializeData.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: ffd56578b2bf3574b91062060c05a6c2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Cloth/ClothSerializeData.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Cloth/ClothSerializeData2.cs b/Assets/MagicaCloth2/Scripts/Core/Cloth/ClothSerializeData2.cs new file mode 100644 index 00000000..9fec43e0 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Cloth/ClothSerializeData2.cs @@ -0,0 +1,94 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using System.Collections.Generic; +using UnityEngine; + +namespace MagicaCloth2 +{ + /// + /// Serialize data (2) + /// Parts that cannot be exported externally. + /// + [System.Serializable] + public class ClothSerializeData2 : IDataValidate, IValid, ITransform + { + /// + /// Initialization Data. + /// + [SerializeField] + public ClothInitSerializeData initData = new ClothInitSerializeData(); + + /// + /// 頂点ペイントデータ + /// vertex paint data. + /// + [SerializeField] + public SelectionData selectionData = new SelectionData(); + + /// + /// Transformと頂点属性辞書データ + /// 実行時でのBoneCloth/BoneSpring作成時にはこの辞書にTransformと頂点属性のペアを格納することで頂点ペイントデータの代わりにすることができます。 + /// 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() + { + } + + /// + /// クロスを構築するための最低限の情報が揃っているかチェックする + /// Check if you have the minimum information to construct the cloth. + /// + /// + public bool IsValid() + { + return true; + } + + public void DataValidate() + { + } + + /// + /// エディタメッシュの更新を判定するためのハッシュコード + /// Hashcode for determining editor mesh updates. + /// + /// + public override int GetHashCode() + { + 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/MagicaCloth2/Scripts/Core/Cloth/ClothSerializeData2.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Cloth/ClothSerializeData2.cs.meta new file mode 100644 index 00000000..b1d233e1 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Cloth/ClothSerializeData2.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 02e311e7737a90a43a9a3d615e6b436e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Cloth/ClothSerializeData2.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Cloth/ClothSerializeDataFunction.cs b/Assets/MagicaCloth2/Scripts/Core/Cloth/ClothSerializeDataFunction.cs new file mode 100644 index 00000000..14484f5e --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Cloth/ClothSerializeDataFunction.cs @@ -0,0 +1,448 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using System; +using System.Collections.Generic; +using System.Linq; +using Unity.Mathematics; +using UnityEngine; + +namespace MagicaCloth2 +{ + /// + /// Serialize data (1) + /// function part. + /// + public partial class ClothSerializeData : IDataValidate, IValid, ITransform + { + /// + /// 検証結果 + /// Verification Results. + /// + ResultCode verificationResult; + public Define.Result VerificationResult => verificationResult.Result; + + + public ClothSerializeData() + { + } + + /// + /// クロスを構築するための最低限の情報が揃っているか検証する + /// Check if you have the minimum information to construct the cloth. + /// + /// + public bool IsValid() + { + verificationResult.SetResult(Define.Result.Empty); // 空データ + + switch (clothType) + { + case ClothProcess.ClothType.BoneCloth: + case ClothProcess.ClothType.BoneSpring: + if (rootBones == null || rootBones.Count == 0) + 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) + return false; + if (sourceRenderers.Count(x => x != null) == 0) + return false; + + // レンダラーの最大数 + if (sourceRenderers.Count > Define.System.MaxRendererCount) + { + 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; + } + + verificationResult.SetSuccess(); + return true; + } + + public void DataValidate() + { + rotationalInterpolation = Mathf.Clamp01(rotationalInterpolation); + rootRotation = Mathf.Clamp01(rootRotation); + animationPoseRatio = Mathf.Clamp01(animationPoseRatio); + + reductionSetting.DataValidate(); + customSkinningSetting.DataValidate(); + normalAlignmentSetting.DataValidate(); + cullingSettings.DataValidate(); + + gravity = Mathf.Clamp(gravity, 0.0f, 20.0f); + if (math.length(gravityDirection) > Define.System.Epsilon) + gravityDirection = math.normalize(gravityDirection); + else + gravityDirection = 0; + gravityFalloff = Mathf.Clamp01(gravityFalloff); + stablizationTimeAfterReset = Mathf.Clamp01(stablizationTimeAfterReset); + blendWeight = Mathf.Clamp01(blendWeight); + + damping.DataValidate(0.0f, 1.0f); + radius.DataValidate(0.001f, 1.0f); + inertiaConstraint.DataValidate(); + tetherConstraint.DataValidate(); + distanceConstraint.DataValidate(); + triangleBendingConstraint.DataValidate(); + angleRestorationConstraint.DataValidate(); + angleLimitConstraint.DataValidate(); + motionConstraint.DataValidate(); + colliderCollisionConstraint.DataValidate(); + selfCollisionConstraint.DataValidate(); + wind.DataValidate(); + } + + /// + /// エディタメッシュの更新を判定するためのハッシュコード + /// Hashcode for determining editor mesh updates. + /// + /// + public override int GetHashCode() + { + const int NullHash = -3910836; + + int hash = 0; + hash += (int)clothType; + foreach (var ren in sourceRenderers) + hash += ren != null ? ren.GetMagicaId().GetHashCode() : NullHash; + foreach (var t in rootBones) + { + var stack = new Stack(30); + stack.Push(t); + while (stack.Count > 0) + { + var t2 = stack.Pop(); + if (t2 == null) + { + hash += NullHash; + continue; + } + hash += t2.GetMagicaId().GetHashCode(); + hash += t2.localPosition.GetHashCode(); + hash += t2.localRotation.GetHashCode(); + int cnt = t2.childCount; + for (int i = 0; i < cnt; i++) + stack.Push(t2.GetChild(i)); + } + } + hash += (int)connectionMode * 10; + hash += reductionSetting.GetHashCode(); + hash += customSkinningSetting.GetHashCode(); + hash += normalAlignmentSetting.GetHashCode(); + hash += cullingSettings.GetHashCode(); + hash += (int)paintMode; + foreach (var map in paintMaps) + { + if (map) + { + hash += map.GetMagicaId().GetHashCode(); + hash += map.isReadable ? 1 : 0; + } + } + hash += paintMapUvChannel * 123; + hash += colliderCollisionConstraint.GetHashCode(); + + return hash; + } + + /// + /// ジョブで参照する構造体に変換して返す + /// Convert to a structure to be referenced in the job and return. + /// + /// + public ClothParameters GetClothParameters() + { + var cparams = new ClothParameters(); + + //cparams.solverFrequency = Define.System.SolverFrequency; + cparams.gravity = clothType == ClothProcess.ClothType.BoneSpring ? 0.0f : gravity; // BoneSpring has no gravity. + cparams.worldGravityDirection = gravityDirection; + cparams.gravityFalloff = gravityFalloff; + cparams.stablizationTimeAfterReset = stablizationTimeAfterReset; + cparams.blendWeight = blendWeight; + cparams.dampingCurveData = damping.ConvertFloatArray() * 0.2f; // 20% + cparams.radiusCurveData = radius.ConvertFloatArray(); + cparams.normalAxis = normalAxis; + + cparams.rotationalInterpolation = rotationalInterpolation; + cparams.rootRotation = rootRotation; + + cparams.culling.Convert(cullingSettings); + cparams.inertiaConstraint.Convert(inertiaConstraint); + cparams.tetherConstraint.Convert(tetherConstraint, clothType); + cparams.distanceConstraint.Convert(distanceConstraint, clothType); + cparams.triangleBendingConstraint.Convert(triangleBendingConstraint); + cparams.angleConstraint.Convert(angleRestorationConstraint, angleLimitConstraint); + cparams.motionConstraint.Convert(motionConstraint, clothType); + cparams.colliderCollisionConstraint.Convert(colliderCollisionConstraint, clothType); + cparams.selfCollisionConstraint.Convert(selfCollisionConstraint, clothType); + cparams.wind.Convert(wind, clothType); + cparams.springConstraint.Convert(springConstraint, clothType); + + return cparams; + } + + class TempBuffer + { + ClothProcess.ClothType clothType; + List sourceRenderers; + ClothMeshWriteMode meshWriteMode; + PaintMode paintMode; + List paintMaps; + int paintMapUvChannel; + List rootBones; + RenderSetupData.BoneConnectionMode connectionMode; + float rotationalInterpolation; + float rootRotation; + ClothUpdateMode updateMode; + ClothDisableMode disableMode; + float animationPoseRatio; + ReductionSettings reductionSetting; + CustomSkinningSettings customSkinningSetting; + NormalAlignmentSettings normalAlignmentSetting; + ClothNormalAxis normalAxis; + List colliderList; + List collisionBones; + MagicaCloth synchronization; + float stablizationTimeAfterReset; + float blendWeight; + CullingSettings cullingSetting; + Transform anchor; + float anchorInertia; + + internal TempBuffer(ClothSerializeData sdata) + { + Push(sdata); + } + + internal void Push(ClothSerializeData sdata) + { + 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; + rootRotation = sdata.rootRotation; + updateMode = sdata.updateMode; + disableMode = sdata.disableMode; + animationPoseRatio = sdata.animationPoseRatio; + reductionSetting = sdata.reductionSetting.Clone(); + customSkinningSetting = sdata.customSkinningSetting.Clone(); + normalAlignmentSetting = sdata.normalAlignmentSetting.Clone(); + normalAxis = sdata.normalAxis; + colliderList = new List(sdata.colliderCollisionConstraint.colliderList); + collisionBones = new List(sdata.colliderCollisionConstraint.collisionBones); + synchronization = sdata.selfCollisionConstraint.syncPartner; + stablizationTimeAfterReset = sdata.stablizationTimeAfterReset; + blendWeight = sdata.blendWeight; + 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; + sdata.rootRotation = rootRotation; + sdata.updateMode = updateMode; + sdata.disableMode = disableMode; + sdata.animationPoseRatio = animationPoseRatio; + sdata.reductionSetting = reductionSetting; + sdata.customSkinningSetting = customSkinningSetting; + sdata.normalAlignmentSetting = normalAlignmentSetting; + sdata.normalAxis = normalAxis; + sdata.colliderCollisionConstraint.colliderList = colliderList; + sdata.colliderCollisionConstraint.collisionBones = collisionBones; + sdata.selfCollisionConstraint.syncPartner = synchronization; + sdata.stablizationTimeAfterReset = stablizationTimeAfterReset; + sdata.blendWeight = blendWeight; + sdata.cullingSettings = cullingSetting; + sdata.inertiaConstraint.anchor = anchor; + sdata.inertiaConstraint.anchorInertia = anchorInertia; + } + } + + /// + /// パラメータをJsonへエクスポートする + /// Export parameters to Json. + /// + /// + public string ExportJson() + { + return JsonUtility.ToJson(this); + } + + /// + /// パラメータをJsonからインポートする + /// Parameterブロックの値型のみがインポートされる + /// Import parameters from Json. + /// Only value types of Parameter blocks are imported. + /// + /// + /// + public bool ImportJson(string json) + { + try + { + // 上書きしないプロパティを保持 + var temp = new TempBuffer(this); + + // Import + JsonUtility.FromJsonOverwrite(json, this); + + // 上書きしないプロパティを書き戻し + temp.Pop(this); + + // 検証 + DataValidate(); + + return true; + } + catch (Exception e) + { + Debug.LogException(e); + return false; + } + } + + /// + /// 別のシリアライズデータからインポートする + /// Import from another serialized data. + /// + /// + /// true = Copy all, false = parameter only + public void Import(ClothSerializeData sdata, bool deepCopy = false) + { + TempBuffer temp = deepCopy ? null : new TempBuffer(this); + + if (deepCopy) + { + clothType = sdata.clothType; + 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; + rootRotation = sdata.rootRotation; + updateMode = sdata.updateMode; + disableMode = sdata.disableMode; + animationPoseRatio = sdata.animationPoseRatio; + reductionSetting = sdata.reductionSetting.Clone(); + customSkinningSetting = sdata.customSkinningSetting.Clone(); + normalAlignmentSetting = sdata.normalAlignmentSetting.Clone(); + normalAxis = sdata.normalAxis; + stablizationTimeAfterReset = sdata.stablizationTimeAfterReset; + blendWeight = sdata.blendWeight; + cullingSettings = sdata.cullingSettings.Clone(); + } + + // parameters + gravity = sdata.gravity; + gravityDirection = sdata.gravityDirection; + gravityFalloff = sdata.gravityFalloff; + damping = sdata.damping.Clone(); + radius = sdata.radius.Clone(); + inertiaConstraint = sdata.inertiaConstraint.Clone(); + tetherConstraint = sdata.tetherConstraint.Clone(); + distanceConstraint = sdata.distanceConstraint.Clone(); + triangleBendingConstraint = sdata.triangleBendingConstraint.Clone(); + angleRestorationConstraint = sdata.angleRestorationConstraint.Clone(); + angleLimitConstraint = sdata.angleLimitConstraint.Clone(); + motionConstraint = sdata.motionConstraint.Clone(); + colliderCollisionConstraint = sdata.colliderCollisionConstraint.Clone(); + selfCollisionConstraint = sdata.selfCollisionConstraint.Clone(); + wind = sdata.wind.Clone(); + + if (deepCopy == false) + temp.Pop(this); + } + + /// + /// 別のクロスコンポーネントからインポートする + /// Import from another cloth component. + /// + /// + /// + public void Import(MagicaCloth src, bool deepCopy = false) + { + Import(src.SerializeData, deepCopy); + } + + public void GetUsedTransform(HashSet transformSet) + { + foreach (var t in rootBones) + { + if (t) + transformSet.Add(t); + } + customSkinningSetting.GetUsedTransform(transformSet); + normalAlignmentSetting.GetUsedTransform(transformSet); + colliderCollisionConstraint.GetUsedTransform(transformSet); + } + + public void ReplaceTransform(Dictionary replaceDict) + { + for (int i = 0; i < rootBones.Count; i++) + { + var t = rootBones[i]; + if (t && replaceDict.ContainsKey(t.GetMagicaId())) + { + rootBones[i] = replaceDict[t.GetMagicaId()]; + } + } + customSkinningSetting.ReplaceTransform(replaceDict); + normalAlignmentSetting.ReplaceTransform(replaceDict); + colliderCollisionConstraint.ReplaceTransform(replaceDict); + } + + /// + /// BoneSpring判定 + /// + /// + 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/MagicaCloth2/Scripts/Core/Cloth/ClothSerializeDataFunction.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Cloth/ClothSerializeDataFunction.cs.meta new file mode 100644 index 00000000..6b2cfa22 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Cloth/ClothSerializeDataFunction.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 8ef74f0c0b959154991c96c397b2ad52 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Cloth/ClothSerializeDataFunction.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Cloth/ClothUpdateMode.cs b/Assets/MagicaCloth2/Scripts/Core/Cloth/ClothUpdateMode.cs new file mode 100644 index 00000000..111d9366 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Cloth/ClothUpdateMode.cs @@ -0,0 +1,36 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp + +namespace MagicaCloth2 +{ + /// + /// Simulation Update Mode + /// + public enum ClothUpdateMode + { + /// + /// This mode assumes that normal Update() will perform the move and animation. + /// + Normal = 0, + + /// + /// This mode assumes that FixedUpdate() is used to perform movement and animation. + /// + UnityPhysics = 1, + + /// + /// 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/MagicaCloth2/Scripts/Core/Cloth/ClothUpdateMode.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Cloth/ClothUpdateMode.cs.meta new file mode 100644 index 00000000..ad0880e7 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Cloth/ClothUpdateMode.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 1377357dedc9a3344b49a8aa397d220d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Cloth/ClothUpdateMode.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Cloth/Collider.meta b/Assets/MagicaCloth2/Scripts/Core/Cloth/Collider.meta new file mode 100644 index 00000000..548e8a66 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Cloth/Collider.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 40021b99aa72bb340a13cdf419aa3226 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/MagicaCloth2/Scripts/Core/Cloth/Collider/ColliderComponent.cs b/Assets/MagicaCloth2/Scripts/Core/Cloth/Collider/ColliderComponent.cs new file mode 100644 index 00000000..6a70d2c8 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Cloth/Collider/ColliderComponent.cs @@ -0,0 +1,434 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using System.Collections.Generic; +using System.Linq; +using UnityEngine; + +namespace MagicaCloth2 +{ + public abstract class ColliderComponent : ClothBehaviour, IDataValidate, ITransform + { + /// + /// トランスフォームからの中心ローカルオフセット + /// Center local offset from transform. + /// + public Vector3 center; + + /// + /// Size + /// Sphere(x:radius) + /// Capsule(x:start radius, y:end radius, z:length) + /// Box(x:size x, y:size y, z:size z) + /// + [SerializeField] + protected Vector3 size; + + /// + /// シンメトリーモード + /// Symmetry mode. + /// + public ColliderSymmetryMode symmetryMode = ColliderSymmetryMode.None; + + /// + /// シンメトリーの接続対象 + /// Symmetry connection target. + /// + public Transform symmetryTarget = null; + + //========================================================================================= + /// + /// Collider type. + /// + /// + public abstract ColliderManager.ColliderType GetColliderType(); + + /// + /// パラメータの検証 + /// + public abstract void DataValidate(); + + //========================================================================================= + /// + /// 登録チーム + /// + private HashSet teamIdSet = new HashSet(); + + /// + /// 現在登録中のシンメトリーモード + /// + public ColliderSymmetryMode? ActiveSymmetryMode { get; private set; } = null; + + /// + /// 現在登録中のシンメトリーターゲット + /// + public Transform ActiveSymmetryTarget { get; private set; } + + //========================================================================================= + /// + /// Get collider size. + /// + /// Sphere(x:radius) + /// Capsule(x:start radius, y:end radius, z:length) + /// Box(x:size x, y:size y, z:size z) + /// + /// + /// + public virtual Vector3 GetSize() => 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 virtual float GetScale() + { + // X軸のみを見る + return transform.lossyScale.x; + } + + /// + /// 方向の逆転(基本的にカプセルコライダー用) + /// + /// + public virtual bool IsReverseDirection() => false; + + /// + /// チームへのコライダー登録通知 + /// + /// + internal void Register(int teamId) + { + teamIdSet.Add(teamId); + } + + /// + /// チームからのコライダー解除通知 + /// + /// + /// 利用者0ならtrue + internal bool Exit(int teamId) + { + teamIdSet.Remove(teamId); + return teamIdSet.Count == 0; + } + + /// + /// パラメータの反映 + /// すでに実行状態の場合はこの関数を呼び出さないとプロパティの変更が反映されません。 + /// Reflection of parameters. + /// If it is already running, property changes will not be reflected unless this function is called. + /// + public void UpdateParameters() + { + // パラメータの検証 + 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, 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) + { + MagicaObjectId id = symmetryTarget.GetMagicaId(); + if (id.IsValid() && replaceDict.ContainsKey(id)) + symmetryTarget = replaceDict[id]; + } + } + + //========================================================================================= + protected virtual void Start() + { + SetActiveSymmetryMode(firstOnly: true); + } + + protected virtual void OnValidate() + { + UpdateParameters(); + } + + protected virtual void OnEnable() + { + // コライダーを有効にする + foreach (int teamId in teamIdSet) + { + MagicaManager.Collider.EnableCollider(this, teamId, true); + } + } + + protected virtual void OnDisable() + { + // コライダーを無効にする + foreach (int teamId in teamIdSet) + { + MagicaManager.Collider?.EnableCollider(this, teamId, false); + } + } + + protected virtual void OnDestroy() + { + // コライダーを削除する + if (teamIdSet.Count > 0) + { + var teamList = teamIdSet.ToList(); + foreach (int teamId in teamList) + { + MagicaManager.Collider?.RemoveCollider(this, teamId); + } + teamIdSet.Clear(); + } + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/Cloth/Collider/ColliderComponent.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Cloth/Collider/ColliderComponent.cs.meta new file mode 100644 index 00000000..7a811223 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Cloth/Collider/ColliderComponent.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: ce7d80df3961a0449ba9ba73c0038b88 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Cloth/Collider/ColliderComponent.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Cloth/Collider/ColliderSymmetryMode.cs b/Assets/MagicaCloth2/Scripts/Core/Cloth/Collider/ColliderSymmetryMode.cs new file mode 100644 index 00000000..7be93a13 --- /dev/null +++ b/Assets/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/MagicaCloth2/Scripts/Core/Cloth/Collider/ColliderSymmetryMode.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Cloth/Collider/ColliderSymmetryMode.cs.meta new file mode 100644 index 00000000..a1fcc9d8 --- /dev/null +++ b/Assets/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.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Cloth/Collider/ColliderSymmetryMode.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Cloth/Collider/MagicaCapsuleCollider.cs b/Assets/MagicaCloth2/Scripts/Core/Cloth/Collider/MagicaCapsuleCollider.cs new file mode 100644 index 00000000..c832b499 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Cloth/Collider/MagicaCapsuleCollider.cs @@ -0,0 +1,132 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using UnityEngine; + +namespace MagicaCloth2 +{ + /// + /// Capsuleコライダーコンポーネント + /// + [AddComponentMenu("MagicaCloth2/MagicaCapsuleCollider")] + [HelpURL("https://magicasoft.jp/en/mc2_capsulecollidercomponent/")] + public class MagicaCapsuleCollider : ColliderComponent + { + public enum Direction + { + [InspectorName("X-Axis")] + X = 0, + + [InspectorName("Y-Axis")] + Y = 1, + + [InspectorName("Z-Axis")] + Z = 2, + } + + /// + /// Reference transform axis. + /// + public Direction direction = Direction.X; + + /// + /// Reverse direction. + /// 方向を逆転させる + /// + public bool reverseDirection = false; + + /// + /// 半径をStart/End別々に設定 + /// Set radius separately for Start/End. + /// + public bool radiusSeparation = false; + + /// + /// 中央揃え + /// Aligned on center. + /// + public bool alignedOnCenter = true; + + + public override ColliderManager.ColliderType GetColliderType() + { + if (direction == Direction.X) + return alignedOnCenter ? ColliderManager.ColliderType.CapsuleX_Center : ColliderManager.ColliderType.CapsuleX_Start; + else if (direction == Direction.Y) + return alignedOnCenter ? ColliderManager.ColliderType.CapsuleY_Center : ColliderManager.ColliderType.CapsuleY_Start; + else + return alignedOnCenter ? ColliderManager.ColliderType.CapsuleZ_Center : ColliderManager.ColliderType.CapsuleZ_Start; + } + + /// + /// set size. + /// + /// + /// + /// + public void SetSize(float startRadius, float endRadius, float length) + { + SetSize(new Vector3(startRadius, endRadius, length)); + radiusSeparation = startRadius != endRadius; + } + + /// + /// get size. + /// (x:start radius, y:end radius, z:length) + /// + /// + public override Vector3 GetSize() + { + if (radiusSeparation) + return size; + else + { + // (始点半径, 終点半径, 長さ) + return new Vector3(size.x, size.x, size.z); + } + } + + /// + /// カプセルのローカル方向を返す + /// + /// + public Vector3 GetLocalDir() + { + float rev = reverseDirection ? -1 : 1; + + if (direction == Direction.X) + return Vector3.right * rev; + else if (direction == Direction.Y) + return Vector3.up * rev; + else + return Vector3.forward * rev; + } + + /// + /// カプセルのローカル上方向を返す + /// + /// + public Vector3 GetLocalUp() + { + if (direction == Direction.X) + return Vector3.up; + else if (direction == Direction.Y) + return Vector3.forward; + else + return Vector3.up; + } + + /// + /// 方向の逆転(基本的にカプセルコライダー用) + /// + /// + public override bool IsReverseDirection() => reverseDirection; + + public override void DataValidate() + { + size.x = Mathf.Max(size.x, 0.001f); + size.y = Mathf.Max(size.y, 0.001f); + size.z = Mathf.Max(size.z, 0.001f); + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/Cloth/Collider/MagicaCapsuleCollider.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Cloth/Collider/MagicaCapsuleCollider.cs.meta new file mode 100644 index 00000000..8d0a30c7 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Cloth/Collider/MagicaCapsuleCollider.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: e6f5338a96461264fb9a1132c8509672 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {fileID: 2800000, guid: db1f683d4db92254e93d234d88f6cd1d, type: 3} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Cloth/Collider/MagicaCapsuleCollider.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Cloth/Collider/MagicaPlaneCollider.cs b/Assets/MagicaCloth2/Scripts/Core/Cloth/Collider/MagicaPlaneCollider.cs new file mode 100644 index 00000000..2195bb5c --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Cloth/Collider/MagicaPlaneCollider.cs @@ -0,0 +1,28 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp + +using UnityEngine; + +namespace MagicaCloth2 +{ + /// + /// Planeコライダーコンポーネント + /// Y軸方向に対する無限平面 + /// Plane Collider. + /// Infinite plane for the Y-axis direction. + /// + [AddComponentMenu("MagicaCloth2/MagicaPlaneCollider")] + [HelpURL("https://magicasoft.jp/en/mc2_planecollidercomponent/")] + public class MagicaPlaneCollider : ColliderComponent + { + public override ColliderManager.ColliderType GetColliderType() + { + return ColliderManager.ColliderType.Plane; + } + + public override void DataValidate() + { + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/Cloth/Collider/MagicaPlaneCollider.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Cloth/Collider/MagicaPlaneCollider.cs.meta new file mode 100644 index 00000000..aa22fe03 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Cloth/Collider/MagicaPlaneCollider.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 1771fb5869b59304e82522e24e85fd40 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {fileID: 2800000, guid: db1f683d4db92254e93d234d88f6cd1d, type: 3} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Cloth/Collider/MagicaPlaneCollider.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Cloth/Collider/MagicaSphereCollider.cs b/Assets/MagicaCloth2/Scripts/Core/Cloth/Collider/MagicaSphereCollider.cs new file mode 100644 index 00000000..746327ed --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Cloth/Collider/MagicaSphereCollider.cs @@ -0,0 +1,34 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using UnityEngine; + +namespace MagicaCloth2 +{ + /// + /// Sphere collider + /// + [AddComponentMenu("MagicaCloth2/MagicaSphereCollider")] + [HelpURL("https://magicasoft.jp/en/mc2_spherecollidercomponent/")] + public class MagicaSphereCollider : ColliderComponent + { + public override ColliderManager.ColliderType GetColliderType() + { + return ColliderManager.ColliderType.Sphere; + } + + public override void DataValidate() + { + size.x = Mathf.Max(size.x, 0.001f); + } + + /// + /// resize the sphere. + /// + /// + public void SetSize(float radius) + { + SetSize(new Vector3(radius, 0.0f, 0.0f)); + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/Cloth/Collider/MagicaSphereCollider.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Cloth/Collider/MagicaSphereCollider.cs.meta new file mode 100644 index 00000000..9ffb9d46 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Cloth/Collider/MagicaSphereCollider.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: f2b68b2c7953ebb479b78627f19a6ccb +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {fileID: 2800000, guid: db1f683d4db92254e93d234d88f6cd1d, type: 3} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Cloth/Collider/MagicaSphereCollider.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Cloth/Constraints.meta b/Assets/MagicaCloth2/Scripts/Core/Cloth/Constraints.meta new file mode 100644 index 00000000..ca8d97dc --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Cloth/Constraints.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: b697bf7b265fa5e4a92ce1e2e9f3c449 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/MagicaCloth2/Scripts/Core/Cloth/Constraints/AngleConstraint.cs b/Assets/MagicaCloth2/Scripts/Core/Cloth/Constraints/AngleConstraint.cs new file mode 100644 index 00000000..295b7af9 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Cloth/Constraints/AngleConstraint.cs @@ -0,0 +1,594 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using System; +using System.Text; +using Unity.Collections; +using Unity.Mathematics; +using UnityEngine; + +namespace MagicaCloth2 +{ + /// + /// 角度復元/角度制限制約 + /// 内部処理がほぼ同じなため1つに統合 + /// + public class AngleConstraint : IDisposable + { + /// + /// angle restoration. + /// 角度復元 + /// + [System.Serializable] + public class RestorationSerializeData : IDataValidate + { + /// + /// Presence or absence of use. + /// [OK] Runtime changes. + /// [OK] Export/Import with Presets + /// + public bool useAngleRestoration; + + /// + /// resilience. + /// 復元力 + /// [OK] Runtime changes. + /// [OK] Export/Import with Presets + /// + public CurveSerializeData stiffness; + + /// + /// Velocity decay during restoration. + /// 復元時の速度減衰 + /// [OK] Runtime changes. + /// [OK] Export/Import with Presets + /// + [Range(0.0f, 1.0f)] + public float velocityAttenuation; + + /// + /// Directional Attenuation of Gravity. + /// Note that this attenuation occurs even if the gravity is 0! + /// 復元の重力方向減衰 + /// この減衰は重力が0でも発生するので注意! + /// [OK] Runtime changes. + /// [OK] Export/Import with Presets + /// + [Range(0.0f, 1.0f)] + public float gravityFalloff; + + public RestorationSerializeData() + { + useAngleRestoration = true; + stiffness = new CurveSerializeData(0.2f, 1.0f, 0.2f, true); + velocityAttenuation = 0.8f; + gravityFalloff = 0.0f; + } + + public void DataValidate() + { + stiffness.DataValidate(0.0f, 1.0f); + velocityAttenuation = Mathf.Clamp01(velocityAttenuation); + gravityFalloff = Mathf.Clamp01(gravityFalloff); + } + + public RestorationSerializeData Clone() + { + return new RestorationSerializeData() + { + useAngleRestoration = useAngleRestoration, + stiffness = stiffness.Clone(), + velocityAttenuation = velocityAttenuation, + gravityFalloff = gravityFalloff, + }; + } + } + + /// + /// angle limit. + /// 角度制限 + /// + [System.Serializable] + public class LimitSerializeData : IDataValidate + { + /// + /// Presence or absence of use. + /// [OK] Runtime changes. + /// [OK] Export/Import with Presets + /// + public bool useAngleLimit; + + /// + /// Limit angle (deg). + /// 制限角度(deg) + /// [OK] Runtime changes. + /// [OK] Export/Import with Presets + /// + public CurveSerializeData limitAngle; + + /// + /// Standard stiffness. + /// 基準剛性 + /// [OK] Runtime changes. + /// [OK] Export/Import with Presets + /// + [Range(0.0f, 1.0f)] + public float stiffness; + + public LimitSerializeData() + { + useAngleLimit = false; + limitAngle = new CurveSerializeData(60.0f, 0.0f, 1.0f); + stiffness = 1.0f; + } + + public void DataValidate() + { + limitAngle.DataValidate(0.0f, 180.0f); + stiffness = Mathf.Clamp01(stiffness); + } + + public LimitSerializeData Clone() + { + return new LimitSerializeData() + { + useAngleLimit = useAngleLimit, + limitAngle = limitAngle.Clone(), + stiffness = stiffness, + }; + } + } + + //========================================================================================= + public struct AngleConstraintParams + { + public bool useAngleRestoration; + + /// + /// 角度復元力 + /// + public float4x4 restorationStiffness; + + /// + /// 角度復元速度減衰 + /// + public float restorationVelocityAttenuation; + + /// + /// 角度復元の重力方向減衰 + /// + public float restorationGravityFalloff; + + + public bool useAngleLimit; + + /// + /// 制限角度(deg) + /// + public float4x4 limitCurveData; + + /// + /// 角度制限剛性 + /// + public float limitstiffness; + + public void Convert(RestorationSerializeData restorationData, LimitSerializeData limitData) + { + useAngleRestoration = restorationData.useAngleRestoration; + // Restoration Powerは設定値の20%とする.つまり1.0で旧0.2となる + restorationStiffness = restorationData.stiffness.ConvertFloatArray() * 0.2f; + restorationVelocityAttenuation = restorationData.velocityAttenuation; + restorationGravityFalloff = restorationData.gravityFalloff; + + useAngleLimit = limitData.useAngleLimit; + limitCurveData = limitData.limitAngle.ConvertFloatArray(); + limitstiffness = limitData.stiffness; + } + } + + //========================================================================================= + public AngleConstraint() + { + } + + public void Dispose() + { + } + + public override string ToString() + { + StringBuilder sb = new StringBuilder(); + sb.AppendLine($"[AngleConstraint]"); + return sb.ToString(); + } + + //========================================================================================= + // Solver + //========================================================================================= + internal static void SolverConstraint( + DataChunk chunk, + in float4 simulationPower, + // team + ref TeamManager.TeamData tdata, + ref ClothParameters param, + // vmesh + ref NativeArray attributes, + ref NativeArray vertexDepths, + ref NativeArray vertexParentIndices, + ref NativeArray baseLineStartDataIndices, + ref NativeArray baseLineDataCounts, + ref NativeArray baseLineData, + // particle + 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; + + 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; + + // ベースラインごと + //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++) + { + 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; + int vindex = v_start + l_index; + + // 自身 + var npos = nextPosArray[pindex]; + var bpos = stepBasicPositionBuffer[pindex]; + var brot = stepBasicRotationBuffer[pindex]; + + rotationBufferArray[pindex] = brot; + + // 親 + if (i > 0) + { + int p_l_index = vertexParentIndices[vindex]; + int p_pindex = p_l_index + p_start; + var pnpos = nextPosArray[p_pindex]; + var pbpos = stepBasicPositionBuffer[p_pindex]; + var pbrot = stepBasicRotationBuffer[p_pindex]; + + if (useAngleLimit) + { + // 現在ベクトル長 + float vlen = math.distance(npos, pnpos); + + // 親からの基本姿勢 + var bv = bpos - pbpos; + 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; + } + } + + if (useAngleRestoration) + { + // 復元ベクトル + float3 rv = bpos - pbpos; + restorationVectorBufferArray[pindex] = rv; + //Debug.Log($"[{pindex}] rv:{rv}"); + } + } + } + + // 反復 + // 角度制限は親と子の位置を徐々に修正していくため反復は必須。 + // 反復は多いほど堅牢性が増す。 + for (int k = 0; k < Define.System.AngleLimitIteration; k++) + { + float iterationRatio = (float)k / (Define.System.AngleLimitIteration - 1); // 0.0 ~ 1.0 + + // 回転の中心点。 + // 親に近い(値が小さい)ほど角度制限の効果が増すが酷い振動の温床ともなる。 + // 中心点がちょうど真ん中(0.5)の場合は堅牢性が最大となり振動が発生しなくなるがそのかわり角度復元/制限の効果が弱くなる。 + // そのため反復ごとに回転中心を徐々に親(0.0)から中間(0.5)に近づけることにより堅牢性と安定性を確保する + // この処理により振動が完全に無くなる訳では無いが許容範囲であるし何よりも角度復元/制限の効果が大幅に向上する + //float limitRotRatio = math.min(math.lerp(0.3f, 0.7f, iterationRatio), 0.5f); + //float limitRotRatio = math.min(math.lerp(0.4f, 0.7f, iterationRatio), 0.5f); + float limitRotRatio = 0.4f; + float restorationRotRatio = math.lerp(0.1f, 0.5f, iterationRatio); + + dataIndex = start + d_start; + for (int i = 0; i < dcnt; i++, dataIndex++) + { + int l_index = baseLineData[dataIndex]; + int pindex = p_start + l_index; + int vindex = v_start + l_index; + + //Debug.Log($"pindex:{pindex}"); + + // 子 + float3 cpos = nextPosArray[pindex]; + float cdepth = vertexDepths[vindex]; + var cattr = attributes[vindex]; + var cInvMass = MathUtility.CalcInverseMass(frictionArray[pindex]); + + // 子が固定ならばスキップ + if (cattr.IsMove() == false) + continue; + + // 親 + int p_pindex = vertexParentIndices[vindex] + p_start; + int p_vindex = vertexParentIndices[vindex] + v_start; + float3 ppos = nextPosArray[p_pindex]; + //float pdepth = vertexDepths[p_vindex]; + var pattr = attributes[p_vindex]; + var pInvMass = MathUtility.CalcInverseMass(frictionArray[p_pindex]); + + //===================================================== + // Angle Limit + //===================================================== + if (useAngleLimit) + { + // 親からの基準姿勢 + quaternion prot = rotationBufferArray[p_pindex]; + float3 localPos = localPosBufferArray[pindex]; + quaternion localRot = localRotBufferArray[pindex]; + + // 現在のベクトル + 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 blen = lengthBufferArray[pindex]; + vlen = math.lerp(vlen, blen, 0.5f); // 計算前の距離に徐々に近づける + 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.MC2EvaluateCurve(cdepth); + float maxAngleRad = math.radians(maxAngleDeg); + float angle = MathUtility.Angle(v, tv); + float3 rv = v; + if (angle > maxAngleRad) + { + // stiffness + float recoveryAngle = math.lerp(angle, maxAngleRad, limitStiffness); + + MathUtility.ClampAngle(v, tv, recoveryAngle, out rv); + } + + // 回転中心割合 + float3 rotPos = ppos + v * limitRotRatio; + + // 親と子のそれぞれの更新位置 + float3 pfpos = rotPos - rv * limitRotRatio; + float3 cfpos = rotPos + rv * (1.0f - limitRotRatio); + + // 加算 + float3 padd = pfpos - ppos; + float3 cadd = cfpos - cpos; + + // 摩擦考慮 + cadd *= cInvMass; + padd *= pInvMass; + + const float attn = Define.System.AngleLimitAttenuation; + + // 子の書き込み + if (cattr.IsMove()) + { + cpos += cadd; + nextPosArray[pindex] = cpos; + velocityPosArray[pindex] = velocityPosArray[pindex] + cadd * attn; + } + + // 親の書き込み + if (pattr.IsMove()) + { + ppos += padd; + nextPosArray[p_pindex] = ppos; + velocityPosArray[p_pindex] = velocityPosArray[p_pindex] + padd * attn; + } + + // 回転補正 + 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.FromToRotationWithoutNormalize(tv, v); + nrot = math.mul(q, nrot); + rotationBufferArray[pindex] = nrot; + } + + EndAngleLimit: + + //===================================================== + // Angle Restoration + //===================================================== + if (useAngleRestoration) + { + //Debug.Log($"pindex:{pindex}, p_pindex:{p_pindex}"); + + // 復元すべきベクトル + 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.MC2EvaluateCurveClamp01(cdepth); + restorationStiffness = math.saturate(restorationStiffness * simulationPower.w); + + //int _pindex = indexBuffer[i] + p_start; + //Debug.Log($"i:{i} [{_pindex}] stiffness:{restorationStiffness} cdepth:{cdepth}"); + + // 重力方向減衰 + restorationStiffness *= gravityFalloff; + + // 球面線形補間 + var q = MathUtility.FromToRotationWithoutNormalize(v / vlen, tv / tvlen, restorationStiffness); + float3 rv = math.mul(q, v); + + // 回転中心割合 + //float restorationRotRatio = GetRotRatio(tv, gravityVector, gravity, gravityFalloff, iterationRatio); + //int _pindex = indexBuffer[i] + p_start; + //Debug.Log($"i:{i} [{_pindex}] ratio:{restorationRotRatio} cdepth:{cdepth}"); + float3 rotPos = ppos + v * restorationRotRatio; + + // 親と子のそれぞれの更新位置 + float3 pfpos = rotPos - rv * restorationRotRatio; + float3 cfpos = rotPos + rv * (1.0f - restorationRotRatio); + + // 加算 + float3 padd = pfpos - ppos; + float3 cadd = cfpos - cpos; + + // 摩擦考慮 + cadd *= cInvMass; + padd *= pInvMass; + + // 子の書き込み + if (cattr.IsMove()) + { + cpos += cadd; + nextPosArray[pindex] = cpos; + velocityPosArray[pindex] = velocityPosArray[pindex] + cadd * restorationAttn; + } + + // 親の書き込み + if (pattr.IsMove()) + { + ppos += padd; + nextPosArray[p_pindex] = ppos; + velocityPosArray[p_pindex] = velocityPosArray[p_pindex] + padd * restorationAttn; + } + } + } + } + } + + // バッファクリア + 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/MagicaCloth2/Scripts/Core/Cloth/Constraints/AngleConstraint.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Cloth/Constraints/AngleConstraint.cs.meta new file mode 100644 index 00000000..4981c8fc --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Cloth/Constraints/AngleConstraint.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: ee1ebe8cef869d6439a8152a540713c4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Cloth/Constraints/AngleConstraint.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Cloth/Constraints/ColliderCollisionConstraint.cs b/Assets/MagicaCloth2/Scripts/Core/Cloth/Constraints/ColliderCollisionConstraint.cs new file mode 100644 index 00000000..8850b3ea --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Cloth/Constraints/ColliderCollisionConstraint.cs @@ -0,0 +1,1065 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using System; +using System.Collections.Generic; +using System.Text; +using Unity.Collections; +using Unity.Collections.LowLevel.Unsafe; +using Unity.Mathematics; +using UnityEngine; + +namespace MagicaCloth2 +{ + /// + /// コライダーによる衝突判定制約 + /// + public class ColliderCollisionConstraint : IDisposable + { + /// + /// Collision judgment mode. + /// 衝突判定モード + /// + public enum Mode + { + None = 0, + Point = 1, + Edge = 2, + } + + [System.Serializable] + public class SerializeData : IDataValidate, ITransform + { + /// + /// Collision judgment mode. + /// 衝突判定モード + /// [OK] Runtime changes. + /// [OK] Export/Import with Presets + /// + public Mode mode; + + /// + /// Friction (0.0 ~ 1.0). + /// Dynamic friction/stationary friction combined use. + /// 摩擦(0.0 ~ 1.0) + /// 動摩擦/静止摩擦兼用 + /// [OK] Runtime changes. + /// [OK] Export/Import with Presets + /// + [Range(0.0f, 0.5f)] + public float friction; + + /// + /// Collider list. + /// コライダーリスト + /// [OK] Runtime changes. + /// [NG] Export/Import with Presets + /// + public List colliderList = new List(); + + /// + /// List of Transforms that perform collision detection with BoneSpring. + /// BoneSpringで衝突判定を行うTransformのリスト + /// [OK] Runtime changes. + /// [NG] Export/Import with Presets + /// + public List collisionBones = new List(); + + /// + /// The maximum distance from the origin that a vertex will be pushed by the collider. Currently used only with BoneSpring. + /// コライダーにより頂点が押し出される原点からの最大距離。現在はBoneSpringのみで利用。 + /// [OK] Runtime changes. + /// [OK] Export/Import with Presets + /// + public CurveSerializeData limitDistance = new CurveSerializeData(0.05f); + + + public SerializeData() + { + mode = Mode.Point; + friction = 0.05f; + } + + public void DataValidate() + { + friction = Mathf.Clamp(friction, 0.0f, 0.5f); + limitDistance.DataValidate(0.0f, 1.0f); + } + + public SerializeData Clone() + { + return new SerializeData() + { + mode = mode, + friction = friction, + colliderList = new List(colliderList), + collisionBones = new List(collisionBones), + }; + } + + public override int GetHashCode() + { + int hash = 0; + foreach (var t in collisionBones) + { + if (t) + hash += t.GetMagicaId().GetHashCode(); + } + + return hash; + } + + public void GetUsedTransform(HashSet transformSet) + { + colliderList.ForEach(x => + { + if (x) + x.GetUsedTransform(transformSet); + }); + foreach (var t in collisionBones) + { + if (t) + transformSet.Add(t); + } + } + + 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]; + if (t && replaceDict.ContainsKey(t.GetMagicaId())) + { + collisionBones[i] = replaceDict[t.GetMagicaId()]; + } + } + } + + public int ColliderLength => colliderList.Count; + } + + public struct ColliderCollisionConstraintParams + { + /// + /// 衝突判定モード + /// BoneSpringではPointに固定される + /// + public Mode mode; + + /// + /// 動摩擦係数(0.0 ~ 1.0) + /// 摩擦1.0に対するステップごとの接線方向の速度減速率 + /// + public float dynamicFriction; + + /// + /// 静止摩擦係数(0.0 ~ 1.0) + /// 静止速度(m/s) + /// + public float staticFriction; + + /// + /// コライダーにより頂点が押し出される原点からの最大距離。現在はBoneSpringのみで利用。 + /// + public float4x4 limitDistance; + + public void Convert(SerializeData sdata, ClothProcess.ClothType clothType) + { + switch (clothType) + { + case ClothProcess.ClothType.BoneCloth: + case ClothProcess.ClothType.MeshCloth: + mode = sdata.mode; + // 動摩擦/静止摩擦は設定摩擦に係数を掛けたものを使用する + dynamicFriction = sdata.friction * Define.System.ColliderCollisionDynamicFrictionRatio; + staticFriction = sdata.friction * Define.System.ColliderCollisionStaticFrictionRatio; + break; + case ClothProcess.ClothType.BoneSpring: + // BoneSpringは球のみ + mode = Mode.Point; + // BoneSpringのみ押し出し距離制限を設ける + limitDistance = sdata.limitDistance.ConvertFloatArray(); + // 摩擦は定数 + dynamicFriction = Define.System.BoneSpringCollisionFriction; + staticFriction = Define.System.BoneSpringCollisionFriction; + break; + } + } + } + + //========================================================================================= + public ColliderCollisionConstraint() + { + } + + + public void Dispose() + { + } + + public override string ToString() + { + StringBuilder sb = new StringBuilder(); + sb.AppendLine($"[ColliderCollisionConstraint]"); + return sb.ToString(); + } + + //========================================================================================= + // Point Solver + //========================================================================================= + internal static void SolverPointConstraint( + DataChunk chunk, + // team + ref TeamManager.TeamData tdata, + ref ClothParameters param, + // vmesh + ref NativeArray attributes, + ref NativeArray vertexDepths, + // particle + ref NativeArray nextPosArray, + ref NativeArray frictionArray, + ref NativeArray collisionNormalArray, + ref NativeArray velocityPosArray, + ref NativeArray basePosArray, + // collider + ref NativeArray colliderFlagArray, + ref NativeArray colliderWorkDataArray + ) + { + if (tdata.UseColliderCount == 0) + return; + if (param.colliderCollisionConstraint.mode != Mode.Point) + return; + if (chunk.IsValid == false) + return; + + 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++) + { + // パーティクル情報 + var nextPos = nextPosArray[pindex]; + var attr = attributes[vindex]; + if (attr.IsInvalid() || attr.IsDisableCollision()) + continue; + if (attr.IsMove() == false && tdata.IsSpring == false) // スプリング利用時は固定頂点も通す + continue; + float depth = vertexDepths[vindex]; + + // BoneSpringでは自動的にソフトコライダーとなる + var basePos = isSpring ? basePosArray[pindex] : float3.zero; // ソフトコライダーのみbasePosが必要 + + // パーティクル半径 + float radius = math.max(param.radiusCurveData.MC2EvaluateCurve(depth), 0.0001f); // safe; + + // チームスケール倍率 + radius *= tdata.scaleRatio; + + // コライダーとの距離 + float mindist = float.MaxValue; + + // 接触コライダー情報 + int collisionColliderId = -1; + float3 collisionNormal = 0; + float3 n = 0; + + // パーティクル押し出し情報 + float3 addPos = 0; + int addCnt = 0; + float3 addN = 0; + + // 接触判定を行うコライダーからの最大距離(collisionFrictionRange) + // パーティクルサイズから算出する + float cfr = radius * 1.0f; // 1.0f? + + // パーティクルAABB + var aabb = new AABB(nextPos - radius, nextPos + radius); + aabb.Expand(cfr); + + // BoneSpringでの最大押し出し距離 + float maxLength = isSpring ? math.max(param.colliderCollisionConstraint.limitDistance.MC2EvaluateCurve(depth), 0.0001f) * tdata.scaleRatio : -1; // チームスケール倍率 + + // チーム内のコライダーをループ + int cindex = tdata.colliderChunk.startIndex; + int ccnt = tdata.colliderCount; + for (int i = 0; i < ccnt; i++, cindex++) + { + var cflag = colliderFlagArray[cindex]; + if (cflag.IsSet(ColliderManager.Flag_Valid) == false) + continue; + if (cflag.IsSet(ColliderManager.Flag_Enable) == false) + continue; + + var ctype = DataUtility.GetColliderType(cflag); + var cwork = colliderWorkDataArray[cindex]; + float dist = 100.0f; + float3 _nextPos = nextPos; + switch (ctype) + { + case ColliderManager.ColliderType.Sphere: + // ソフトコライダーはSphereのみ + dist = PointSphereColliderDetection(ref _nextPos, basePos, radius, aabb, cwork, isSpring, maxLength, out n); + break; + case ColliderManager.ColliderType.CapsuleX_Center: + case ColliderManager.ColliderType.CapsuleY_Center: + case ColliderManager.ColliderType.CapsuleZ_Center: + case ColliderManager.ColliderType.CapsuleX_Start: + case ColliderManager.ColliderType.CapsuleY_Start: + case ColliderManager.ColliderType.CapsuleZ_Start: + dist = PointCapsuleColliderDetection(ref _nextPos, radius, aabb, cwork, out n); + break; + case ColliderManager.ColliderType.Plane: + dist = PointPlaneColliderDetction(ref _nextPos, radius, cwork, out n); + break; + default: + Debug.LogError($"unknown collider type:{ctype}"); + break; + } + + // 明確な接触と押し出しあり + if (dist <= 0.0f) + { + // 押し出されたベクトルと接触法線をすべて加算する + addPos += (_nextPos - nextPos); + addN += n; + addCnt++; + //Debug.Log($"Collision!"); + } + + // コライダーに一定距離近づいている場合(動摩擦/静止摩擦が影響する) + if (dist <= cfr) + { + // 接触法線をすべて加算し、またコライダーまでの最近距離を記録する + collisionColliderId = cindex; + collisionNormal += n; // すべて加算する + mindist = math.min(mindist, dist); + } + } + + // 最終位置 + // 平均化する + if (addCnt > 0) + { + // 合成された接触法線の長さに比例してパーティクルの移動を制限する + // これにより2つのコライダーに挟まれたパーティクルが暴れなくなる + addN /= addCnt; + float len = math.length(addN); + if (len < Define.System.Epsilon) + { + addPos = 0; + } + else + { + float t = math.min(len, 1.0f); + addPos /= addCnt; + nextPos += addPos * t; + } + } + + // 摩擦係数(friction)計算 + if (collisionColliderId >= 0 && cfr > 0.0f && math.lengthsq(collisionNormal) > 1e-06f) + { + // コライダーからの距離により変化(0.0~接地面1.0) + //Develop.Assert(cfr > 0.0f); + var friction = 1.0f - math.saturate(mindist / cfr); + frictionArray[pindex] = math.max(friction, frictionArray[pindex]); // 大きい方 + + // 摩擦用接触法線平均化 + //Develop.Assert(math.length(collisionNormal) > 0.0f); + collisionNormal = math.normalize(collisionNormal); + } + collisionNormalArray[pindex] = collisionNormal; + // todo:一応コライダーIDを記録しているが現在未使用! + //colliderIdArray[pindex] = collisionColliderId + 1; // +1するので注意! + + // 書き戻し + nextPosArray[pindex] = nextPos; + + // 速度影響(BoneSpringのみ) + if (isSpring && addCnt > 0) + { + // BoneSpringでは速度影響を0にする + velocityPosArray[pindex] = velocityPosArray[pindex] + addPos; + } + } + } + + 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; + + var oldpos = nextpos; + + //========================================================= + // 衝突解決 + //========================================================= + 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); + + // 衝突法線 + normal = n; + + // 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); + + // (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; + } +#endif + + return dist; + } + + 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; // ここに押し出し法線 + + // 衝突法線 + normal = n; + + // c = 平面位置(パーティクル半径分オフセット) + // n = 平面方向 + // 平面衝突判定と押し出し + // 平面との距離を返す(押し出しの場合は0.0) + return MathUtility.IntersectPointPlaneDist(cpos + n * radius, n, nextpos, out nextpos); + } + + 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; + + // コライダー情報 + 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; + + // 移動前コライダーのローカルベクトル + 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); + + // 衝突法線 + normal = n; + + // c = 平面位置 + // n = 平面方向 + // 平面衝突判定と押し出し + return MathUtility.IntersectPointPlaneDist(c, n, nextpos, out nextpos); + } + + //========================================================================================= + // Edge Solver + //========================================================================================= + internal unsafe static void SolverEdgeConstraint( + DataChunk chunk, + // team + ref TeamManager.TeamData tdata, + ref ClothParameters param, + // vmesh + ref NativeArray attributes, + ref NativeArray vertexDepths, + ref NativeArray edges, + // particle + ref NativeArray nextPosArray, + // collider + 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; + + // ■Edge + int* vecAPt = (int*)tempVectorBufferA.GetUnsafePtr(); + int* vecBPt = (int*)tempVectorBufferB.GetUnsafePtr(); + int* cntPt = (int*)tempCountBuffer.GetUnsafePtr(); + int* floatPt = (int*)tempFloatBufferA.GetUnsafePtr(); + + // ■計算 + // エッジごと + 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++) + { + // エッジ情報 + int2 edge = edges[eindex]; + int2 vE = edge + vstart; + var attrE0 = attributes[vE.x]; + var attrE1 = attributes[vE.y]; + // 両方とも固定なら不要 + bool isMove0 = attrE0.IsMove(); + bool isMove1 = attrE1.IsMove(); + if (isMove0 == false && isMove1 == false) + 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.MC2EvaluateCurve(depthE.x), param.radiusCurveData.MC2EvaluateCurve(depthE.y)); + + // チームスケール倍率 + radiusE *= tdata.scaleRatio; + + // 接触判定を行うコライダーからの最大距離 + // パーティクルサイズから算出する + float cfr = (radiusE.x + radiusE.y) * 0.5f * 1.0f; // 1.0f? + + // 接触コライダー情報 + float mindist = float.MaxValue; + int collisionColliderId = -1; + float3 collisionNormal = 0; + float3 n = 0; + + // エッジ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); + aabbE.Encapsulate(aabbE1); + aabbE.Expand(cfr); + + // パーティクル押し出し情報 + float3x2 addPos = 0; + int addCnt = 0; + float3 addN = 0; + + // チーム内のコライダーをループ + int cindex = tdata.colliderChunk.startIndex; + int ccnt = tdata.colliderCount; + for (int i = 0; i < ccnt; i++, cindex++) + { + var cflag = colliderFlagArray[cindex]; + if (cflag.IsSet(ColliderManager.Flag_Valid) == false) + continue; + if (cflag.IsSet(ColliderManager.Flag_Enable) == false) + continue; + + var ctype = DataUtility.GetColliderType(cflag); + var cwork = colliderWorkDataArray[cindex]; + float dist = 100.0f; + float3x2 _nextPos = nextPosE; + switch (ctype) + { + case ColliderManager.ColliderType.Sphere: + dist = EdgeSphereColliderDetection(ref _nextPos, radiusE, aabbE, cfr, cwork, out n); + break; + case ColliderManager.ColliderType.CapsuleX_Center: + case ColliderManager.ColliderType.CapsuleY_Center: + case ColliderManager.ColliderType.CapsuleZ_Center: + case ColliderManager.ColliderType.CapsuleX_Start: + case ColliderManager.ColliderType.CapsuleY_Start: + case ColliderManager.ColliderType.CapsuleZ_Start: + dist = EdgeCapsuleColliderDetection(ref _nextPos, radiusE, aabbE, cfr, cwork, out n); + break; + case ColliderManager.ColliderType.Plane: + dist = EdgePlaneColliderDetection(ref _nextPos, radiusE, cwork, out n); + break; + default: + Debug.LogError($"Unknown collider type:{ctype}"); + break; + } + + // 明確な接触と押し出しあり + if (dist <= 0.0f) + { + // 押し出されたベクトルと接触法線をすべて加算する + addPos += (_nextPos - nextPosE); + addN += n; + addCnt++; + } + + // コライダーに一定距離近づいている場合(動摩擦/静止摩擦が影響する) + if (dist <= cfr) + { + // 接触法線をすべて加算し、またコライダーまでの最近距離を記録する + collisionColliderId = cindex; + collisionNormal += n; // すべて加算する + mindist = math.min(mindist, dist); + } + } + + // 最終位置 + // 平均化する + if (addCnt > 0) + { + // 合成された接触法線の長さに比例してパーティクルの移動を制限する + // これにより2つのコライダーに挟まれたパーティクルが暴れなくなる + addN /= addCnt; + float len = math.length(addN); + if (len > Define.System.Epsilon) + { + float t = math.min(len, 1.0f); + addPos /= addCnt; + addPos *= t; + + // 書き戻し + InterlockUtility.AddFloat3(pE.x, addPos.c0, cntPt, vecAPt); + InterlockUtility.AddFloat3(pE.y, addPos.c1, cntPt, vecAPt); + } + } + + // 摩擦係数(friction)集計 + if (collisionColliderId >= 0 && cfr > 0.0f && math.lengthsq(collisionNormal) > 1e-06f) + { + // コライダーからの距離により変化(0.0~接地面1.0) + //Develop.Assert(cfr > 0.0f); + var friction = 1.0f - math.saturate(mindist / cfr); + + // 摩擦用接触法線平均化 + //Develop.Assert(math.length(collisionNormal) > 0.0f); + collisionNormal = math.normalize(collisionNormal); + + if (isMove0) + { + InterlockUtility.Max(pE.x, friction, floatPt); + InterlockUtility.AddFloat3(pE.x, collisionNormal, vecBPt); + } + if (isMove1) + { + InterlockUtility.Max(pE.y, friction, floatPt); + InterlockUtility.AddFloat3(pE.y, collisionNormal, vecBPt); + } + } + } + } + + internal unsafe static void SumEdgeConstraint( + DataChunk chunk, + // team + ref TeamManager.TeamData tdata, + ref ClothParameters param, + // particle + 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; + + // ■Edge + int* vecAPt = (int*)tempVectorBufferA.GetUnsafePtr(); + int* vecBPt = (int*)tempVectorBufferB.GetUnsafePtr(); + int* cntPt = (int*)tempCountBuffer.GetUnsafePtr(); + int* floatPt = (int*)tempFloatBufferA.GetUnsafePtr(); + + // ■集計 + // パーティクルごと + //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++) + { + // nextpos + int count = tempCountBuffer[pindex]; + if (count > 0) + { + float3 add = InterlockUtility.ReadAverageFloat3(pindex, cntPt, vecAPt); + + // 書き出し + nextPosArray[pindex] = nextPosArray[pindex] + add; + } + + // friction + float f = InterlockUtility.ReadFloat(pindex, floatPt); + if (f > 0.0f && f > frictionArray[pindex]) + { + frictionArray[pindex] = f; + } + + // collision normal + float3 n = InterlockUtility.ReadFloat3(pindex, vecBPt); + if (math.lengthsq(n) > 0.0f) + { + n = math.normalize(n); + collisionNormalArray[pindex] = n; + } + + // バッファクリア + 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/MagicaCloth2/Scripts/Core/Cloth/Constraints/ColliderCollisionConstraint.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Cloth/Constraints/ColliderCollisionConstraint.cs.meta new file mode 100644 index 00000000..a387541d --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Cloth/Constraints/ColliderCollisionConstraint.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 2fd00990cb70cd54d99a32756b3ccc84 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Cloth/Constraints/ColliderCollisionConstraint.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Cloth/Constraints/DistanceConstraint.cs b/Assets/MagicaCloth2/Scripts/Core/Cloth/Constraints/DistanceConstraint.cs new file mode 100644 index 00000000..55fd7174 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Cloth/Constraints/DistanceConstraint.cs @@ -0,0 +1,536 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using System; +using System.Collections.Generic; +using System.Text; +using Unity.Collections; +using Unity.Mathematics; +using UnityEngine; + +namespace MagicaCloth2 +{ + /// + /// 距離制約 + /// + public class DistanceConstraint : IDisposable + { + [System.Serializable] + public class SerializeData : IDataValidate + { + /// + /// Overall connection stiffness (0.0 ~ 1.0). + /// 全体的な接続の剛性(0.0 ~ 1.0) + /// [OK] Runtime changes. + /// [OK] Export/Import with Presets + /// + public CurveSerializeData stiffness; + + public SerializeData() + { + stiffness = new CurveSerializeData(1.0f, 1.0f, 0.5f, false); + } + + public void DataValidate() + { + stiffness.DataValidate(0.0f, 1.0f); + } + + public SerializeData Clone() + { + return new SerializeData() + { + stiffness = stiffness.Clone(), + }; + } + } + + public struct DistanceConstraintParams + { + /// + /// 剛性 + /// + public float4x4 restorationStiffness; + + /// + /// 距離制約の速度減衰率(0.0 ~ 1.0) + /// + public float velocityAttenuation; + + public void Convert(SerializeData sdata, ClothProcess.ClothType clothType) + { + switch (clothType) + { + case ClothProcess.ClothType.BoneCloth: + case ClothProcess.ClothType.MeshCloth: + restorationStiffness = sdata.stiffness.ConvertFloatArray(); + break; + case ClothProcess.ClothType.BoneSpring: + // BoneSpringは定数 + restorationStiffness = Define.System.BoneSpringDistanceStiffness; + break; + } + velocityAttenuation = Define.System.DistanceVelocityAttenuation; + } + } + + //========================================================================================= + /// + /// 接続タイプ数 + /// + public const int TypeCount = 2; + + /// + /// 制約データ + /// + [System.Serializable] + public class ConstraintData : IValid + { + public ResultCode result; + + public uint[] indexArray; + public ushort[] dataArray; + public float[] distanceArray; + + public bool IsValid() + { + return indexArray != null && indexArray.Length > 0; + } + } + + /// + /// パーティクルごとのデータ開始インデックスとデータ数を1つのuint(10-22)にパックしたもの + /// + public ExNativeArray indexArray; + + /// + /// 接続パーティクルリスト + /// + public ExNativeArray dataArray; + + /// + /// 対象への基準距離リスト + /// ただし符号によりタイプを示す(+:Vertical, -:Horizontal) + /// + public ExNativeArray distanceArray; + + /// + /// 登録データ数を返す + /// + public int DataCount => indexArray?.Count ?? 0; + + //========================================================================================= + public DistanceConstraint() + { + indexArray = new ExNativeArray(0, true); + dataArray = new ExNativeArray(0, true); + distanceArray = new ExNativeArray(0, true); + } + + public void Dispose() + { + indexArray?.Dispose(); + dataArray?.Dispose(); + distanceArray?.Dispose(); + } + + public override string ToString() + { + StringBuilder sb = new StringBuilder(); + sb.AppendLine($"[DistanceConstraint]"); + sb.AppendLine($" -indexArray:{indexArray.ToSummary()}"); + sb.AppendLine($" -dataArray:{dataArray.ToSummary()}"); + sb.AppendLine($" -distanceArray:{distanceArray.ToSummary()}"); + + return sb.ToString(); + } + + //========================================================================================= + /// + /// 制約データの作成 + /// + /// + public static ConstraintData CreateData(VirtualMesh proxyMesh, in ClothParameters parameters) + { + var constraintData = new ConstraintData(); + + NativeParallelMultiHashMap vvMap = default; + + try + { + int vcnt = proxyMesh.VertexCount; + + // 頂点の接続頂点配列をMultiHashMapに変換する + vvMap = JobUtility.ToNativeMultiHashMap(proxyMesh.vertexToVertexIndexArray, proxyMesh.vertexToVertexDataArray); + + var connectSet = new HashSet(); + using var verticalConnection = new MultiDataBuilder(vcnt, vcnt * 2); + using var horizontalConnection = new MultiDataBuilder(vcnt, vcnt * 2); + + // 構造接続 + for (int i = 0; i < vcnt; i++) + { + if (vvMap.ContainsKey(i) == false) + continue; + + var attr = proxyMesh.attributes[i]; + int pindex = proxyMesh.vertexParentIndices[i]; + + foreach (var data in vvMap.GetValuesForKey(i)) + { + int tindex = data; + var t_attr = proxyMesh.attributes[tindex]; + int t_pindex = proxyMesh.vertexParentIndices[tindex]; + + // 両方とも固定ならば無効 + if (attr.IsMove() == false && t_attr.IsMove() == false) + continue; + + // 1点でも無効なら除外する + if (attr.IsInvalid() || t_attr.IsInvalid()) + continue; + + // 登録 + if (tindex == pindex || i == t_pindex) + { + // ベースライン + verticalConnection.Add(i, data); + } + else + { + // それ以外 + horizontalConnection.Add(i, data); + } + uint pack = DataUtility.Pack32Sort(i, tindex); + connectSet.Add(pack); + //Debug.Log($"({i} - {tindex})"); + } + } + +#if true + // shear接続(横接続として登録) + if (proxyMesh.edgeToTriangles.IsCreated) + { + int ecnt = proxyMesh.EdgeCount; + for (int l = 0; l < ecnt; l++) + { + int2 edge = proxyMesh.edges[l]; + var tset = proxyMesh.edgeToTriangles.MC2ToFixedList128Bytes(edge); + int tcnt = tset.Length; + if (tcnt < 2) + continue; + + // p3 + + // / \ + // p1 +---+ p2 + // \ / + // p4 + + var p1 = proxyMesh.localPositions[edge.x]; + var p2 = proxyMesh.localPositions[edge.y]; + float edgeLength1 = math.length(p1 - p2); + if (edgeLength1 < Define.System.Epsilon) + continue; + var v1 = math.normalize(p1 - p2); + var cen = (p1 + p2) * 0.5f; + + for (int i = 0; i < tcnt - 1; i++) + { + int3 tri1 = proxyMesh.triangles[tset[i]]; + int e3 = MathUtility.GetUnuseTriangleIndex(tri1, edge); + var p3 = proxyMesh.localPositions[e3]; + var attr3 = proxyMesh.attributes[e3]; + var n1 = MathUtility.TriangleNormal(p1, p2, p3); + for (int j = i + 1; j < tcnt; j++) + { + int3 tri2 = proxyMesh.triangles[tset[j]]; + int e4 = MathUtility.GetUnuseTriangleIndex(tri2, edge); + var p4 = proxyMesh.localPositions[e4]; + var attr4 = proxyMesh.attributes[e4]; + var n2 = MathUtility.TriangleNormal(p1, p2, p4); + + // 両方とも固定ならば無効 + if (attr3.IsMove() == false && attr4.IsMove() == false) + continue; + + // (1)トライアングルの内角がほぼ水平かチェック + // 20度:0.9396926f + float dot = math.abs(math.dot(n1, n2)); + if (dot < 0.9396926f) + continue; + + // (2)トライアングルペアの2つの対角線の長さが一定以内なら正方形と判定する + float edgeLength2 = math.length(p3 - p4); + float ratio = math.abs(edgeLength2 / edgeLength1 - 1.0f); + if (ratio <= 0.3f) + { + // 正方形 + // 対角線(p3-p4)をShearとして接続する + uint pack = DataUtility.Pack32Sort(e3, e4); + if (connectSet.Contains(pack) == false) + { + connectSet.Add(pack); + horizontalConnection.Add(e3, (ushort)e4); + horizontalConnection.Add(e4, (ushort)e3); + } + } + } + } + } + } +#endif + // 制約データ登録 + (var dataArryaV, var indexArrayV) = verticalConnection.ToArray(); + (var dataArryaH, var indexArrayH) = horizontalConnection.ToArray(); + + // すべて無効属性などデータがnullの場合もある + int total = (dataArryaV?.Length ?? 0) + (dataArryaH?.Length ?? 0); + if (total > 0) + { + var indexList = new List(vcnt); + var dataList = new List(total); + var distanceList = new List(total); + for (int i = 0; i < vcnt; i++) + { + int start = dataList.Count; + int cnt = 0; + + float3 pos = proxyMesh.localPositions[i]; + + for (int k = 0; k < TypeCount; k++) + { + DataUtility.Unpack12_20(k == 0 ? indexArrayV[i] : indexArrayH[i], out var dcnt, out var dstart); + for (int j = 0; j < dcnt; j++) + { + ushort data = k == 0 ? dataArryaV[dstart + j] : dataArryaH[dstart + j]; + var tpos = proxyMesh.localPositions[data]; + float dist = math.distance(pos, tpos); + + // ゼロ距離も認める(v2.17.0) + dataList.Add(data); + distanceList.Add(dist < 1e-08f ? 0.0f : (k == 0 ? dist : -dist)); // マイナスはhorizontalタイプ + cnt++; + } + } + + uint pack = DataUtility.Pack12_20(cnt, start); + indexList.Add(pack); + } + + constraintData.indexArray = indexList.ToArray(); + constraintData.dataArray = dataList.ToArray(); + constraintData.distanceArray = distanceList.ToArray(); + } + + constraintData.result.SetSuccess(); + } + catch (Exception exception) + { + Debug.LogError(exception); + constraintData.result.SetError(Define.Result.Constraint_CreateDistanceException); + throw; + } + finally + { + if (vvMap.IsCreated) + vvMap.Dispose(); + } + + return constraintData; + } + + //========================================================================================= + /// + /// 制約データを登録する + /// + /// + internal void Register(ClothProcess cprocess) + { + if (cprocess?.distanceConstraintData?.IsValid() ?? false) + { + ref var tdata = ref MagicaManager.Team.GetTeamDataRef(cprocess.TeamId); + + tdata.distanceStartChunk = indexArray.AddRange(cprocess.distanceConstraintData.indexArray); + tdata.distanceDataChunk = dataArray.AddRange(cprocess.distanceConstraintData.dataArray); + distanceArray.AddRange(cprocess.distanceConstraintData.distanceArray); + } + } + + /// + /// 制約データを解除する + /// + /// + internal void Exit(ClothProcess cprocess) + { + if (cprocess != null && cprocess.TeamId > 0) + { + ref var tdata = ref MagicaManager.Team.GetTeamDataRef(cprocess.TeamId); + + indexArray.Remove(tdata.distanceStartChunk); + dataArray.Remove(tdata.distanceDataChunk); + distanceArray.Remove(tdata.distanceDataChunk); + + tdata.distanceStartChunk.Clear(); + tdata.distanceDataChunk.Clear(); + } + } + + //========================================================================================= + // Solver + //========================================================================================= + internal static void SolverConstraint( + DataChunk chunk, + float4 simulationPower, + // team + ref TeamManager.TeamData tdata, + ref ClothParameters param, + // vmesh + ref NativeArray attributes, + ref NativeArray depthArray, + // particle + ref NativeArray nextPosArray, + ref NativeArray basePosArray, + ref NativeArray velocityPosArray, + ref NativeArray frictionArray, + // constrants + 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; + + // 復元を基本姿勢で行うかアニメーション後の姿勢で行うかの判定 + float animeRatio = 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++) + { + // パーティクル情報 + var nextPos = nextPosArray[pindex]; + var attr = attributes[vindex]; + float depth = depthArray[vindex]; + float friction = frictionArray[pindex]; + + if (attr.IsInvalid()) + continue; + + // Spring利用中は固定も通す + if (attr.IsDontMove() && isSpring == false) + continue; + + // 固定点の重量 + float fixMass = isSpring ? 10.0f : 50.0f; + + // 重量 + // BoneSpringでは固定点の重量加算を行わない + float invMass = MathUtility.CalcInverseMass(friction, depth, attr.IsDontMove(), fixMass); + + // 基本剛性 + float stiffness = param.distanceConstraint.restorationStiffness.MC2EvaluateCurveClamp01(depth); + stiffness *= simulationPower.y; + + //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 addPos = 0; + int addCnt = 0; + + int start = d_start + dstart; + for (int i = 0; i < dcnt; i++) + { + int t_l_index = dataArray[start + i]; + float restDist = distanceArray[start + i]; + + // タイプ別剛性 + float finalStiffness = math.saturate(restDist >= 0.0f ? stiffness : stiffness * Define.System.DistanceHorizontalStiffness); + + // 相手パーティクル情報 + int tpindex = p_start + t_l_index; + int tvindex = v_start + t_l_index; + var t_nextPos = nextPosArray[tpindex]; + float3 t_basePos = basePosArray[tpindex]; + float t_depth = depthArray[tvindex]; + float t_friction = frictionArray[tpindex]; + var t_attr = attributes[tvindex]; + + var v = t_nextPos - nextPos; + + // ゼロ距離対応(v2.17.0) + if(restDist == 0.0f) + { + // ゼロ距離は単に中点で結合させる + // AnimationPoseRatioも無関係 + addPos = v * 0.5f; + addCnt++; + } + else + { + // 重量 + // BoneSpringでは固定点の重量加算を行わない + float t_invMass = MathUtility.CalcInverseMass(t_friction, t_depth, t_attr.IsDontMove(), fixMass); + + // 復元する長さ + // !Distance制約は初期化時に保存した距離を見るようにしないと駄目 + // フラグにより初期値かアニメーション後の姿勢かを切り替える + float restLength = math.lerp(math.abs(restDist) * scl, math.distance(basePos, t_basePos), animeRatio); + + // 現在の長さ + float distance = math.length(v); + + // 距離がほぼ0ならば処理をスキップする(エラーの回避) + if (distance < Define.System.Epsilon) + continue; + + // 伸縮 + float3 n = math.normalize(v); + float3 corr = (distance - restLength) * finalStiffness * n / (invMass + t_invMass); + float3 corr0 = invMass * corr; + //float3 corr1 = -t_invMass * corr; // 相手側(使用しない) + + // すべて加算する + addPos += corr0; + addCnt++; + } + } + + // 最終位置 + if (addCnt > 0) + { + addPos = addPos / addCnt; // 平均化 + nextPos += addPos; + nextPosArray[pindex] = nextPos; + + // 速度影響 + float attn = param.distanceConstraint.velocityAttenuation; + velocityPosArray[pindex] = velocityPosArray[pindex] + addPos * attn; + } + } + } + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/Cloth/Constraints/DistanceConstraint.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Cloth/Constraints/DistanceConstraint.cs.meta new file mode 100644 index 00000000..305dd349 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Cloth/Constraints/DistanceConstraint.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 78c9fce0ef596d444be169932d9e9b6d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Cloth/Constraints/DistanceConstraint.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Cloth/Constraints/InertiaConstraint.cs b/Assets/MagicaCloth2/Scripts/Core/Cloth/Constraints/InertiaConstraint.cs new file mode 100644 index 00000000..02892b47 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Cloth/Constraints/InertiaConstraint.cs @@ -0,0 +1,636 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using System; +using System.Text; +using Unity.Mathematics; +using UnityEngine; +using UnityEngine.Serialization; + +namespace MagicaCloth2 +{ + /// + /// Inertia and travel/rotation limits. + /// 慣性と移動/回転制限 + /// + public class InertiaConstraint : IDisposable + { + /// + /// テレポートモード + /// Teleport processing mode. + /// + public enum TeleportMode + { + None = 0, + + /// + /// シミュレーションをリセットします + /// Reset the simulation. + /// + Reset = 1, + + /// + /// テレポート前の状態を継続します + /// Continue the state before the teleport. + /// + Keep = 2, + } + + [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) + /// [OK] Runtime changes. + /// [OK] Export/Import with Presets + /// + [FormerlySerializedAs("movementInertia")] + [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) + /// [OK] Runtime changes. + /// [OK] Export/Import with Presets + /// + public CheckSliderSerializeData movementSpeedLimit; + + /// + /// World rotation speed limit (deg/s). + /// ワールド回転速度制限(deg/s) + /// [OK] Runtime changes. + /// [OK] Export/Import with Presets + /// + public CheckSliderSerializeData rotationSpeedLimit; + + /// + /// Local Influence (0.0 ~ 1.0). + /// ローカル慣性影響(0.0 ~ 1.0) + /// [OK] Runtime changes. + /// [OK] Export/Import with Presets + /// + [Range(0.0f, 1.0f)] + public float localInertia; + + /// + /// Local movement speed limit (m/s). + /// ローカル移動速度制限(m/s) + /// [OK] Runtime changes. + /// [OK] Export/Import with Presets + /// + public CheckSliderSerializeData localMovementSpeedLimit; + + /// + /// Local rotation speed limit (deg/s). + /// ローカル回転速度制限(deg/s) + /// [OK] Runtime changes. + /// [OK] Export/Import with Presets + /// + public CheckSliderSerializeData localRotationSpeedLimit; + + /// + /// depth inertia (0.0 ~ 1.0). + /// Increasing the effect weakens the inertia near the root (makes it difficult to move). + /// 深度慣性(0.0 ~ 1.0) + /// 影響を大きくするとルート付近の慣性が弱くなる(動きにくくなる) + /// [OK] Runtime changes. + /// [OK] Export/Import with Presets + /// + [Range(0.0f, 1.0f)] + public float depthInertia; + + /// + /// Centrifugal acceleration (0.0 ~ 1.0). + /// 遠心力加速(0.0 ~ 1.0) + /// [OK] Runtime changes. + /// [OK] Export/Import with Presets + /// + [Range(0.0f, 1.0f)] + public float centrifualAcceleration; + + /// + /// Particle Velocity Limit (m/s). + /// パーティクル速度制限(m/s) + /// [OK] Runtime changes. + /// [OK] Export/Import with Presets + /// + public CheckSliderSerializeData particleSpeedLimit; + + /// + /// Teleport determination method. + /// テレポート判定モード + /// [OK] Runtime changes. + /// [OK] Export/Import with Presets + /// + public TeleportMode teleportMode; + + /// + /// Teleport detection distance. + /// テレポート判定距離 + /// [OK] Runtime changes. + /// [OK] Export/Import with Presets + /// + public float teleportDistance; + + /// + /// Teleport detection angle(deg). + /// テレポート判定回転角度(deg) + /// [OK] Runtime changes. + /// [OK] Export/Import with Presets + /// + public float teleportRotation; + + 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; + localMovementSpeedLimit = new CheckSliderSerializeData(false, 5.0f); + localRotationSpeedLimit = new CheckSliderSerializeData(false, 720.0f); + depthInertia = 0.0f; + centrifualAcceleration = 0.0f; + particleSpeedLimit = new CheckSliderSerializeData(true, 4.0f); + teleportMode = TeleportMode.None; + teleportDistance = 0.5f; + teleportRotation = 90.0f; + } + + public SerializeData Clone() + { + return new SerializeData() + { + anchor = anchor, + anchorInertia = anchorInertia, + worldInertia = worldInertia, + movementInertiaSmoothing = movementInertiaSmoothing, + movementSpeedLimit = movementSpeedLimit.Clone(), + rotationSpeedLimit = rotationSpeedLimit.Clone(), + localInertia = localInertia, + localMovementSpeedLimit = localMovementSpeedLimit.Clone(), + localRotationSpeedLimit = localRotationSpeedLimit.Clone(), + depthInertia = depthInertia, + centrifualAcceleration = centrifualAcceleration, + particleSpeedLimit = particleSpeedLimit.Clone(), + teleportMode = teleportMode, + teleportDistance = teleportDistance, + teleportRotation = teleportRotation, + }; + } + + 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); + localMovementSpeedLimit.DataValidate(0.0f, Define.System.MaxMovementSpeedLimit); + localRotationSpeedLimit.DataValidate(0.0f, Define.System.MaxRotationSpeedLimit); + centrifualAcceleration = Mathf.Clamp01(centrifualAcceleration); + depthInertia = Mathf.Clamp01(depthInertia); + particleSpeedLimit.DataValidate(0.0f, Define.System.MaxParticleSpeedLimit); + teleportDistance = Mathf.Max(teleportDistance, 0.0f); + teleportRotation = Mathf.Max(teleportRotation, 0.0f); + } + } + + 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; + + /// + /// ローカル慣性影響(0.0 ~ 1.0) + /// + public float localInertia; + + /// + /// ローカル移動速度制限(m/s) + /// + public float localMovementSpeedLimit; + + /// + /// ローカル回転速度制限(deg/s) + /// + public float localRotationSpeedLimit; + + /// + /// 深度慣性(0.0 ~ 1.0) + /// 影響を大きくするとルート付近の慣性が弱くなる(動きにくくなる) + /// + public float depthInertia; + + /// + /// 遠心力加速(0.0 ~ 1.0) + /// + public float centrifualAcceleration; + + /// + /// パーティクル速度制限(m/s) + /// + public float particleSpeedLimit; + + /// + /// テレポートモード + /// + public TeleportMode teleportMode; + + /// + /// テレポート判定距離 + /// + public float teleportDistance; + + /// + /// テレポート判定角度(deg) + /// + public float teleportRotation; + + 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; + localMovementSpeedLimit = sdata.localMovementSpeedLimit.GetValue(-1); + localRotationSpeedLimit = sdata.localRotationSpeedLimit.GetValue(-1); + depthInertia = sdata.depthInertia; + centrifualAcceleration = sdata.centrifualAcceleration; + particleSpeedLimit = sdata.particleSpeedLimit.GetValue(-1); + teleportMode = sdata.teleportMode; + teleportDistance = sdata.teleportDistance; + teleportRotation = sdata.teleportRotation; + } + } + + //========================================================================================= + /// + /// センタートランスフォームのデータ + /// + [System.Serializable] + public struct CenterData + { + /// + /// 現在のアンカー姿勢 + /// + public float3 anchorPosition; + public quaternion anchorRotation; + + /// + /// 前フレームのアンカー姿勢 + /// + public float3 oldAnchorPosition; + public quaternion oldAnchorRotation; + + /// + /// アンカー空間でのコンポーネントのローカル座標 + /// + public float3 anchorComponentLocalPosition; + + /// + /// 参照すべきセンタートランスフォームインデックス + /// 同期時は同期先チームのもにになる + /// + public int centerTransformIndex; + + /// + /// 現フレームのコンポーネント姿勢 + /// + public float3 componentWorldPosition; + public quaternion componentWorldRotation; + public float3 componentWorldScale; + + /// + /// 前フレームのコンポーネント姿勢 + /// + public float3 oldComponentWorldPosition; + public quaternion oldComponentWorldRotation; + public float3 oldComponentWorldScale; + + /// + /// 現フレームのコンポーネント移動量 + /// + public float3 frameComponentShiftVector; + public quaternion frameComponentShiftRotation; + + /// + /// 現フレームのコンポーネント移動速度と方向 + /// + public float frameMovingSpeed; + public float3 frameMovingDirection; + + /// + /// 現フレームの姿勢 + /// + public float3 frameWorldPosition; + public quaternion frameWorldRotation; + public float3 frameWorldScale; + public float3 frameLocalPosition; + + /// + /// 前フレームの姿勢 + /// + public float3 oldFrameWorldPosition; + public quaternion oldFrameWorldRotation; + public float3 oldFrameWorldScale; + + /// + /// 現ステップでの姿勢 + /// + public float3 nowWorldPosition; + public quaternion nowWorldRotation; + //public float3 nowWorldScale; // ※現在未使用 + + /// + /// 前回ステップでの姿勢 + /// + public float3 oldWorldPosition; + public quaternion oldWorldRotation; + + /// + /// ステップごとの移動力削減割合(0.0~1.0) + /// + public float stepMoveInertiaRatio; + + /// + /// ステップごとの回転力削減割合(0.0~1.0) + /// + public float stepRotationInertiaRatio; + + /// + /// ステップごとの移動ベクトル + /// これは削減前の純粋なワールドベクトル + /// + public float3 stepVector; + + /// + /// ステップごとの回転ベクトル + /// これは削減前の純粋なワールド回転 + /// + public quaternion stepRotation; + + /// + /// ステップごとの慣性全体移動シフトベクトル + /// + public float3 inertiaVector; + + /// + /// ステップごとの慣性全体シフト回転 + /// + public quaternion inertiaRotation; + + /// + /// ステップごとの慣性削減後の移動速度(m/s) + /// + public float stepMovingSpeed; + + /// + /// ステップごとの慣性削減後の移動方向 + /// + public float3 stepMovingDirection; + + /// + /// 回転の角速度(rad/s) + /// + public float angularVelocity; + + /// + /// 回転軸(角速度0の場合は(0,0,0)) + /// + public float3 rotationAxis; + + /// + /// 初期化時の慣性中心姿勢でのローカル重力方向 + /// 重力falloff計算で使用 + /// + 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; + oldFrameWorldRotation = quaternion.identity; + nowWorldRotation = quaternion.identity; + oldWorldRotation = quaternion.identity; + stepRotation = quaternion.identity; + } + } + + /// + /// 制約データ + /// + [System.Serializable] + public class ConstraintData + { + public ResultCode result; + public CenterData centerData; + public float3 initLocalGravityDirection; + } + + /// + /// チームごとの固定点リスト + /// + internal ExNativeArray fixedArray; + + //========================================================================================= + public InertiaConstraint() + { + fixedArray = new ExNativeArray(0, true); + } + + public void Dispose() + { + fixedArray?.Dispose(); + fixedArray = null; + } + + public override string ToString() + { + StringBuilder sb = new StringBuilder(); + sb.AppendLine($"[InertiaConstraint]"); + sb.AppendLine($" -fixedArray:{fixedArray.ToSummary()}"); + + return sb.ToString(); + } + + //========================================================================================= + /// + /// 制約データの作成 + /// + /// + public static ConstraintData CreateData(VirtualMesh proxyMesh, in ClothParameters parameters) + { + var constraintData = new ConstraintData(); + + try + { + // ■センター + var cdata = new CenterData(); + cdata.Initialize(); + cdata.centerTransformIndex = proxyMesh.centerTransformIndex; + constraintData.centerData = cdata; + + // 固定点リストはすでにproxyMeshのcenterFixedListに格納されている + float3 nor = 0; + float3 tan = 0; + int ccnt = proxyMesh.CenterFixedPointCount; + if (ccnt > 0) + { + for (int i = 0; i < ccnt; i++) + { + int fixedIndex = proxyMesh.centerFixedList[i]; + + // 初期姿勢を求める + var lnor = proxyMesh.localNormals[fixedIndex]; + var ltan = proxyMesh.localTangents[fixedIndex]; + var lrot = MathUtility.ToRotation(lnor, ltan); + var bindRot = proxyMesh.vertexBindPoseRotations[fixedIndex]; + var q = math.mul(lrot, bindRot); + nor += MathUtility.ToNormal(q); + tan += MathUtility.ToTangent(q); + } + } + + float3 localGravityDirection = new float3(0, -1, 0); + if (ccnt > 0) + { + // 初期センター姿勢からローカル重力方向を算出する + var rot = MathUtility.ToRotation(math.normalize(nor), math.normalize(tan)); + var irot = math.inverse(rot); + localGravityDirection = math.mul(irot, parameters.worldGravityDirection); + } + constraintData.initLocalGravityDirection = localGravityDirection; + + constraintData.result.SetSuccess(); + + //Develop.Log($"Create [InertiaConstraint]."); + } + catch (Exception exception) + { + Debug.LogError(exception); + constraintData.result.SetError(Define.Result.Constraint_CreateInertiaException); + throw; + } + finally + { + } + + return constraintData; + } + + internal void Register(ClothProcess cprocess) + { + // センターデータのセンタートランスフォームインデックスをダイレクト値に変更 + ref var tdata = ref MagicaManager.Team.GetTeamDataRef(cprocess.TeamId); + ref var cdata = ref MagicaManager.Team.centerDataArray.GetRef(cprocess.TeamId); + cdata.centerTransformIndex = tdata.centerTransformIndex; + + // 初期化時のローカル重力方向 + cdata.initLocalGravityDirection = cprocess.inertiaConstraintData.initLocalGravityDirection; + //Debug.Log($"[{cprocess.TeamId}] initLocalGravityDirection:{cdata.initLocalGravityDirection}"); + + // 固定点リスト + var c = new DataChunk(); + if (cprocess.ProxyMeshContainer.shareVirtualMesh.CenterFixedPointCount > 0) + { + c = fixedArray.AddRange(cprocess.ProxyMeshContainer.shareVirtualMesh.centerFixedList); + } + tdata.fixedDataChunk = c; + } + + internal void Exit(ClothProcess cprocess) + { + if (cprocess != null && cprocess.TeamId > 0) + { + ref var tdata = ref MagicaManager.Team.GetTeamDataRef(cprocess.TeamId); + + fixedArray.Remove(tdata.fixedDataChunk); + tdata.fixedDataChunk.Clear(); + } + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/Cloth/Constraints/InertiaConstraint.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Cloth/Constraints/InertiaConstraint.cs.meta new file mode 100644 index 00000000..b9331085 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Cloth/Constraints/InertiaConstraint.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: ac7ce6c753c84f24ca87c6d1b2f7efd8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Cloth/Constraints/InertiaConstraint.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Cloth/Constraints/MotionConstraint.cs b/Assets/MagicaCloth2/Scripts/Core/Cloth/Constraints/MotionConstraint.cs new file mode 100644 index 00000000..d856e0d3 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Cloth/Constraints/MotionConstraint.cs @@ -0,0 +1,292 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using System; +using Unity.Collections; +using Unity.Mathematics; +using UnityEngine; + +namespace MagicaCloth2 +{ + public class MotionConstraint : IDisposable + { + [System.Serializable] + public class SerializeData : IDataValidate + { + /// + /// Whether or not to use maximum travel range + /// 最大移動範囲 + /// [OK] Runtime changes. + /// [OK] Export/Import with Presets + /// + public bool useMaxDistance; + + /// + /// Maximum travel range. + /// [OK] Runtime changes. + /// [OK] Export/Import with Presets + /// + public CurveSerializeData maxDistance; + + /// + /// Use of backstop. + /// バックストップ使用の有無 + /// [OK] Runtime changes. + /// [OK] Export/Import with Presets + /// + public bool useBackstop; + + /// + /// Backstop sphere radius. + /// [OK] Runtime changes. + /// [OK] Export/Import with Presets + /// + [Range(0.1f, 10.0f)] + public float backstopRadius; + + /// + /// Distance from vertex to backstop sphere. + /// [OK] Runtime changes. + /// [OK] Export/Import with Presets + /// + public CurveSerializeData backstopDistance; + + /// + /// repulsive force(0.0 ~ 1.0) + /// [OK] Runtime changes. + /// [OK] Export/Import with Presets + /// + [Range(0.0f, 1.0f)] + public float stiffness; + + public SerializeData() + { + useMaxDistance = false; + maxDistance = new CurveSerializeData(0.3f); + useBackstop = false; + backstopRadius = 10.0f; + backstopDistance = new CurveSerializeData(0.0f); + stiffness = 1.0f; + } + + public void DataValidate() + { + maxDistance.DataValidate(0.0f, 5.0f); + //maxDistanceOffset = Mathf.Clamp01(maxDistanceOffset); + + backstopRadius = Mathf.Clamp(backstopRadius, 0.0f, 10.0f); + backstopDistance.DataValidate(0.0f, 1.0f); + + stiffness = Mathf.Clamp01(stiffness); + } + + public SerializeData Clone() + { + return new SerializeData() + { + useMaxDistance = useMaxDistance, + maxDistance = maxDistance.Clone(), + useBackstop = useBackstop, + backstopRadius = backstopRadius, + backstopDistance = backstopDistance.Clone(), + stiffness = stiffness, + }; + } + } + + public struct MotionConstraintParams + { + /// + /// 最大移動範囲 + /// + public bool useMaxDistance; + public float4x4 maxDistanceCurveData; + //public float maxDistanceOffset; + + /// + /// バックストップ距離 + /// + public bool useBackstop; + public float backstopRadius; + public float4x4 backstopDistanceCurveData; + + // stiffness + public float stiffness; + + public void Convert(SerializeData sdata, ClothProcess.ClothType clothType) + { + useMaxDistance = clothType == ClothProcess.ClothType.BoneSpring ? false : sdata.useMaxDistance; + maxDistanceCurveData = sdata.maxDistance.ConvertFloatArray(); + //maxDistanceOffset = sdata.maxDistanceOffset; + + useBackstop = clothType == ClothProcess.ClothType.BoneSpring ? false : sdata.useBackstop; + backstopRadius = sdata.backstopRadius; + backstopDistanceCurveData = sdata.backstopDistance.ConvertFloatArray(); + + stiffness = sdata.stiffness; + } + } + + public void Dispose() + { + } + + //========================================================================================= + // Solver + //========================================================================================= + internal static void SolverConstraint( + DataChunk chunk, + // team + ref TeamManager.TeamData tdata, + ref ClothParameters param, + // vmesh + ref NativeArray attributes, + ref NativeArray vertexDepths, + // particle + 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; + + 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++) + { + // 移動パーティクルのみ + var attr = attributes[vindex]; + if (attr.IsMove() == false) + continue; + + var nextPos = nextPosArray[pindex]; + var basePos = basePosArray[pindex]; + float depth = vertexDepths[vindex]; + + // !MaxDistanceとBackstop制約は常にアニメーション姿勢(basePose)から計算されるので注意! + // !そのためAnimationBlendRatioは影響しない。 + + // 適用頂点属性チェック + if (attr.IsMotion()) + { + var opos = nextPos; + + // パーティクル半径 + float radius = math.max(param.radiusCurveData.MC2EvaluateCurve(depth), 0.0001f); // safe + + // 摩擦影響距離 + float cfr = radius * 1.0f; + + // 深さは二次曲線にする(test) + depth = depth * depth; + + //========================================================= + // axis + //========================================================= + var baseRot = baseRotArray[pindex]; + float3 dir = math.up(); + switch (param.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); + + //========================================================= + // Max Distance + //========================================================= + if (param.motionConstraint.useMaxDistance) + { + float maxDistance = param.motionConstraint.maxDistanceCurveData.MC2EvaluateCurve(depth); + //var cen = basePos + dir * (motionParam.maxDistanceOffset * maxDistance); + var cen = basePos; + var v = MathUtility.ClampVector(nextPos - cen, maxDistance); + nextPos = cen + v; + } + + //========================================================= + // Backstop + //========================================================= + if (param.motionConstraint.useBackstop) + { + float backstopDistance = param.motionConstraint.backstopDistanceCurveData.MC2EvaluateCurve(depth); + if (backstopRadius > 0.0f) + { + // バックストップは法線逆方向 + float3 cen = basePos + -dir * (backstopDistance + backstopRadius); + var v = nextPos - cen; + float len = math.length(v); + if (len > Define.System.Epsilon && len < (backstopRadius + cfr)) + { + var n = v / len; + if (len < backstopRadius) + { + nextPos = cen + n * backstopRadius; + } + +#if false // 摩擦はあまり良くない気がするのでとりあえずOFF + // 摩擦 + float friction = 1.0f - math.saturate((len - backstopRadius) / cfr); + float nowFriction = frictionArray[pindex]; + if (friction > nowFriction) + { + // 大きければ更新 + frictionArray[pindex] = friction; + + // 接触法線 + collisionNormalArray[pindex] = n; + } +#endif + } + } + } + + //========================================================= + // Stiffness + //========================================================= + nextPos = math.lerp(opos, nextPos, stiffness); + + //========================================================= + // 格納 + //========================================================= + // 位置 + nextPosArray[pindex] = nextPos; + + // 速度影響 + var add = nextPos - opos; + const float attn = 0.95f; + velocityPosArray[pindex] = velocityPosArray[pindex] + add * attn; + } + } + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/Cloth/Constraints/MotionConstraint.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Cloth/Constraints/MotionConstraint.cs.meta new file mode 100644 index 00000000..d7f063c7 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Cloth/Constraints/MotionConstraint.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 659973f118f2eb64295ac6e523fdafff +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Cloth/Constraints/MotionConstraint.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Cloth/Constraints/SelfCollisionConstraint.cs b/Assets/MagicaCloth2/Scripts/Core/Cloth/Constraints/SelfCollisionConstraint.cs new file mode 100644 index 00000000..3058a647 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Cloth/Constraints/SelfCollisionConstraint.cs @@ -0,0 +1,2320 @@ +// Magica Cloth 2. +// Copyright (c) 2025 MagicaSoft. +// https://magicasoft.jp +using System; +using System.Runtime.CompilerServices; +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 partial class SelfCollisionConstraint : IDisposable + { + public enum SelfCollisionMode + { + None = 0, + + /// + /// PointPoint + /// + //Point = 1, // omit! + + /// + /// PointTriangle + EdgeEdge + Intersect + /// + FullMesh = 2, + } + + [System.Serializable] + public class SerializeData : IDataValidate + { + /// + /// self-collision mode + /// [OK] Runtime changes. + /// [OK] Export/Import with Presets + /// + public SelfCollisionMode selfMode; + + /// + /// primitive thickness. + /// [OK] Runtime changes. + /// [OK] Export/Import with Presets + /// + public CurveSerializeData surfaceThickness = new CurveSerializeData(0.005f, 0.5f, 1.0f, false); + + /// + /// mutual collision mode. + /// [OK] Runtime changes. + /// [OK] Export/Import with Presets + /// + public SelfCollisionMode syncMode; + + /// + /// Mutual Collision Opponent. + /// [OK] Runtime changes. + /// [OK] Export/Import with Presets + /// + public MagicaCloth syncPartner; + + /// + /// cloth weight. + /// [OK] Runtime changes. + /// [OK] Export/Import with Presets + /// + [Range(0.0f, 1.0f)] + public float clothMass = 0.0f; + + public SerializeData() + { + selfMode = SelfCollisionMode.None; + syncMode = SelfCollisionMode.None; + } + + public void DataValidate() + { + surfaceThickness.DataValidate(Define.System.SelfCollisionThicknessMin, Define.System.SelfCollisionThicknessMax); + clothMass = Mathf.Clamp01(clothMass); + } + + public SerializeData Clone() + { + return new SerializeData() + { + selfMode = selfMode, + surfaceThickness = surfaceThickness.Clone(), + syncMode = syncMode, + syncPartner = syncPartner, + clothMass = clothMass, + }; + } + + public MagicaCloth GetSyncPartner() + { + return syncMode != SelfCollisionMode.None ? syncPartner : null; + } + } + + public struct SelfCollisionConstraintParams + { + public SelfCollisionMode selfMode; + public float4x4 surfaceThicknessCurveData; + public SelfCollisionMode syncMode; + public float clothMass; + + public void Convert(SerializeData sdata, ClothProcess.ClothType clothType) + { + selfMode = clothType == ClothProcess.ClothType.BoneSpring ? SelfCollisionMode.None : sdata.selfMode; + surfaceThicknessCurveData = sdata.surfaceThickness.ConvertFloatArray(); + syncMode = clothType == ClothProcess.ClothType.BoneSpring ? SelfCollisionMode.None : sdata.syncMode; + clothMass = sdata.clothMass; + } + } + + //========================================================================================= + /// + /// プリミティブ + /// Point/Edge/Triangleの管理 + /// + public const uint KindPoint = 0; + public const uint KindEdge = 1; + public const uint KindTriangle = 2; + + public const uint Flag_KindMask = 0x03000000; // 24~25bit + public const uint Flag_Fix0 = 0x04000000; + public const uint Flag_Fix1 = 0x08000000; + public const uint Flag_Fix2 = 0x10000000; + 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; + + 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 + { + /// + /// フラグ + /// + public uint flag; + + /// + /// プリミティブを構成するパーティクルインデックス + /// 不要な軸は(-1)が設定されている + /// + public int3 particleIndices; + + public float3 invMass; + + /// + /// プリミティブAABB + /// + public AABB aabb; + + /// + /// UniformGird座標 + /// + public int3 grid; + + public float depth; + + /// + /// 厚み + /// + public float thickness; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool IsIgnore() + { + return (flag & Flag_Ignore) != 0; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool IsAllFix() + { + return (flag & Flag_AllFix) != 0; + } + + /// + /// パーティクルインデックスが1つ以上重複しているか判定する + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool AnyParticle(ref Primitive pri) + { + uint kind = ((flag & Flag_KindMask) >> 24) + 1; + + for (int i = 0; i < kind; i++) + { + int p = particleIndices[i]; + + // 入力すべてが非0ならtrue + if (math.all(pri.particleIndices - p) == false) + return true; + } + + return false; + } + + /// + /// ソート用 + /// グリッドX->Y->Zの順でソート + /// + /// + /// + public int CompareTo(Primitive other) + { + 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 int CompareTo(GridInfo other) + { + if (hash < other.hash) + return -1; + else if (hash > other.hash) + return 1; + else + return 0; + } + } + 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; + + //========================================================================================= + /// + /// ポイントプリミティブ総数 + /// + public int PointPrimitiveCount { get; private set; } = 0; + + /// + /// エッジプリミティブ総数 + /// + public int EdgePrimitiveCount { get; private set; } = 0; + + /// + /// トライアングルプリミティブ総数 + /// + public int TrianglePrimitiveCount { get; private set; } = 0; + + //========================================================================================= + /// + /// 交差解決フラグ(パーティクルと連動) + /// + internal NativeArray intersectFlagArray; + + internal int IntersectCount { get; private set; } = 0; + + //========================================================================================= + public SelfCollisionConstraint() + { + 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() + { + PointPrimitiveCount = 0; + EdgePrimitiveCount = 0; + TrianglePrimitiveCount = 0; + + intersectFlagArray.MC2DisposeSafe(); + + 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; + } + + /// + /// データの有無を返す + /// + /// + public bool HasPrimitive() + { + return (PointPrimitiveCount + EdgePrimitiveCount + TrianglePrimitiveCount) > 0; + } + + public override string ToString() + { + StringBuilder sb = new StringBuilder(); + sb.AppendLine($"[SelfCollisionConstraint]"); + sb.AppendLine($" -intersectFlagArray:{(intersectFlagArray.IsCreated ? intersectFlagArray.Length : 0)}"); + + return sb.ToString(); + } + + //========================================================================================= + /// + /// 制約データを登録する + /// + /// + internal void Register(ClothProcess cprocess) + { + UpdateTeam(cprocess.TeamId); + } + + /// + /// 制約データを解除する + /// + /// + internal void Exit(ClothProcess cprocess) + { + if (cprocess != null && cprocess.TeamId > 0) + { + // Exitフラグを見て自動的にすべて解放される + // また同期相手のフラグ更新も行う + UpdateTeam(cprocess.TeamId); + } + } + + /// + /// フラグおよびバッファの更新 + /// + /// + /// + internal void UpdateTeam(int teamId) + { + var tm = MagicaManager.Team; + + if (tm.ContainsTeamData(teamId) == false) + return; + ref var tdata = ref tm.GetTeamDataRef(teamId); + var oldFlag = tdata.flag; + + // チームが消滅中かどうか + 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; + var syncMode = exit ? SelfCollisionMode.None : parameter.selfCollisionConstraint.syncMode; + + bool usePointPrimitive = false; + bool useEdgePrimitive = false; + bool useTrianglePrimitive = false; + + bool selfEdgeEdge = false; + bool selfPointTriangle = false; + bool selfTrianglePoint = false; + bool selfEdgeTriangleIntersect = false; + bool selfTriangleEdgeIntersect = false; + + bool syncEdgeEdge = false; + bool syncPointTriangle = false; + bool syncTrianglePoint = false; + bool syncEdgeTriangleIntersect = false; + bool syncTriangleEdgeIntersect = false; + + bool PsyncEdgeEdge = false; + bool PsyncPointTriangle = false; + bool PsyncTrianglePoint = false; + bool PsyncEdgeTriangleIntersect = false; + bool PsyncTriangleEdgeIntersect = false; + + if (selfMode == SelfCollisionMode.FullMesh) + { + if (tdata.EdgeCount > 0) + { + useEdgePrimitive = true; + selfEdgeEdge = true; + } + if (tdata.TriangleCount > 0) + { + usePointPrimitive = true; + useTrianglePrimitive = true; + selfPointTriangle = true; + selfTrianglePoint = true; + } + if (tdata.EdgeCount > 0 && tdata.TriangleCount > 0) + { + selfEdgeTriangleIntersect = true; + selfTriangleEdgeIntersect = true; + } + } + + // sync + if (syncMode != SelfCollisionMode.None && tm.ContainsTeamData(tdata.syncTeamId)) + { + ref var stdata = ref tm.GetTeamDataRef(tdata.syncTeamId); + if (syncMode == SelfCollisionMode.FullMesh) + { + if (tdata.EdgeCount > 0 && stdata.EdgeCount > 0) + { + useEdgePrimitive = true; + syncEdgeEdge = true; + } + if (tdata.TriangleCount > 0) + { + useTrianglePrimitive = true; + syncTrianglePoint = true; + } + if (stdata.TriangleCount > 0) + { + usePointPrimitive = true; + syncPointTriangle = true; + } + if (tdata.EdgeCount > 0 && stdata.TriangleCount > 0) + { + syncEdgeTriangleIntersect = true; + } + if (tdata.TriangleCount > 0 && stdata.EdgeCount > 0) + { + syncTriangleEdgeIntersect = true; + } + } + } + + // sync parent + if (tdata.syncParentTeamId.Length > 0 && exit == false) + { + for (int i = 0; i < tdata.syncParentTeamId.Length; i++) + { + int parentTeamId = tdata.syncParentTeamId[i]; + ref var ptdata = ref tm.GetTeamDataRef(parentTeamId); + if (ptdata.IsValid) + { + ref var parentParameter = ref tm.GetParametersRef(parentTeamId); + var parentSyncMode = parentParameter.selfCollisionConstraint.syncMode; + if (parentSyncMode == SelfCollisionMode.FullMesh) + { + if (ptdata.EdgeCount > 0 && tdata.EdgeCount > 0) + { + useEdgePrimitive = true; + PsyncEdgeEdge = true; + } + if (ptdata.TriangleCount > 0) + { + usePointPrimitive = true; + PsyncPointTriangle = true; + } + if (tdata.TriangleCount > 0) + { + useTrianglePrimitive = true; + PsyncTrianglePoint = true; + } + if (tdata.EdgeCount > 0 && ptdata.TriangleCount > 0) + { + PsyncEdgeTriangleIntersect = true; + } + if (tdata.TriangleCount > 0 && ptdata.EdgeCount > 0) + { + PsyncTriangleEdgeIntersect = true; + } + } + } + } + } + + // フラグ + tdata.flag.SetBits(TeamManager.Flag_Self_PointPrimitive, usePointPrimitive); + tdata.flag.SetBits(TeamManager.Flag_Self_EdgePrimitive, useEdgePrimitive); + tdata.flag.SetBits(TeamManager.Flag_Self_TrianglePrimitive, useTrianglePrimitive); + + tdata.flag.SetBits(TeamManager.Flag_Self_EdgeEdge, selfEdgeEdge); + tdata.flag.SetBits(TeamManager.Flag_Self_PointTriangle, selfPointTriangle); + tdata.flag.SetBits(TeamManager.Flag_Self_TrianglePoint, selfTrianglePoint); + tdata.flag.SetBits(TeamManager.Flag_Self_EdgeTriangleIntersect, selfEdgeTriangleIntersect); + tdata.flag.SetBits(TeamManager.Flag_Self_TriangleEdgeIntersect, selfTriangleEdgeIntersect); + + tdata.flag.SetBits(TeamManager.Flag_Sync_EdgeEdge, syncEdgeEdge); + tdata.flag.SetBits(TeamManager.Flag_Sync_PointTriangle, syncPointTriangle); + tdata.flag.SetBits(TeamManager.Flag_Sync_TrianglePoint, syncTrianglePoint); + tdata.flag.SetBits(TeamManager.Flag_Sync_EdgeTriangleIntersect, syncEdgeTriangleIntersect); + tdata.flag.SetBits(TeamManager.Flag_Sync_TriangleEdgeIntersect, syncTriangleEdgeIntersect); + + tdata.flag.SetBits(TeamManager.Flag_PSync_EdgeEdge, PsyncEdgeEdge); + tdata.flag.SetBits(TeamManager.Flag_PSync_PointTriangle, PsyncPointTriangle); + tdata.flag.SetBits(TeamManager.Flag_PSync_TrianglePoint, PsyncTrianglePoint); + tdata.flag.SetBits(TeamManager.Flag_PSync_EdgeTriangleIntersect, PsyncEdgeTriangleIntersect); + tdata.flag.SetBits(TeamManager.Flag_PSync_TriangleEdgeIntersect, PsyncTriangleEdgeIntersect); + + // point buffer + if (usePointPrimitive && tdata.selfPointChunk.IsValid == false) + { + // init + int pointCount = tdata.ParticleCount; + tdata.selfPointChunk = primitiveArrayB.AddRange(pointCount); + uniformGridStartCountBuffer.AddRange(pointCount); + int start = tdata.selfPointChunk.startIndex; + InitPrimitive(teamId, tdata, KindPoint, start, pointCount); + PointPrimitiveCount += pointCount; + } + else if (usePointPrimitive == false && tdata.selfPointChunk.IsValid) + { + // remove + primitiveArrayB.Remove(tdata.selfPointChunk); + uniformGridStartCountBuffer.Remove(tdata.selfPointChunk); + PointPrimitiveCount -= tdata.selfPointChunk.dataLength; + tdata.selfPointChunk.Clear(); + } + + // edge buffer + if (useEdgePrimitive && tdata.selfEdgeChunk.IsValid == false) + { + // init + int edgeCount = tdata.EdgeCount; + tdata.selfEdgeChunk = primitiveArrayB.AddRange(edgeCount); + uniformGridStartCountBuffer.AddRange(edgeCount); + int start = tdata.selfEdgeChunk.startIndex; + InitPrimitive(teamId, tdata, KindEdge, start, edgeCount); + EdgePrimitiveCount += edgeCount; + } + else if (useEdgePrimitive == false && tdata.selfEdgeChunk.IsValid) + { + // remove + primitiveArrayB.Remove(tdata.selfEdgeChunk); + uniformGridStartCountBuffer.Remove(tdata.selfEdgeChunk); + EdgePrimitiveCount -= tdata.selfEdgeChunk.dataLength; + tdata.selfEdgeChunk.Clear(); + } + + // triangle buffer + if (useTrianglePrimitive && tdata.selfTriangleChunk.IsValid == false) + { + // init + int triangleCount = tdata.TriangleCount; + tdata.selfTriangleChunk = primitiveArrayB.AddRange(triangleCount); + uniformGridStartCountBuffer.AddRange(triangleCount); + int start = tdata.selfTriangleChunk.startIndex; + InitPrimitive(teamId, tdata, KindTriangle, start, triangleCount); + TrianglePrimitiveCount += triangleCount; + } + else if (useTrianglePrimitive == false && tdata.selfTriangleChunk.IsValid) + { + // remove + primitiveArrayB.Remove(tdata.selfTriangleChunk); + uniformGridStartCountBuffer.Remove(tdata.selfTriangleChunk); + TrianglePrimitiveCount -= tdata.selfTriangleChunk.dataLength; + tdata.selfTriangleChunk.Clear(); + } + + // Intersect + bool useIntersect = tdata.flag.TestAny(TeamManager.Flag_Self_EdgeTriangleIntersect, 6); + bool oldIntersect = oldFlag.TestAny(TeamManager.Flag_Self_EdgeTriangleIntersect, 6); + if (useIntersect && oldIntersect == false) + { + // init + IntersectCount++; // チーム利用カウント + } + else if (useIntersect == false && oldIntersect) + { + // remove + IntersectCount--; + } + + // 同期対象に対して再帰する + if (tdata.syncTeamId != 0 && tm.ContainsTeamData(tdata.syncTeamId)) + { + UpdateTeam(tdata.syncTeamId); + } + } + + /// + /// プリミティブ初期化 + /// + /// + /// + /// + /// + /// + 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, + + edges = vm.edges.GetNativeArray(), + triangles = vm.triangles.GetNativeArray(), + attributes = vm.attributes.GetNativeArray(), + vertexDepths = vm.vertexDepths.GetNativeArray(), + + primitiveArrayB = primitiveArrayB.GetNativeArray(), + }; + job.Run(length); // ここではRun()で実行する + } + + [BurstCompile] + struct InitPrimitiveJob : IJobParallelFor + { + public int teamId; + public TeamManager.TeamData tdata; + + public uint kind; + public int startPrimitive; + + // 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 primitiveArrayB; + + public void Execute(int index) + { + int pri_index = startPrimitive + index; + + var p = primitiveArrayB[pri_index]; + int pstart = tdata.particleChunk.startIndex; + + // プリミティブを構成するパーティクルインデックス + int3 particleIndices = -1; + if (kind == KindPoint) + { + particleIndices[0] = pstart + index; + } + else if (kind == KindEdge) + { + int estart = tdata.proxyEdgeChunk.startIndex; + particleIndices.xy = edges[estart + index] + pstart; + } + else if (kind == KindTriangle) + { + int tstart = tdata.proxyTriangleChunk.startIndex; + particleIndices.xyz = triangles[tstart + index] + pstart; + } + + // フラグなど + 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 = particleIndices[i]; + int vindex = tdata.proxyCommonChunk.startIndex + pindex - pstart; + var attr = attributes[vindex]; + if (attr.IsMove()) + flag &= ~fix_flag; + else + { + flag |= fix_flag; + fixcnt++; + } + fix_flag <<= 1; + if (attr.IsInvalid()) + ignore = true; + depth += vertexDepths[vindex]; + } + if (fixcnt == ac) + flag |= Flag_AllFix; + else + flag &= ~Flag_AllFix; + if (ignore) + flag |= Flag_Ignore; + depth /= ac; + + p.flag = (kind << 24) | flag; + p.particleIndices = particleIndices; + p.depth = depth; + p.grid = Define.System.SelfCollisionIgnoreGrid; // 無効グリッド + + primitiveArrayB[pri_index] = p; + + //Debug.Log($"pri[{pri_index}] p:{p.particleIndices}, {p.GetKind()}"); + } + } + + /// + /// 作業バッファ更新 + /// + internal void WorkBufferUpdate() + { + // 交差フラグバッファ + if (IntersectCount > 0) + { + int pcnt = MagicaManager.Simulation.ParticleCount; + intersectFlagArray.MC2Resize(pcnt, options: NativeArrayOptions.ClearMemory); + } + } + + //========================================================================================= + // Primitive + //========================================================================================= + [BurstCompile] + unsafe internal struct SelfStep_UpdatePrimitiveJob : IJobParallelFor + { + public int workerCount; + public int updateIndex; + public float4 simulationPower; + + // team + [Unity.Collections.ReadOnly] + public NativeList batchSelfTeamList; + [Unity.Collections.ReadOnly] + public NativeArray teamDataArray; + [Unity.Collections.ReadOnly] + public NativeArray parameterArray; + + // particle + [Unity.Collections.ReadOnly] + public NativeArray nextPosArray; + [Unity.Collections.ReadOnly] + public NativeArray oldPosArray; + [Unity.Collections.ReadOnly] + public NativeArray frictionArray; + + // self collision + public bool useIntersect; + [NativeDisableParallelForRestriction] + public NativeArray primitiveArrayB; + [Unity.Collections.ReadOnly] + public NativeArray intersectFlagArray; + + // バッチ内のローカルチームインデックスごと + // ワーカー分割(3固定) + public void Execute(int index) + { + // チームIDとワーカーID + int localIndex = index / workerCount; + int workerIndex = index % workerCount; + + // 各ベースポインタ + TeamManager.TeamData* teamPt = (TeamManager.TeamData*)teamDataArray.GetUnsafeReadOnlyPtr(); + ClothParameters* paramPt = (ClothParameters*)parameterArray.GetUnsafeReadOnlyPtr(); + + int teamId = batchSelfTeamList[localIndex]; + ref var tdata = ref *(teamPt + teamId); + ref var param = ref *(paramPt + teamId); + + if (updateIndex >= tdata.updateCount) + return; + if (tdata.IsProcess == false) + return; + if (tdata.ParticleCount == 0) + return; + + // セルフコリジョン + // ■プリミティブとグリッドの更新 + // 範囲 + //var chunk = MathUtility.GetWorkerChunk(tdata.particleChunk.dataLength, workerCount, workerIndex); + //if (chunk.IsValid) + { + UpdatePrimitive( + workerIndex, + // team + teamId, + ref tdata, + ref param, + // particle + ref nextPosArray, + ref oldPosArray, + ref frictionArray, + // self collisiotn + useIntersect, + ref primitiveArrayB, + ref intersectFlagArray + ); + } + } + } + + /// + /// ブロードフェーズ + /// プリミティブ更新 + /// + 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; + + // self collision + [Unity.Collections.ReadOnly] + public NativeArray primitiveArrayB; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray uniformGridStartCountBuffer; + + // バッチ内のローカルチームインデックスごと + // ワーカー分割(3固定) + public void Execute(int index) + { + // チームIDとワーカーID + int localIndex = index / kindCount; + int kindIndex = index % kindCount; + + // 各ベースポインタ + TeamManager.TeamData* teamPt = (TeamManager.TeamData*)teamDataArray.GetUnsafeReadOnlyPtr(); + + int teamId = batchSelfTeamList[localIndex]; + ref var tdata = ref *(teamPt + teamId); + + if (updateIndex >= tdata.updateCount) + return; + if (tdata.IsProcess == false) + return; + if (tdata.ParticleCount == 0) + return; + + // セルフコリジョン + // ■プリミティブとグリッドの更新(初回ステップのみ) + if (updateIndex == 0) + { + UpdateGrid( + kindIndex, + // team + teamId, + ref tdata, + // self collisiotn + ref primitiveArrayB, + ref uniformGridStartCountBuffer + ); + } + } + } + + 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) + + // ■プリミティブ更新 =================================================================== + 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) + ) + { + { + 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 priIndex = pc.startIndex; + for (int j = 0; j < pc.dataLength; j++, priIndex++) + { + 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}"); + } + } + } + } + + [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 NativeList batchSelfTeamList; + [Unity.Collections.ReadOnly] + public NativeArray teamDataArray; + + // 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 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) && stdata.IsProcess && stdata.ParticleCount > 0) + { + //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) + { + Primitive* pt = (Primitive*)primitiveArrayB.GetUnsafeReadOnlyPtr(); + ContactInfo* ct = (ContactInfo*)contactList.GetUnsafePtr(); + + ref ContactInfo contact = ref *(ct + index); + + // 反復計算用にコンタクト情報を更新する + 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 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; + + // 押出法線 + float3 n = (cA - cB) / clen; + + // 最近接点での変位 + var dA0 = nextPosA0 - oldPosA0; + var dA1 = nextPosA1 - oldPosA1; + var dB0 = nextPosB0 - oldPosB0; + var dB1 = nextPosB1 - oldPosB1; + 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; + if (l > (thickness + scr)) + return; + + // 有効 + contact.enable = 1; + contact.s = (half)s; + contact.t = (half)t; + contact.n = (half3)n; + } + else if (contact.contactType == ContactType_PointTriangle) + { + var nextPosA0 = nextPosArray[p0.particleIndices.x]; + var oldPosA0 = oldPosArray[p0.particleIndices.x]; + + 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 = nextPosA0 - oldPosA0; + var dB0 = nextPosB0 - oldPosB0; + var dB1 = nextPosB1 - oldPosB1; + var dB2 = nextPosB2 - oldPosB2; + + // 衝突予測と格納 + float3 cp; + // 移動前ポイントと移動前トライアングルへの最近接点 + cp = MathUtility.ClosestPtPointTriangle(oldPosA0, oldPosB0, oldPosB1, oldPosB2, out var uvw); + + // 最近接点座標の変位を求める + float3 dt = dB0 * uvw.x + dB1 * uvw.y + dB2 * uvw.z; + + // 最近接点ベクトル + float3 cv = cp - oldPosA0; + float cvlen = math.length(cv); + 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) + { + // 移動前トライアングル法線 + float3 otn = MathUtility.TriangleNormal(oldPosB0, oldPosB1, oldPosB2); + + // 移動前のパーティクル方向性 + 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; + + // 有効 + 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) + { + 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; + } + } + } + + // バッファクリア + int pindexB = tdata.particleChunk.startIndex; + for (int i = 0; i < tdata.particleChunk.dataLength; i++, pindexB++) + { + tempCountBuffer[pindexB] = 0; + tempVectorBufferA[pindexB] = 0; + } + } + } + + //========================================================================================= + // Intersect + //========================================================================================= + [BurstCompile] + unsafe internal struct SelfDetectionIntersectJob : IJobParallelFor + { + 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 (stdata.IsProcess && stdata.ParticleCount > 0) + { + 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; + + // self collision + [Unity.Collections.ReadOnly] + public NativeList intersectList; + + // buffer + [Unity.Collections.WriteOnly] + [NativeDisableParallelForRestriction] + public NativeArray intersectFlagArray; + + + public void Execute(int index) + { + IntersectInfo* it = (IntersectInfo*)intersectList.GetUnsafeReadOnlyPtr(); + + ref var intersect = ref *(it + index); + + // edge + float3 p = nextPosArray[intersect.edgeParticeIndices.x]; + float3 q = nextPosArray[intersect.edgeParticeIndices.y]; + + // triangle + float3 a = nextPosArray[intersect.triangleParticleIndices.x]; + float3 b = nextPosArray[intersect.triangleParticleIndices.y]; + float3 c = nextPosArray[intersect.triangleParticleIndices.z]; + + // Intersect test + // 線分とトライアングルの交差判定 + var qp = p - q; + + var ac = c - a; + var ab = b - a; + float3 n = math.cross(ab, ac); + + float d = math.dot(qp, n); + + // 水平は無効 + if (math.abs(d) < Define.System.Epsilon) + return; + + // 法線裏側からの侵入に対応 + if (d < 0.0f) + { + //p = epri.nextPos.c1; + p = q; + qp = -qp; + d = -d; + } + + var ap = p - a; + var t = math.dot(ap, n); + if (t < 0.0f) + return; + if (t > d) + return; + + float3 e = math.cross(qp, ap); + var v = math.dot(ac, e); + if (v < 0.0f || v > d) + return; + var w = -math.dot(ab, e); + if (w < 0.0f || (v + w) > d) + return; + + // !交差! + // Edgeにフラグを立てる + intersectFlagArray[intersect.edgeParticeIndices.x] = 1; + intersectFlagArray[intersect.edgeParticeIndices.y] = 1; + + // Triangleにはフラグは立てない + + //Debug.Log($"Intersect! edge:{p0.particleIndices.xyz}, tri:{p1.particleIndices.xyz}"); + } + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/Cloth/Constraints/SelfCollisionConstraint.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Cloth/Constraints/SelfCollisionConstraint.cs.meta new file mode 100644 index 00000000..dc83f97a --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Cloth/Constraints/SelfCollisionConstraint.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: b72668632a29f4f4687108fdf55561cc +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Cloth/Constraints/SelfCollisionConstraint.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Cloth/Constraints/SpringConstraint.cs b/Assets/MagicaCloth2/Scripts/Core/Cloth/Constraints/SpringConstraint.cs new file mode 100644 index 00000000..39968c8c --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Cloth/Constraints/SpringConstraint.cs @@ -0,0 +1,130 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp + +using System; +using UnityEngine; + +namespace MagicaCloth2 +{ + /// + /// スプリング制約 + /// 固定パーティクルにスプリングの機能を追加する + /// 現在はBoneSpringのみで利用 + /// + public class SpringConstraint : IDisposable + { + [System.Serializable] + public class SerializeData : IDataValidate + { + /// + /// Use of springs + /// スプリングの利用 + /// [OK] Runtime changes. + /// [OK] Export/Import with Presets + /// + public bool useSpring; + + /// + /// spring strength.(0.0 ~ 1.0) + /// スプリングの強さ(0.0 ~ 1.0) + /// [OK] Runtime changes. + /// [OK] Export/Import with Presets + /// + [Range(0.001f, 0.2f)] + public float springPower; + + /// + /// Distance that can be moved from the origin. + /// 原点から移動可能な距離 + /// [OK] Runtime changes. + /// [OK] Export/Import with Presets + /// + [Range(0.0f, 0.5f)] + public float limitDistance; + + /// + /// Movement restriction in normal direction.(0.0 ~ 1.0) + /// 法線方向に対しての移動制限(0.0 ~ 1.0) + /// [OK] Runtime changes. + /// [OK] Export/Import with Presets + /// + [Range(0.0f, 1.0f)] + public float normalLimitRatio; + + /// + /// De-synchronize each spring.(0.0 ~ 1.0) + /// 各スプリングの非同期化(0.0 ~ 1.0) + /// [OK] Runtime changes. + /// [OK] Export/Import with Presets + /// + [Range(0.0f, 1.0f)] + public float springNoise; + + public SerializeData() + { + useSpring = true; + springPower = 0.04f; + limitDistance = 0.1f; + normalLimitRatio = 1.0f; + springNoise = 0.0f; + } + + public void DataValidate() + { + springPower = Math.Clamp(springPower, 0.001f, 1.0f); + limitDistance = Mathf.Max(limitDistance, 0); + normalLimitRatio = Mathf.Clamp01(normalLimitRatio); + springNoise = Mathf.Clamp01(springNoise); + } + + public SerializeData Clone() + { + return new SerializeData() + { + useSpring = useSpring, + springPower = springPower, + limitDistance = limitDistance, + normalLimitRatio = normalLimitRatio, + springNoise = springNoise, + }; + } + } + + public struct SpringConstraintParams + { + /// + /// スプリングの強さ(0.0 ~ 1.0) + /// スプリング未使用時は0.0 + /// + public float springPower; + + /// + /// 原点からの移動制限距離 + /// + public float limitDistance; + + /// + /// 法線方向に対する移動制限 + /// + public float normalLimitRatio; + + /// + /// 各スプリングの非同期率(0.0 ~ 1.0) + /// + public float springNoise; + + public void Convert(SerializeData sdata, ClothProcess.ClothType clothType) + { + springPower = clothType == ClothProcess.ClothType.BoneSpring && sdata.useSpring ? sdata.springPower : 0.0f; + limitDistance = sdata.limitDistance; + normalLimitRatio = sdata.normalLimitRatio; + springNoise = sdata.springNoise; + } + } + + public void Dispose() + { + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/Cloth/Constraints/SpringConstraint.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Cloth/Constraints/SpringConstraint.cs.meta new file mode 100644 index 00000000..0fdcf4e9 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Cloth/Constraints/SpringConstraint.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 890580bb4f2b4c742a2c1b491e9a9e07 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Cloth/Constraints/SpringConstraint.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Cloth/Constraints/TetherConstraint.cs b/Assets/MagicaCloth2/Scripts/Core/Cloth/Constraints/TetherConstraint.cs new file mode 100644 index 00000000..46840a4a --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Cloth/Constraints/TetherConstraint.cs @@ -0,0 +1,203 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using System; +using Unity.Collections; +using Unity.Mathematics; +using UnityEngine; + +namespace MagicaCloth2 +{ + /// + /// 最大距離制約 + /// 移動パーティクルが移動できる距離を自身のルートパーティクルとの距離から制限する + /// + public class TetherConstraint : IDisposable + { + [System.Serializable] + public class SerializeData : IDataValidate + { + /// + /// Maximum shrink limit (0.0 ~ 1.0). + /// 0.0=do not shrink. + /// 最大縮小限界(0.0 ~ 1.0) + /// 0.0=縮小しない + /// [OK] Runtime changes. + /// [OK] Export/Import with Presets + /// + [Range(0.0f, 1.0f)] + public float distanceCompression; + + public SerializeData() + { + distanceCompression = 0.4f; + } + + public void DataValidate() + { + distanceCompression = Mathf.Clamp(distanceCompression, 0.0f, 1.0f); + } + + public SerializeData Clone() + { + return new SerializeData() + { + distanceCompression = distanceCompression, + }; + } + } + + public struct TetherConstraintParams + { + /// + /// 最大縮小割合(0.0 ~ 1.0) + /// 0.0=縮小しない + /// + public float compressionLimit; + + /// + /// 最大拡大割合(0.0 ~ 1.0) + /// 0.0=拡大しない + /// + public float stretchLimit; + + public void Convert(SerializeData sdata, ClothProcess.ClothType clothType) + { + switch (clothType) + { + case ClothProcess.ClothType.BoneCloth: + case ClothProcess.ClothType.MeshCloth: + compressionLimit = sdata.distanceCompression; + break; + case ClothProcess.ClothType.BoneSpring: + // BoneSpringは定数 + compressionLimit = Define.System.BoneSpringTetherCompressionLimit; + break; + } + stretchLimit = Define.System.TetherStretchLimit; + } + } + + public void Dispose() + { + } + + //========================================================================================= + // Solver + //========================================================================================= + internal static void SolverConstraint( + DataChunk chunk, + // team + ref TeamManager.TeamData tdata, + ref ClothParameters param, + ref InertiaConstraint.CenterData cdata, + // vmesh + ref NativeArray attributes, + ref NativeArray vertexDepths, + ref NativeArray vertexRootIndices, + // particle + ref NativeArray nextPosArray, + ref NativeArray velocityPosArray, + ref NativeArray frictionArray, + // buffer + 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++) + { + var attr = attributes[vindex]; + if (attr.IsMove() == false) + continue; + + int rootIndex = vertexRootIndices[vindex]; + if (rootIndex < 0) + continue; + + //Debug.Log($"Tether [{pindex}] root:{rootIndex + p_start}"); + + var nextPos = nextPosArray[pindex]; + var rootPos = nextPosArray[rootIndex + p_start]; + float depth = vertexDepths[vindex]; + float friction = frictionArray[pindex]; + //float invMass = MathUtility.CalcInverseMass(friction); + + // 現在のベクトル + float3 v = rootPos - nextPos; + + // 現在の長さ + float distance = math.length(v); + + // 距離がほぼ0ならば処理をスキップする(エラーの回避) + if (distance < Define.System.Epsilon) + continue; + + // 復元距離 + // フラグにより初期姿勢かアニメーション後姿勢かを切り替える + float3 calcPos = stepBasicPositionBuffer[pindex]; + float3 calcRootPos = stepBasicPositionBuffer[rootIndex + p_start]; + float calcDistance = math.distance(calcPos, calcRootPos); + + //Debug.Log($"[{pindex}] calcPos:{calcPos}, calcRootPos:{calcRootPos}, calcDistance:{calcDistance}"); + + // 初期位置がまったく同じ状況を考慮 + if (calcDistance == 0.0f) + continue; + + // 現在の伸縮割合 + //Develop.Assert(calcDistance > 0.0f); + float ratio = distance / calcDistance; +#if true + // 距離が範囲内なら伸縮しない + float dist = 0; + float stiffness; + float attn; + 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) + { + // 縮んでいる場合は戻りを比較的緩やかにする。これは振動の防止につながる。 + dist = distance - compressionLimit * calcDistance; + float t = math.saturate((compressionLimit - ratio) / Define.System.TetherStiffnessWidth); + stiffness = Define.System.TetherCompressionStiffness * t; + //stiffness = Define.System.TetherCompressionStiffness; + attn = Define.System.TetherCompressionVelocityAttenuation; + } + else if (ratio > stretchLimit) + { + // 伸びている場合は戻りを急速に行う。その代わり速度影響は弱くする。 + dist = distance - stretchLimit * calcDistance; + float t = math.saturate((ratio - stretchLimit) / Define.System.TetherStiffnessWidth); + stiffness = Define.System.TetherStretchStiffness * t; + //stiffness = Define.System.TetherStretchStiffness; + attn = Define.System.TetherStretchVelocityAttenuation; + } + else + continue; + + // 移動量 + float3 add = (v / distance) * (dist * stiffness); +#endif + + // 摩擦による移動減衰 + //add *= invMass; + + // 位置 + var oldPos = nextPos; + nextPos += add; + nextPosArray[pindex] = nextPos; + + // 速度影響 + //float attn = param.velocityAttenuation; + velocityPosArray[pindex] = velocityPosArray[pindex] + add * attn; + } + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/Cloth/Constraints/TetherConstraint.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Cloth/Constraints/TetherConstraint.cs.meta new file mode 100644 index 00000000..eee9a2ba --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Cloth/Constraints/TetherConstraint.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: c071eb1b529a69546be39d4575fffd86 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Cloth/Constraints/TetherConstraint.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Cloth/Constraints/TriangleBendingConstraint.cs b/Assets/MagicaCloth2/Scripts/Core/Cloth/Constraints/TriangleBendingConstraint.cs new file mode 100644 index 00000000..4a498f1b --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Cloth/Constraints/TriangleBendingConstraint.cs @@ -0,0 +1,738 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using System; +using System.Collections.Generic; +using System.Text; +using Unity.Collections; +using Unity.Collections.LowLevel.Unsafe; +using Unity.Mathematics; +using UnityEngine; + +namespace MagicaCloth2 +{ + /// + /// トライアングル曲げ制約 + /// + public class TriangleBendingConstraint : IDisposable + { + /// + /// ボリュームとして処理する判定フラグ + /// + const sbyte VOLUME_SIGN = 100; + + public enum Method + { + None = 0, + + /// + /// 2面角による曲げ制御 + /// 2面は初期の角度を保つように移動する。ただし角度のみなので±の近い方に曲る。 + /// + DihedralAngle = 1, + + /// + /// 方向性ありの2面角曲げ制約 + /// 初期姿勢を保つように復元する + /// + DirectionDihedralAngle = 2, + } + + [System.Serializable] + public class SerializeData : IDataValidate + { + /// + /// Restoring force (0.0 ~ 1.0) + /// [OK] Runtime changes. + /// [OK] Export/Import with Presets + /// + [Range(0.0f, 1.0f)] + public float stiffness; + + public SerializeData() + { + //method = Method.DirectionDihedralAngle; + stiffness = 1.0f; + } + + public void DataValidate() + { + stiffness = Mathf.Clamp01(stiffness); + } + + public SerializeData Clone() + { + return new SerializeData() + { + //method = method, + stiffness = stiffness, + }; + } + } + + public struct TriangleBendingConstraintParams + { + public Method method; + public float stiffness; + + public void Convert(SerializeData sdata) + { + // モードはDirectionDihedralAngleに固定する + method = sdata.stiffness > Define.System.Epsilon ? Method.DirectionDihedralAngle : Method.None; + //method = sdata.stiffness > Define.System.Epsilon ? Method.DihedralAngle : Method.None; + + stiffness = sdata.stiffness; + } + } + + //========================================================================================= + [System.Serializable] + public class ConstraintData : IValid + { + public ResultCode result; + public ulong[] trianglePairArray; + public float[] restAngleOrVolumeArray; + public sbyte[] signOrVolumeArray; + + public int writeBufferCount; + public uint[] writeDataArray; + public uint[] writeIndexArray; + + public bool IsValid() + { + return trianglePairArray != null && trianglePairArray.Length > 0; + } + } + + /// + /// トライアングルペアの4頂点をushortとしてulongにパッキングしたもの + /// v2 + + /// /|\ + /// v0 + | + v1 + /// \|/ + /// v3 + + /// 上位ビットからv0-v1-v2-v3の順で並んでいる + /// + public ExNativeArray trianglePairArray; + + /// + /// トライアングルペアごとの復元角度もしくはボリューム値 + /// + public ExNativeArray restAngleOrVolumeArray; + + /// + /// トライアングルペアごとの復元方向もしくはボリューム判定(VOLUME_SIGN(100)=このペアはボリュームである) + /// + public ExNativeArray signOrVolumeArray; + + //public int DataCount => trianglePairArray?.Count ?? 0; + + /// + /// ボリューム計算の浮動小数点誤差を回避するための倍数 + /// + const float VolumeScale = 1000.0f; + + //========================================================================================= + public TriangleBendingConstraint() + { + trianglePairArray = new ExNativeArray(0, true); + restAngleOrVolumeArray = new ExNativeArray(0, true); + signOrVolumeArray = new ExNativeArray(0, true); + } + + public void Dispose() + { + trianglePairArray?.Dispose(); + restAngleOrVolumeArray?.Dispose(); + signOrVolumeArray?.Dispose(); + + trianglePairArray = null; + restAngleOrVolumeArray = null; + signOrVolumeArray = null; + } + + public override string ToString() + { + StringBuilder sb = new StringBuilder(); + sb.AppendLine($"[TriangleBendConstraint]"); + sb.AppendLine($" -trianglePairArray:{trianglePairArray.ToSummary()}"); + sb.AppendLine($" -restAngleOrVolumeArray:{restAngleOrVolumeArray.ToSummary()}"); + sb.AppendLine($" -signOrVolumeArray:{signOrVolumeArray.ToSummary()}"); + + return sb.ToString(); + } + + //========================================================================================= + /// + /// 制約データの作成 + /// + /// + /// + /// + public static ConstraintData CreateData(VirtualMesh proxyMesh, in ClothParameters parameters) + { + var constraintData = new ConstraintData(); + + try + { + // アルゴリズムの有無にかかわらずトライアングルがあるなら生成する + //var method = parameters.triangleBendingConstraint.method; + //if (method == Method.None) + // return null; + + if (proxyMesh.TriangleCount == 0) + return null; + + int ecnt = proxyMesh.EdgeCount; + if (ecnt == 0) + return null; + + var trianglePairList = new List(ecnt * 2); + var restAngleOrVolumeList = new List(ecnt * 2); + var signOrVolumeList = new List(ecnt * 2); + var writeDataList = new List(ecnt * 2); + var volumeSet = new HashSet(); + + int bendingCount = 0; + int volumeCount = 0; + + int vcnt = proxyMesh.VertexCount; + using var multiBuilder = new MultiDataBuilder(vcnt, vcnt * 2); + + // エッジごとの接続トライアングルをループ + for (int k = 0; k < ecnt; k++) + { + int2 edge = proxyMesh.edges[k]; + if (proxyMesh.edgeToTriangles.ContainsKey(edge) == false) + continue; + + var triangles = proxyMesh.edgeToTriangles.MC2ToFixedList128Bytes(edge); + int tcnt = triangles.Length; + + // トライアングルの組み合わせ + for (int i = 0; i < tcnt - 1; i++) + { + // 0 + int tindex0 = triangles[i]; + int3 tri0 = proxyMesh.triangles[tindex0]; + + for (int j = i + 1; j < tcnt; j++) + { + // 1 + int tindex1 = triangles[j]; + int3 tri1 = proxyMesh.triangles[tindex1]; + + // 対角点 + int2 dp = MathUtility.GetRestTriangleVertex(tri0, tri1, edge); + + // 4点の構成 + // 頂点インデックス形成 + // v2 + + // /|\ + // v0 + | + v1 + // \|/ + // v3 + + // 2/3が共通の辺, 0/1が対角点 + int4 vtx = new int4(dp.x, dp.y, edge.x, edge.y); + + // 4点がすべて固定ならば除外する + var attr0 = proxyMesh.attributes[vtx.x]; + var attr1 = proxyMesh.attributes[vtx.y]; + var attr2 = proxyMesh.attributes[vtx.z]; + var attr3 = proxyMesh.attributes[vtx.w]; + if (attr0.IsDontMove() && attr1.IsDontMove() && attr2.IsDontMove() && attr3.IsDontMove()) + continue; + + // 1点でも無効なら除外する + if (attr0.IsInvalid() || attr1.IsInvalid() || attr2.IsInvalid() || attr3.IsInvalid()) + continue; + + ulong pair = DataUtility.Pack64(vtx); + + // (1)TriangleBendingとして登録判定 + float restData; + sbyte signFlag; + InitDihedralAngle(proxyMesh, vtx.x, vtx.y, vtx.z, vtx.w, out restData, out signFlag); + var degAngle = math.abs(math.degrees(restData)); + if (degAngle < Define.System.TriangleBendingMaxAngle) // 90度以上で登録すると不安定になる + { + 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), + multiBuilder.CountValuesForKey(vtx.y), + multiBuilder.CountValuesForKey(vtx.z), + multiBuilder.CountValuesForKey(vtx.w) + ); + writeDataList.Add(writeData); + + multiBuilder.Add(vtx.x, 0); + multiBuilder.Add(vtx.y, 0); + multiBuilder.Add(vtx.z, 0); + multiBuilder.Add(vtx.w, 0); + + bendingCount++; + } + // (2)Volumeとして登録判定 + if (degAngle >= Define.System.VolumeMinAngle && degAngle <= 179.0f) + { + var sortPack = DataUtility.PackInt4(vtx); + if (volumeSet.Contains(sortPack) == false) + { + + InitVolume(proxyMesh, vtx.x, vtx.y, vtx.z, vtx.w, out restData, out signFlag); + trianglePairList.Add(pair); + restAngleOrVolumeList.Add(restData); + signOrVolumeList.Add(signFlag); + volumeSet.Add(sortPack); + + uint writeData = DataUtility.Pack32( + multiBuilder.CountValuesForKey(vtx.x), + multiBuilder.CountValuesForKey(vtx.y), + multiBuilder.CountValuesForKey(vtx.z), + multiBuilder.CountValuesForKey(vtx.w) + ); + writeDataList.Add(writeData); + + multiBuilder.Add(vtx.x, 0); + multiBuilder.Add(vtx.y, 0); + multiBuilder.Add(vtx.z, 0); + multiBuilder.Add(vtx.w, 0); + + volumeCount++; + + //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) + // Debug.Log($"Bend Triangle Pair. edge:{edge}, tri:({tri0},{tri1})"); + } + } + } + + // データ格納 + constraintData.trianglePairArray = trianglePairList.Count > 0 ? trianglePairList.ToArray() : null; + constraintData.restAngleOrVolumeArray = restAngleOrVolumeList.Count > 0 ? restAngleOrVolumeList.ToArray() : null; + constraintData.signOrVolumeArray = signOrVolumeList.Count > 0 ? signOrVolumeList.ToArray() : null; + constraintData.writeDataArray = writeDataList.Count > 0 ? writeDataList.ToArray() : null; + constraintData.writeBufferCount = multiBuilder.Count(); + constraintData.writeIndexArray = multiBuilder.ToIndexArray(); + + constraintData.result.SetSuccess(); + + //Develop.DebugLog($"TriangleBending:{bendingCount}, Volume:{volumeCount}"); + } + catch (Exception exception) + { + Debug.LogError(exception); + constraintData.result.SetError(Define.Result.Constraint_CreateTriangleBendingException); + throw; + } + finally + { + } + + return constraintData; + } + + 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 = 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); + 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) + { + // 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 n1 = math.cross(pos2 - pos0, pos3 - pos0); + float3 n2 = math.cross(pos3 - pos1, pos2 - pos1); + n1 = math.normalize(n1); + n2 = math.normalize(n2); + float dot = math.dot(n1, n2); + dot = MathUtility.Clamp1(dot); + + restAngle = math.acos(dot); + + // 方向性の算出 + // 復元方向を正負のフラグとして格納する + float3 e = pos3 - pos2; + float dir = math.dot(math.cross(n1, n2), e); + float sign = math.sign(dir); + //Debug.Assert(sign != 0); + //dihedralRestAngle *= sign; + + signFlag = sign < 0 ? (sbyte)-1 : (sbyte)1; + } + + //========================================================================================= + /// + /// 制約データを登録する + /// + /// + internal void Register(ClothProcess cprocess) + { + if (cprocess?.bendingConstraintData?.IsValid() ?? false) + { + ref var tdata = ref MagicaManager.Team.GetTeamDataRef(cprocess.TeamId); + + var cdata = cprocess.bendingConstraintData; + tdata.bendingPairChunk = trianglePairArray.AddRange(cdata.trianglePairArray); + restAngleOrVolumeArray.AddRange(cdata.restAngleOrVolumeArray); + signOrVolumeArray.AddRange(cdata.signOrVolumeArray); + } + } + + /// + /// 制約データを解除する + /// + /// + internal void Exit(ClothProcess cprocess) + { + if (cprocess != null && cprocess.TeamId > 0) + { + ref var tdata = ref MagicaManager.Team.GetTeamDataRef(cprocess.TeamId); + + trianglePairArray.Remove(tdata.bendingPairChunk); + restAngleOrVolumeArray.Remove(tdata.bendingPairChunk); + signOrVolumeArray.Remove(tdata.bendingPairChunk); + + tdata.bendingPairChunk.Clear(); + } + } + + //========================================================================================= + // Solver + //========================================================================================= + internal unsafe static void SolverConstraint( + DataChunk chunk, + in float4 simulationPower, + // team + ref TeamManager.TeamData tdata, + ref ClothParameters param, + // vmesh + ref NativeArray attributes, + ref NativeArray depthArray, + // particle + ref NativeArray nextPosArray, + ref NativeArray frictionArray, + // constraints + ref NativeArray trianglePairArray, + ref NativeArray restAngleOrVolumeArray, + ref NativeArray signOrVolumeArray, + // 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; + 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++) + { + // トライアングルペア + 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; + for (int i = 0; i < 4; i++) + { + pindex = pindex4[i]; + vindex = vindex4[i]; + nextPosBuffer[i] = nextPosArray[pindex]; + float friction = frictionArray[pindex]; + float depth = depthArray[vindex]; + bool fix = attributes[vindex].IsDontMove(); + invMassBuffer[i] = fix ? 0.01f : MathUtility.CalcInverseMass(friction, depth); + } + + // データ + int l_index = pairIndex - tdata.bendingPairChunk.startIndex; + int dataIndex = tdata.bendingPairChunk.startIndex + l_index; + float restAngle = restAngleOrVolumeArray[dataIndex]; + sbyte signOrVolume = signOrVolumeArray[dataIndex]; + + // メソッドごとの解決 + bool result = false; + if (signOrVolume == VOLUME_SIGN) + { + // Volume + float volumeRest = restAngle * tdata.scaleRatio; // スケール倍率 + + // マイナススケール + volumeRest *= tdata.negativeScaleSign; + + result = CalcVolume(nextPosBuffer, invMassBuffer, volumeRest, stiffness, ref addPosBuffer); + } + else + { + // Triangle Bending + if (param.triangleBendingConstraint.method == Method.DihedralAngle) + { + // 方向性なし二面角 + result = CalcDihedralAngle(0, nextPosBuffer, invMassBuffer, restAngle, stiffness, ref addPosBuffer); + } + else if (param.triangleBendingConstraint.method == Method.DirectionDihedralAngle) + { + // 方向性あり二面角 + float sign = signOrVolume < 0 ? -1 : 1; + restAngle *= sign; + + // マイナススケール + restAngle *= tdata.negativeScaleSign; + + result = CalcDihedralAngle(sign, nextPosBuffer, invMassBuffer, restAngle, stiffness, ref addPosBuffer); + } + } + + // 集計バッファへ格納 + if (result) + { + for (int i = 0; i < 4; i++) + { + pindex = pindex4[i]; + InterlockUtility.AddFloat3(pindex, addPosBuffer[i], cntPt, sumPt); + } + } + } + } + + 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++) + { + // 移動のみ + if (attributes[vindex].IsDontMove() == false) + { + 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; + } + } + + // バッファクリア + tempCountBuffer[pindex] = 0; + tempVectorBufferA[pindex] = 0; + } + } + + static bool CalcVolume( + in float3x4 nextPosBuffer, + in float4 invMassBuffer, + float volumeRest, + 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]; + + float volume = (1.0f / 6.0f) * math.dot(math.cross(nextPos1 - nextPos0, nextPos2 - nextPos0), nextPos3 - nextPos0); + volume *= VolumeScale; // 浮動小数点演算誤差回避 + + 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); + lambda *= VolumeScale; // 浮動小数点演算誤差回避 + + 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) + { + // 方向性あり(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/MagicaCloth2/Scripts/Core/Cloth/Constraints/TriangleBendingConstraint.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Cloth/Constraints/TriangleBendingConstraint.cs.meta new file mode 100644 index 00000000..cf53b197 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Cloth/Constraints/TriangleBendingConstraint.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 8932223289542744aa07b8c5b25852ad +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Cloth/Constraints/TriangleBendingConstraint.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Cloth/CullingSettings.cs b/Assets/MagicaCloth2/Scripts/Core/Cloth/CullingSettings.cs new file mode 100644 index 00000000..831413c1 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Cloth/CullingSettings.cs @@ -0,0 +1,162 @@ +// Magica Cloth 2. +// Copyright (c) 2025 MagicaSoft. +// https://magicasoft.jp +using System.Collections.Generic; +using UnityEngine; + +namespace MagicaCloth2 +{ + [System.Serializable] + public class CullingSettings : IDataValidate + { + /// + /// Camera culling mode. + /// カメラカリングモード + /// + public enum CameraCullingMode + { + /// + /// No culling. + /// カリングは行わない + /// + Off = 0, + + /// + /// Simulation resets when hidden from camera. + /// カメラから非表示になるとシミュレーションはリセットされる + /// + Reset = 10, + + /// + /// Simulation pauses when hidden from camera. + /// カメラから非表示になるとシミュレーションは一時停止する + /// + Keep = 20, + + /// + /// Automatically set from linked animator. + /// 連動アニメーターから自動設定する + /// - Animator.CullingMode.AlwaysAnimate -> Off + /// - Animator.CullingMode.CullUpdateTransforms -> Reset + /// - Animator.CullingMode.CullCompletely -> Keep + /// + AnimatorLinkage = 30, + } + + /// + /// Camera culling method. + /// カリング方式 + /// + public enum CameraCullingMethod + { + /// + /// Work with an animator. + /// アニメーターと連動する + /// + AutomaticRenderer = 0, + + /// + /// Determine from user-specified renderer. + /// ユーザー指定のレンダラーから判定する + /// + ManualRenderer = 10, + } + + /// + /// Camera culling mode. + /// カメラカリングモード + /// [OK] Runtime changes. + /// [NG] Export/Import with Presets + /// + public CameraCullingMode cameraCullingMode = CameraCullingMode.AnimatorLinkage; + + /// + /// Camera culling judgment method. + /// カメラカリング判定方式 + /// [OK] Runtime changes. + /// [NG] Export/Import with Presets + /// + public CameraCullingMethod cameraCullingMethod = CameraCullingMethod.AutomaticRenderer; + + /// + /// User-specified camera culling judgment renderer. + /// ユーザー指定のカメラカリング判定用レンダラー + /// [OK] Runtime changes. + /// [NG] Export/Import with Presets + /// + 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() + { + return new CullingSettings() + { + cameraCullingMode = cameraCullingMode, + cameraCullingMethod = cameraCullingMethod, + cameraCullingRenderers = new List(cameraCullingRenderers), + distanceCullingLength = distanceCullingLength.Clone(), + distanceCullingFadeRatio = distanceCullingFadeRatio, + distanceCullingReferenceObject = distanceCullingReferenceObject, + }; + } + + /// + /// エディタメッシュの更新を判定するためのハッシュコード + /// (このハッシュは実行時には利用されない編集用のもの) + /// + /// + public override int GetHashCode() => 0; + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/Cloth/CullingSettings.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Cloth/CullingSettings.cs.meta new file mode 100644 index 00000000..4701a70a --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Cloth/CullingSettings.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 701eba9d7e8713a4da1b475eb5d89a76 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Cloth/CullingSettings.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Cloth/CurveSerializeData.cs b/Assets/MagicaCloth2/Scripts/Core/Cloth/CurveSerializeData.cs new file mode 100644 index 00000000..9d441069 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Cloth/CurveSerializeData.cs @@ -0,0 +1,122 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using Unity.Mathematics; +using UnityEngine; + +namespace MagicaCloth2 +{ + [System.Serializable] + public class CurveSerializeData + { + /// + /// Basic value. + /// + public float value; + + /// + /// Use of curves. + /// + public bool useCurve; + + /// + /// Animation curve. + /// + public AnimationCurve curve = AnimationCurve.Linear(0.0f, 1.0f, 1.0f, 1.0f); + + public CurveSerializeData() + { + } + + public CurveSerializeData(float value) + { + this.value = value; + useCurve = false; + curve = AnimationCurve.Linear(0.0f, 1.0f, 1.0f, 1.0f); + } + + public CurveSerializeData(float value, float curveStart, float curveEnd, bool useCurve = true) + { + this.value = value; + this.useCurve = useCurve; + curve = AnimationCurve.Linear(0.0f, Mathf.Clamp01(curveStart), 1.0f, Mathf.Clamp01(curveEnd)); + } + + public CurveSerializeData(float value, AnimationCurve curve) + { + this.value = value; + useCurve = true; + this.curve = curve; + } + + public void SetValue(float value) + { + this.value = value; + useCurve = false; + } + + public void SetValue(float value, float curveStart, float curveEnd, bool useCurve = true) + { + this.value = value; + this.useCurve = useCurve; + curve = AnimationCurve.Linear(0.0f, Mathf.Clamp01(curveStart), 1.0f, Mathf.Clamp01(curveEnd)); + } + + public void SetValue(float value, AnimationCurve curve) + { + this.value = value; + useCurve = true; + this.curve = curve; + } + + public void DataValidate(float min, float max) + { + value = Mathf.Clamp(value, min, max); + } + + /// + /// Get the current value of Time(0.0 ~ 1.0). + /// + /// + /// + public float Evaluate(float time) + { + if (useCurve) + return curve.Evaluate(time) * value; + else + return value; + } + + /// + /// カーブ情報をジョブで利用するための16個のfloat配列(float4x4)に変換して返す + /// Convert the curve information into a 16 float array (float4x4) for use in the job and return it. + /// + /// + public float4x4 ConvertFloatArray() + { + if (useCurve) + { + return DataUtility.ConvertAnimationCurve(curve) * value; + } + else + { + return value; + } + } + + public CurveSerializeData Clone() + { + var cdata = new CurveSerializeData() + { + value = value, + useCurve = useCurve, + }; + var c = new AnimationCurve(curve.keys); + c.preWrapMode = curve.preWrapMode; + c.postWrapMode = curve.postWrapMode; + cdata.curve = c; + + return cdata; + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/Cloth/CurveSerializeData.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Cloth/CurveSerializeData.cs.meta new file mode 100644 index 00000000..8a1cd969 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Cloth/CurveSerializeData.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 9f7735bfb35f7314db881831c265ae81 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Cloth/CurveSerializeData.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Cloth/CustomSkinningSettings.cs b/Assets/MagicaCloth2/Scripts/Core/Cloth/CustomSkinningSettings.cs new file mode 100644 index 00000000..3cec209c --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Cloth/CustomSkinningSettings.cs @@ -0,0 +1,100 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using System.Collections.Generic; +using System.Linq; +using UnityEngine; + +namespace MagicaCloth2 +{ + [System.Serializable] + public class CustomSkinningSettings : IValid, IDataValidate, ITransform + { + /// + /// valid state. + /// 有効状態 + /// [NG] Runtime changes. + /// [NG] Export/Import with Presets + /// + public bool enable = false; + + /// + /// Bones for custom skinning. + /// カスタムスキニング用ボーン + /// [NG] Runtime changes. + /// [NG] Export/Import with Presets + /// + public List skinningBones = new List(); + + public void DataValidate() + { + //angularAttenuation = Mathf.Clamp01(angularAttenuation); + //distanceReduction = Mathf.Clamp01(distanceReduction); + //distancePow = Mathf.Clamp(distancePow, 0.1f, 5.0f); + } + + public bool IsValid() + { + if (enable == false) + return false; + if (skinningBones.Count == 0) + return false; + if (skinningBones.Any(n => n != null) == false) + return false; + + return true; + } + + public CustomSkinningSettings Clone() + { + return new CustomSkinningSettings() + { + enable = enable, + skinningBones = new List(skinningBones), + }; + } + + /// + /// エディタメッシュの更新を判定するためのハッシュコード + /// (このハッシュは実行時には利用されない編集用のもの) + /// + /// + public override int GetHashCode() + { + int hash = 0; + + // おそらくカスタムスキニングは不要 +#if false + hash += enable.GetHashCode() * 101; + hash += angularAttenuation.GetHashCode(); + hash += distanceReduction.GetHashCode(); + hash += distancePow.GetHashCode(); + foreach (var t in skinningBones) + hash += t?.GetInstanceID() ?? 0; +#endif + + return hash; + } + + public void GetUsedTransform(HashSet transformSet) + { + foreach (var t in skinningBones) + { + if (t) + transformSet.Add(t); + } + } + + public void ReplaceTransform(Dictionary replaceDict) + { + for (int i = 0; i < skinningBones.Count; i++) + { + var t = skinningBones[i]; + if (t && replaceDict.ContainsKey(t.GetMagicaId())) + { + skinningBones[i] = replaceDict[t.GetMagicaId()]; + } + } + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/Cloth/CustomSkinningSettings.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Cloth/CustomSkinningSettings.cs.meta new file mode 100644 index 00000000..cebb733f --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Cloth/CustomSkinningSettings.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 93141a4088f5d094b95f02f4d362ea4f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Cloth/CustomSkinningSettings.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Cloth/GizmoSerializeData.cs b/Assets/MagicaCloth2/Scripts/Core/Cloth/GizmoSerializeData.cs new file mode 100644 index 00000000..433409b3 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Cloth/GizmoSerializeData.cs @@ -0,0 +1,36 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp + +namespace MagicaCloth2 +{ + /// + /// MagicaClothコンポーネントのギズモ表示用シリアライズデータ + /// + [System.Serializable] + public class GizmoSerializeData + { + public bool always = false; + + // Cloth + public ClothDebugSettings clothDebugSettings = new ClothDebugSettings(); + + // Virtual Mesh. これはデバッグ用 +#if MC2_DEBUG + public VirtualMeshDebugSettings proxyDebugSettings = new VirtualMeshDebugSettings(); + public VirtualMeshDebugSettings mappingDebugSettings = new VirtualMeshDebugSettings(); + public int debugMappingIndex = 0; +#endif // MC2_DEBUG + + public GizmoSerializeData() + { + clothDebugSettings.enable = true; + clothDebugSettings.shape = true; + } + + public bool IsAlways() + { + return always; + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/Cloth/GizmoSerializeData.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Cloth/GizmoSerializeData.cs.meta new file mode 100644 index 00000000..1a673a2a --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Cloth/GizmoSerializeData.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 599ae32263dff354aa87f60fe8748dd8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Cloth/GizmoSerializeData.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Cloth/MagicaCloth.cs b/Assets/MagicaCloth2/Scripts/Core/Cloth/MagicaCloth.cs new file mode 100644 index 00000000..4ad84f26 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Cloth/MagicaCloth.cs @@ -0,0 +1,142 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using UnityEngine; + +namespace MagicaCloth2 +{ + /// + /// MagicaCloth main component. + /// + [AddComponentMenu("MagicaCloth2/MagicaCloth")] + [HelpURL("https://magicasoft.jp/en/mc2_magicaclothcomponent/")] + public partial class MagicaCloth : ClothBehaviour, IValid + { + /// + /// Serialize data (1). + /// Basic parameters. + /// Import/export target. + /// Can be rewritten at runtime. + /// + [SerializeField] + private ClothSerializeData serializeData = new ClothSerializeData(); + public ClothSerializeData SerializeData => serializeData; + + /// + /// Serialize data (2). + /// Hidden data that cannot be rewritten at runtime + /// + [SerializeField] + internal ClothSerializeData2 serializeData2 = new ClothSerializeData2(); + +#if UNITY_EDITOR + /// + /// Gizmo display specification when editing. + /// + [SerializeField] + private GizmoSerializeData gizmoSerializeData = new GizmoSerializeData(); + public GizmoSerializeData GizmoSerializeData => gizmoSerializeData; +#endif + + /// + /// General processing. + /// + private ClothProcess process = new ClothProcess(); + public ClothProcess Process + { + get + { + process.cloth = this; + return process; + } + } + + /// + /// Cloth component transform. + /// Proxy meshes and selection data are managed in this space. + /// + public Transform ClothTransform => transform; + + /// + /// Synchronization target. + /// + 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. + /// クロスコンポーネントが有効な状態か確認します。 + /// + /// + public bool IsValid() + { + return MagicaManager.IsPlaying() && Process.IsValid() && Process.TeamId > 0; + } + + //========================================================================================= + protected void Reset() + { +#if UNITY_EDITOR + // Automatically generate pre-build ID + serializeData2.preBuildData.buildId = PreBuildSerializeData.GenerateBuildID(); +#endif + } + + protected void OnValidate() + { + Process.DataUpdate(); + } + + protected void Awake() + { + if (MagicaManager.initializationLocation == MagicaManager.InitializationLocation.Awake) + { + Process.Init(); + MagicaManager.Team.RemoveMonitoringProcess(Process); + } + } + + protected void OnEnable() + { + Process.StartUse(); + } + + protected void OnDisable() + { + Process.EndUse(); + } + + protected void Start() + { + if (MagicaManager.initializationLocation == MagicaManager.InitializationLocation.Start) + { + Process.Init(); + MagicaManager.Team.RemoveMonitoringProcess(Process); + } + + Process.AutoBuild(); + } + + protected void OnDestroy() + { + Process.Dispose(); + } + + /// + /// Hash code for checking changes when editing. + /// + /// + public override int GetMagicaHashCode() + { + int hash = SerializeData.GetHashCode() + serializeData2.GetHashCode(); + hash += isActiveAndEnabled ? this.GetMagicaId().GetHashCode() : 0; // component active. + return hash; + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/Cloth/MagicaCloth.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Cloth/MagicaCloth.cs.meta new file mode 100644 index 00000000..6ad388c1 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Cloth/MagicaCloth.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: bdbd3ce05f5b45942b56ede5c9b38364 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 5 + icon: {fileID: 2800000, guid: cf7e3400035e987478c3a19e57b4cf75, type: 3} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Cloth/MagicaCloth.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Cloth/MagicaClothAPI.cs b/Assets/MagicaCloth2/Scripts/Core/Cloth/MagicaClothAPI.cs new file mode 100644 index 00000000..1ccaebb7 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Cloth/MagicaClothAPI.cs @@ -0,0 +1,353 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using System; +using System.Collections.Generic; +using UnityEngine; + +namespace MagicaCloth2 +{ + public partial class MagicaCloth + { + /// + /// シリアライズデータ2の取得 + /// SerializeData2クラスはシステムが利用するパラメータクラスです。 + /// そのためユーザーによる変更は推奨されていません。 + /// + /// Acquisition of SerializedData2. + /// The SerializeData2 class is a parameter class used by the system. + /// Therefore, user modification is not recommended. + /// + /// + public ClothSerializeData2 GetSerializeData2() + { + return serializeData2; + } + + /// + /// クロスデータ構築完了後イベント + /// Event after completion of cloth data construction. + /// (true = Success, false = Failure) + /// + public Action OnBuildComplete; + + /// + /// レンダラーメッシュ変更後イベント + /// Renderer mesh change event. + /// (true = Change to custom mesh, false = Change to original mesh) + /// + public Action OnRendererMeshChange; + + /// + /// 初期化を実行します + /// すでに初期化済みの場合は何もしません。 + /// perform initialization. + /// If already initialized, do nothing. + /// + public void Initialize() + { + if (Application.isPlaying == false) + return; + + Process.Init(); + } + + /// + /// コンポーネントのStart()で実行される自動ビルドを無効にします + /// Disable automatic builds that run on the component's Start(). + /// + public void DisableAutoBuild() + { + if (Application.isPlaying == false) + return; + + Process.SetState(ClothProcess.State_DisableAutoBuild, true); + } + + /// + /// コンポーネントを構築し実行します + /// すべてのデータをセットアップしたあとに呼び出す必要があります + /// build and run the component. + /// Must be called after setting up all data. + /// + /// true=start build. false=build failed. + public bool BuildAndRun() + { + bool ret = false; + bool buildComplate = true; + + try + { + if (Application.isPlaying == false) + throw new MagicaClothProcessingException(); + + DisableAutoBuild(); + + 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) + { + 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; + } + + // 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); + } + + return ret; + } + + /// + /// コンポーネントが保持するトランスフォームを置換します。 + /// 置換先のトランスフォーム名をキーとした辞書を渡します。 + /// Replaces a component's transform. + /// Passes a dictionary keyed by the name of the transform to be replaced. + /// + /// Dictionary keyed by the name of the transform to be replaced. + public void ReplaceTransform(Dictionary targetTransformDict) + { + // コンポーネントが利用しているすべてのTransformを取得します + var useTransformSet = new HashSet(); + Process.GetUsedTransform(useTransformSet); + + // 置換処理用の辞書を作成 + // key:置換対象トランスフォームのインスタンスID + // value:入れ替えるトランスフォーム + var replaceDict = new Dictionary(); + foreach (var t in useTransformSet) + { + if (t && targetTransformDict.ContainsKey(t.name)) + { + replaceDict.Add(t.GetMagicaId(), targetTransformDict[t.name]); + } + } + + // 置換する + Process.ReplaceTransform(replaceDict); + } + + /// + /// コンポーネントが保持するすべてのトランスフォームを取得します。 + /// Gets all the transforms held by the component. + /// + /// + public HashSet GetUsedTransform() + { + var useTransformSet = new HashSet(); + Process.GetUsedTransform(useTransformSet); + return useTransformSet; + } + + + /// + /// パラメータの変更を通知 + /// 実行中にパラメータを変更した場合はこの関数を呼ぶ必要があります + /// You should call this function if you changed parameters during execution. + /// + public void SetParameterChange() + { + if (IsValid()) + { + Process.DataUpdate(); + } + } + + /// + /// タイムスケールを変更します + /// Change the time scale. + /// + /// 0.0-1.0 + public void SetTimeScale(float timeScale) + { + if (IsValid()) + { + ref var tdata = ref MagicaManager.Team.GetTeamDataRef(Process.TeamId); + tdata.timeScale = Mathf.Clamp01(timeScale); + } + } + + /// + /// タイムスケールを取得します + /// Get the time scale. + /// + /// + public float GetTimeScale() + { + if (IsValid()) + { + ref var tdata = ref MagicaManager.Team.GetTeamDataRef(Process.TeamId); + return tdata.timeScale; + } + else + return 1.0f; + } + + /// + /// シミュレーションを初期状態にリセットします + /// Reset the simulation to its initial state. + /// + /// If true, resume while maintaining posture. + public void ResetCloth(bool keepPose = false) + { + if (IsValid()) + { + ref var tdata = ref MagicaManager.Team.GetTeamDataRef(Process.TeamId); + if (keepPose) + { + // Keep + tdata.flag.SetBits(TeamManager.Flag_KeepTeleport, true); + } + else + { + // Reset + tdata.flag.SetBits(TeamManager.Flag_Reset, true); + tdata.flag.SetBits(TeamManager.Flag_TimeReset, true); + tdata.flag.SetBits(TeamManager.Flag_CameraCullingKeep, false); + Process.SetState(ClothProcess.State_CameraCullingKeep, false); + Process.UpdateRendererUse(); + } + } + } + + /// + /// 慣性の中心座標を取得します + /// Get the center of inertia position. + /// + /// + public Vector3 GetCenterPosition() + { + if (IsValid()) + { + ref var cdata = ref MagicaManager.Team.GetCenterDataRef(Process.TeamId); + return ClothTransform.TransformPoint(cdata.frameLocalPosition); + } + else + return Vector3.zero; + } + + /// + /// 外力を加えます + /// Add external force. + /// + /// + /// (m/s) + /// + public void AddForce(Vector3 forceDirection, float forceVelocity, ClothForceMode fmode = ClothForceMode.VelocityAdd) + { + if (IsValid() && forceDirection.magnitude > 0.0f && forceVelocity > 0.0f && fmode != ClothForceMode.None) + { + ref var tdata = ref MagicaManager.Team.GetTeamDataRef(Process.TeamId); + tdata.forceMode = fmode; + tdata.impactForce = forceDirection.normalized * forceVelocity; + } + } + + /// + /// TransformおよびMeshへの書き込みを禁止または許可します + /// この機能を使うことでストップモーションを実装することが可能です + /// Prevent or allow writing to Transform and Mesh. + /// By using this function, it is possible to implement stop motion. + /// + /// true=write disabled, false=write enabled + public void SetSkipWriting(bool sw) + { + if (IsValid()) + { + Process.SetSkipWriting(sw); + } + } + + private RenderData GetRenderData(Renderer ren) + { + if (IsValid() == false || ren == null) + return null; + MagicaObjectId handle = ren.GetMagicaId(); + return MagicaManager.Render.GetRendererData(handle); + } + + /// + /// MeshClothのオリジナルメッシュを取得します + /// Get the original mesh of MeshCloth. + /// + /// + /// null if not found + public Mesh GetOriginalMesh(Renderer ren) + { + var rdata = GetRenderData(ren); + return rdata != null ? rdata.originalMesh : null; + } + + /// + /// MeshClothのカスタムメッシュを取得します + /// Get the custom mesh for MeshCloth. + /// + /// + /// null if not found + public Mesh GetCustomMesh(Renderer ren) + { + var rdata = GetRenderData(ren); + return rdata != null ? rdata.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/MagicaCloth2/Scripts/Core/Cloth/MagicaClothAPI.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Cloth/MagicaClothAPI.cs.meta new file mode 100644 index 00000000..095e8c77 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Cloth/MagicaClothAPI.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: ebbf2c9c05a3200438a0a1f7b352d81f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Cloth/MagicaClothAPI.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Cloth/MagicaClothAnimationProperty.cs b/Assets/MagicaCloth2/Scripts/Core/Cloth/MagicaClothAnimationProperty.cs new file mode 100644 index 00000000..88e3882d --- /dev/null +++ b/Assets/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/MagicaCloth2/Scripts/Core/Cloth/MagicaClothAnimationProperty.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Cloth/MagicaClothAnimationProperty.cs.meta new file mode 100644 index 00000000..67c35a94 --- /dev/null +++ b/Assets/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.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Cloth/MagicaClothAnimationProperty.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Cloth/NormalAlignmentSettings.cs b/Assets/MagicaCloth2/Scripts/Core/Cloth/NormalAlignmentSettings.cs new file mode 100644 index 00000000..bef9e8d6 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Cloth/NormalAlignmentSettings.cs @@ -0,0 +1,107 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using System.Collections.Generic; +using UnityEngine; + +namespace MagicaCloth2 +{ + /// + /// Normal adjustment settings. + /// 法線調整設定 + /// + [System.Serializable] + public class NormalAlignmentSettings : IValid, IDataValidate, ITransform + { + public enum AlignmentMode + { + None = 0, + + /// + /// Radiation from center of AABB. + /// 中心から放射 + /// + BoundingBoxCenter = 1, + + /// + /// Emit from the specified transform. + /// 指定トランスフォームから放射 + /// + Transform = 2, + } + + /// + /// adjustment mode. + /// [NG] Runtime changes. + /// [NG] Export/Import with Presets + /// + public AlignmentMode alignmentMode = AlignmentMode.None; + + /// + /// Transform at which the radiation is centered. + /// [NG] Runtime changes. + /// [NG] Export/Import with Presets + /// + public Transform adjustmentTransform; + + + public void DataValidate() + { + } + + public bool IsValid() + { + switch (alignmentMode) + { + case AlignmentMode.None: + case AlignmentMode.BoundingBoxCenter: + case AlignmentMode.Transform: + //case AlignmentMode.BoneWeight: + return true; + } + + return false; + } + + public NormalAlignmentSettings Clone() + { + return new NormalAlignmentSettings() + { + alignmentMode = alignmentMode, + adjustmentTransform = adjustmentTransform, + }; + } + + /// + /// エディタメッシュの更新を判定するためのハッシュコード + /// (このハッシュは実行時には利用されない編集用のもの) + /// + /// + public override int GetHashCode() + { + int hash = 0; + hash += (int)alignmentMode * 105; + if (adjustmentTransform) + { + hash += adjustmentTransform.GetMagicaId().GetHashCode(); + hash += adjustmentTransform.position.GetHashCode(); + } + + return hash; + } + + public void GetUsedTransform(HashSet transformSet) + { + if (adjustmentTransform) + transformSet.Add(adjustmentTransform); + } + + public void ReplaceTransform(Dictionary replaceDict) + { + if (adjustmentTransform && replaceDict.ContainsKey(adjustmentTransform.GetMagicaId())) + { + adjustmentTransform = replaceDict[adjustmentTransform.GetMagicaId()]; + } + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/Cloth/NormalAlignmentSettings.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Cloth/NormalAlignmentSettings.cs.meta new file mode 100644 index 00000000..c6b33371 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Cloth/NormalAlignmentSettings.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 558afbac4118e4c4da1657e02a653e3d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Cloth/NormalAlignmentSettings.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Cloth/SelectionData.cs b/Assets/MagicaCloth2/Scripts/Core/Cloth/SelectionData.cs new file mode 100644 index 00000000..1f4e1b65 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Cloth/SelectionData.cs @@ -0,0 +1,445 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using System; +using System.Collections.Generic; +using Unity.Burst; +using Unity.Collections; +using Unity.Jobs; +using Unity.Mathematics; + +namespace MagicaCloth2 +{ + /// + /// 頂点の属性情報(移動/固定/無効)データ + /// このデータはシリアライズされる + /// 座標はクロスコンポーネントのローカル空間で格納される + /// Vertex attribute information (move/fix/disable) data. + /// This data is serialized. + /// Coordinates are stored in the cloth component's local space. + /// + [System.Serializable] + public class SelectionData : IValid + { + /// + /// 属性のローカル座標 + /// これはクロスコンポーネント空間 + /// Attribute local coordinates. + /// This is the cloth component space. + /// + public float3[] positions; + + /// + /// 上記の属性値 + /// サイズはpositionsと同じでなくてはならない + /// Attribute value above. + /// size must be the same as positions. + /// + public VertexAttribute[] attributes; + + /// + /// セレクションデータ構築時のVirtualMeshの最大頂点接続距離 + /// Maximum vertex connection distance of VirtualMesh when constructing selection data. + /// + public float maxConnectionDistance; + + /// + /// ユーザーが編集したデータかどうか + /// Is the data edited by the user? + /// + public bool userEdit = false; + + //========================================================================================= + public SelectionData() { } + + public SelectionData(int cnt) + { + positions = new float3[cnt]; + attributes = new VertexAttribute[cnt]; + } + + public SelectionData(VirtualMesh vmesh, float4x4 transformMatrix) + { + if (vmesh != null && vmesh.VertexCount > 0) + { + // vmesh座標をコンポーネント空間に変換して格納する + using var posArray = new NativeArray(vmesh.localPositions.GetNativeArray(), Allocator.TempJob); + var job = new TransformPositionJob() + { + transformMatrix = transformMatrix, + localPositions = posArray, + }; + job.Run(vmesh.VertexCount); + + positions = posArray.ToArray(); + attributes = vmesh.attributes.ToArray(); + maxConnectionDistance = vmesh.maxVertexDistance.Value; + } + } + + [BurstCompile] + struct TransformPositionJob : IJobParallelFor + { + public float4x4 transformMatrix; + public NativeArray localPositions; + + public void Execute(int index) + { + var pos = localPositions[index]; + pos = math.transform(transformMatrix, pos); + localPositions[index] = pos; + } + } + + public int Count + { + get + { + return positions?.Length ?? 0; + } + } + + public bool IsValid() + { + if (positions == null || positions.Length == 0) + return false; + if (attributes == null || attributes.Length == 0) + return false; + if (positions.Length != attributes.Length) + return false; + + return true; + } + + public bool IsUserEdit() => userEdit; + + public SelectionData Clone() + { + var sdata = new SelectionData(); + sdata.positions = positions?.Clone() as float3[]; + sdata.attributes = attributes?.Clone() as VertexAttribute[]; + sdata.maxConnectionDistance = maxConnectionDistance; + sdata.userEdit = userEdit; + + return sdata; + } + + /// + /// ハッシュ(このセレクションデータの識別に利用される) + /// + /// + //public override int GetHashCode() + //{ + // if (IsValid() == false) + // return 0; + + // // 頂点座標のハッシュをいくつかサンプリングする + // uint hash = 0; + // int len = positions.Length; + // int step = math.max(len / 4, 1); + // for (int i = 0; i < len; i += step) + // { + // hash += math.hash(positions[i]); + // hash += (uint)attributes[i].Value; + // } + // hash += math.hash(positions[len - 1]); + // hash += (uint)attributes[len - 1].Value; + + // return (int)hash; + //} + + /// + /// 2つのセレクションデータが等しいか判定する + /// (座標の詳細は見ない。属性の詳細は見る) + /// + /// + /// + public bool Compare(SelectionData sdata) + { + //return GetHashCode() == sdata.GetHashCode(); + + if (positions?.Length != sdata.positions?.Length) + return false; + + if (attributes?.Length != sdata.attributes?.Length) + return false; + + if (userEdit != sdata.userEdit) + return false; + + // 座標と属性は正確に見る + // todo:この処理が重いようならBurstに切り替える + int cnt = attributes.Length; + for (int i = 0; i < cnt; i++) + { + if (attributes[i] != sdata.attributes[i]) + return false; + if (positions[i].Equals(sdata.positions[i]) == false) + return false; + } + + return true; + } + + public void AddRange(float3[] addPositions, VertexAttribute[] addAttributes = null) + { + if (Count == 0) + { + positions = addPositions; + attributes = addAttributes != null ? addAttributes : new VertexAttribute[addPositions.Length]; + } + else + { + // 拡張 + int cnt = Count; + int addCnt = addPositions.Length; + float3[] newPositions = new float3[cnt + addCnt]; + VertexAttribute[] newAttribues = new VertexAttribute[cnt + addCnt]; + + Array.Copy(positions, 0, newPositions, 0, cnt); + Array.Copy(addPositions, 0, newPositions, cnt, addCnt); + + Array.Copy(attributes, 0, newAttribues, 0, cnt); + if (addAttributes != null) + { + Array.Copy(addAttributes, 0, newAttribues, cnt, addCnt); + } + + positions = newPositions; + attributes = newAttribues; + } + } + + public void Fill(VertexAttribute attr) + { + Array.Fill(attributes, attr); + } + + //========================================================================================= + public NativeArray GetPositionNativeArray() + { + return new NativeArray(positions, Allocator.Persistent); + } + + public NativeArray GetPositionNativeArray(float4x4 transformMatrix) + { + var posArray = GetPositionNativeArray(); + var job = new TransformPositionJob() + { + transformMatrix = transformMatrix, + localPositions = posArray, + }; + job.Run(Count); + + return posArray; + } + + public NativeArray GetAttributeNativeArray() + { + return new NativeArray(attributes, Allocator.Persistent); + } + + //========================================================================================= + /// + /// 属性座標をグリッドマップに登録して返す + /// + /// + /// + /// + /// 移動属性を含めるかどうか + /// 固定属性を含めるかどうか + /// 無効属性を含めるかどうか + /// + public static GridMap CreateGridMapRun( + float gridSize, + in NativeArray positions, + in NativeArray attributes, + bool move = true, bool fix = true, bool ignore = true, bool invalid = true + ) + { + var gridMap = new GridMap(positions.Length); + + var job = new CreateGridMapJob() + { + move = move, + fix = fix, + ignore = ignore, + invalid = invalid, + gridMap = gridMap.GetMultiHashMap(), + gridSize = gridSize, + positions = positions, + attribute = attributes, + }; + job.Run(); + + return gridMap; + } + + [BurstCompile] + struct CreateGridMapJob : IJob + { + public bool move; + public bool fix; + public bool ignore; + public bool invalid; + + public NativeParallelMultiHashMap gridMap; + public float gridSize; + + [Unity.Collections.ReadOnly] + public NativeArray positions; + [Unity.Collections.ReadOnly] + public NativeArray attribute; + + public void Execute() + { + int cnt = positions.Length; + for (int i = 0; i < cnt; i++) + { + var attr = attribute[i]; + if (move == false && attr.IsMove()) + continue; + if (fix == false && attr.IsFixed()) + continue; + //if (ignore == false && attr.IsIgnore()) + // continue; + if (invalid == false && attr.IsInvalid()) + continue; + + var pos = positions[i]; + + GridMap.AddGrid(pos, i, gridMap, gridSize); + } + } + } + + //========================================================================================= + /// + /// セレクションデータを結合する + /// + /// + public void Merge(SelectionData from) + { + if (from.Count == 0) + return; + + var cnt = Count + from.Count; + var newPositions = new List(cnt); + var newAttributes = new List(cnt); + if (positions != null) + newPositions.AddRange(positions); + if (attributes != null) + newAttributes.AddRange(attributes); + newPositions.AddRange(from.positions); + newAttributes.AddRange(from.attributes); + + positions = newPositions.ToArray(); + attributes = newAttributes.ToArray(); + maxConnectionDistance = math.max(maxConnectionDistance, from.maxConnectionDistance); + userEdit = userEdit || from.userEdit; + } + + /// + /// 頂点数の異なるセレクションデータを移植する + /// + /// 移動元セレクションデータ + public void ConvertFrom(SelectionData from) + { + if (from.Count == 0) + return; + if (Count == 0) + return; + + // 移動先データ + using var toPositions = GetPositionNativeArray(); + using var toAttributes = GetAttributeNativeArray(); + + // 移動元データ + using var fromPositions = from.GetPositionNativeArray(); + using var fromAttributes = from.GetAttributeNativeArray(); + + // 移動先のAABB + using var aabb = new NativeReference(Allocator.TempJob); + JobUtility.CalcAABBRun(toPositions, Count, aabb); + float serachRadius = aabb.Value.MaxSideLength * 0.2f; // 20% + serachRadius = math.max(serachRadius, Define.System.MinimumGridSize); + + // 移動元データをグリッドに登録する + float gridSize = serachRadius * 0.5f; + using var gridMap = CreateGridMapRun(gridSize, fromPositions, fromAttributes); + + // 移動先座標を範囲検索し見つかった移動元属性を付与する + var job = new ConvertSelectionJob() + { + gridSize = gridSize, + radius = serachRadius, + toPositions = toPositions, + toAttributes = toAttributes, + gridMap = gridMap.GetMultiHashMap(), + fromPositions = fromPositions, + fromAttributes = fromAttributes, + }; + job.Run(Count); + + // 結果の書き戻し + positions = toPositions.ToArray(); + attributes = toAttributes.ToArray(); + } + + [BurstCompile] + struct ConvertSelectionJob : IJobParallelFor + { + public float gridSize; + public float radius; + + // to + [Unity.Collections.ReadOnly] + public NativeArray toPositions; + [Unity.Collections.WriteOnly] + public NativeArray toAttributes; + + // from + [Unity.Collections.ReadOnly] + public NativeParallelMultiHashMap gridMap; + [Unity.Collections.ReadOnly] + public NativeArray fromPositions; + [Unity.Collections.ReadOnly] + public NativeArray fromAttributes; + + public void Execute(int vindex) + { + float3 pos = toPositions[vindex]; + + // 見つからない場合はInvalid + VertexAttribute attr = VertexAttribute.Invalid; + + // 範囲グリッド走査 + float minDist = float.MaxValue; + foreach (int3 grid in GridMap.GetArea(pos, radius, gridMap, gridSize)) + { + if (gridMap.ContainsKey(grid) == false) + continue; + + // このグリッドを検索する + foreach (int tindex in gridMap.GetValuesForKey(grid)) + { + // 距離判定 + float3 tpos = fromPositions[tindex]; + float dist = math.distance(pos, tpos); + if (dist > radius) + continue; + if (dist > minDist) + continue; + + // 近傍設定 + minDist = dist; + attr = fromAttributes[tindex]; + } + } + + // 属性反映 + toAttributes[vindex] = attr; + } + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/Cloth/SelectionData.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Cloth/SelectionData.cs.meta new file mode 100644 index 00000000..537a0ee9 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Cloth/SelectionData.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: c35ca9ed7221ef445843e9c21428c27d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Cloth/SelectionData.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Cloth/Wind.meta b/Assets/MagicaCloth2/Scripts/Core/Cloth/Wind.meta new file mode 100644 index 00000000..d2b84c12 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Cloth/Wind.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: e487ff1775b55bb4897455a2b4a5123a +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/MagicaCloth2/Scripts/Core/Cloth/Wind/MagicaWindZone.cs b/Assets/MagicaCloth2/Scripts/Core/Cloth/Wind/MagicaWindZone.cs new file mode 100644 index 00000000..9ac5a70b --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Cloth/Wind/MagicaWindZone.cs @@ -0,0 +1,204 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using UnityEngine; + +namespace MagicaCloth2 +{ + /// + /// Wind zone + /// + [AddComponentMenu("MagicaCloth2/MagicaWindZone")] + [HelpURL("https://magicasoft.jp/en/mc2_windzone_component/")] + public class MagicaWindZone : ClothBehaviour + { + public enum Mode + { + /// + /// 領域を持たない全体に影響する風 + /// Wind that affects the whole without area. + /// + GlobalDirection = 0, + + /// + /// 球型の領域を持つ方向風 + /// Directional wind with spherical area. + /// + SphereDirection = 1, + + /// + /// ボックス型の領域を持つ方向風 + /// + BoxDirection = 2, + + /// + /// 球型の領域を持つ放射風 + /// Directional wind with box area. + /// + SphereRadial = 10, + } + + /// + /// Zone mode. + /// [OK] Runtime changes. + /// + public Mode mode = Mode.GlobalDirection; + + /// + /// Box size. + /// [OK] Runtime changes. + /// + public Vector3 size = new Vector3(10.0f, 10.0f, 10.0f); + + /// + /// Sphere size. + /// [OK] Runtime changes. + /// + public float radius = 10.0f; + + /// + /// メイン風力 + /// main wind (m/s). + /// [OK] Runtime changes. + /// + [Range(0, 30)] + public float main = 5.0f; + + /// + /// 乱流率 + /// turbulence rate. + /// [OK] Runtime changes. + /// + [Range(0.0f, 1.0f)] + public float turbulence = 1.0f; + + /// + /// 風の方向X角度(ローカル角度) + /// wind direction x angle (local angle). + /// [OK] Runtime changes. + /// + [Range(-180, 180)] + public float directionAngleX = 0; + + /// + /// 風の方向Y角度(ローカル角度) + /// wind direction y angle (local angle). + /// [OK] Runtime changes. + /// + [Range(-180, 180)] + public float directionAngleY = 0; + + /// + /// 放射風の減衰 + /// Radiation wind attenuation. + /// [OK] Runtime changes. + /// + public AnimationCurve attenuation = AnimationCurve.EaseInOut(0.0f, 1.0f, 1.0f, 0.0f); + + /// + /// 他の風の影響を無効にせずに追加するフラグ + /// Flags to add without disabling other wind effects. + /// [OK] Runtime changes. + /// + public bool isAddition = false; + + //========================================================================================= + /// + /// 風マネージャデータへの参照インデックス(-1=無効) + /// Reference index to wind manager data (-1=disabled). + /// + public int WindId { get; private set; } = -1; + + + //========================================================================================= + protected void Awake() + { + WindId = MagicaManager.Wind.AddWind(this); + } + + protected void OnEnable() + { + MagicaManager.Wind.SetEnable(WindId, true); + } + + protected void OnDisable() + { + MagicaManager.Wind?.SetEnable(WindId, false); + } + + protected void OnDestroy() + { + MagicaManager.Wind?.RemoveWind(WindId); + WindId = -1; + } + + //========================================================================================= + /// + /// 方向風か判定する + /// whether the zone has directional winds. + /// + /// + public bool IsDirection() + { + switch (mode) + { + case Mode.GlobalDirection: + case Mode.SphereDirection: + case Mode.BoxDirection: + return true; + default: + return false; + } + } + + /// + /// 放射風か判定する + /// whether the zone has radiant winds. + /// + /// + public bool IsRadial() + { + switch (mode) + { + case Mode.SphereRadial: + return true; + default: + return false; + } + } + + /// + /// 追加される風か判定する + /// Whether it is a wind of additional system. + /// + /// + public bool IsAddition() => isAddition; + + /// + /// 方向性風の風向きを取得する + /// Get the direction of the directional wind. + /// + /// + /// + public Vector3 GetWindDirection(bool localSpace = false) + { + var lq = Quaternion.Euler(directionAngleX, directionAngleY, 0.0f); + var ldir = lq * Vector3.forward; + return localSpace ? ldir : transform.TransformDirection(ldir); + } + + /// + /// 方向性風の風向きを設定する + /// Set the wind direction for directional wind. + /// + /// + /// + public void SetWindDirection(Vector3 dir, bool localSpace = false) + { + Vector3 lv = localSpace ? dir : transform.InverseTransformDirection(dir); + 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/MagicaCloth2/Scripts/Core/Cloth/Wind/MagicaWindZone.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Cloth/Wind/MagicaWindZone.cs.meta new file mode 100644 index 00000000..9a492d22 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Cloth/Wind/MagicaWindZone.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: c2e01f3f330fcf34eb7f2aa7b311cee5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {fileID: 2800000, guid: 28008cd7b4b7bb24482a4260fbe8c25e, type: 3} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Cloth/Wind/MagicaWindZone.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Cloth/Wind/WindParams.cs b/Assets/MagicaCloth2/Scripts/Core/Cloth/Wind/WindParams.cs new file mode 100644 index 00000000..5c0f483c --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Cloth/Wind/WindParams.cs @@ -0,0 +1,36 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp + +namespace MagicaCloth2 +{ + /// + /// 風の調整用パラメータ + /// + public struct WindParams : IValid + { + public float influence; + public float frequency; + public float turbulence; + public float blend; + public float synchronization; + public float depthWeight; + public float movingWind; + + public void Convert(WindSettings sdata, ClothProcess.ClothType clothType) + { + influence = sdata.influence; + frequency = sdata.frequency; + turbulence = sdata.turbulence; + blend = sdata.blend; + synchronization = sdata.synchronization; + depthWeight = sdata.depthWeight; + movingWind = sdata.movingWind; + } + + public bool IsValid() + { + return influence > Define.System.Epsilon; + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/Cloth/Wind/WindParams.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Cloth/Wind/WindParams.cs.meta new file mode 100644 index 00000000..80de01ea --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Cloth/Wind/WindParams.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 7aeb50197bc0c754d953e215c45b7c34 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Cloth/Wind/WindParams.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Cloth/Wind/WindSettings.cs b/Assets/MagicaCloth2/Scripts/Core/Cloth/Wind/WindSettings.cs new file mode 100644 index 00000000..e2f10f91 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Cloth/Wind/WindSettings.cs @@ -0,0 +1,109 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using UnityEngine; + +namespace MagicaCloth2 +{ + /// + /// 風調整用シリアライズデータ + /// Serialized data for wind adjustment. + /// + [System.Serializable] + public class WindSettings : IValid, IDataValidate + { + /// + /// 全体の影響率(1.0=100%) + /// Overall impact rate (1.0=100%). + /// [OK] Runtime changes. + /// [OK] Export/Import with Presets + /// + [Range(0.0f, 2.0f)] + public float influence = 1.0f; + + /// + /// 揺れの周期(値を大きくすると周期が速くなる) + /// Period of shaking (the higher the value, the faster the period). + /// [OK] Runtime changes. + /// [OK] Export/Import with Presets + /// + [Range(0.0f, 2.0f)] + public float frequency = 1.0f; + + /// + /// 乱流率 + /// turbulence rate. + /// [OK] Runtime changes. + /// [OK] Export/Import with Presets + /// + [Range(0.0f, 2.0f)] + public float turbulence = 1.0f; + + /// + /// Sin波とNoise波のブレンド率(0.0:sin ~ 1.0:noise) + /// Blend ratio of sine wave and noise wave (0.0:sin ~ 1.0:noise). + /// [OK] Runtime changes. + /// [OK] Export/Import with Presets + /// + [Range(0.0f, 1.0f)] + public float blend = 0.7f; + + /// + /// ベースラインごとの同期率 + /// Synchronization rate by baseline. + /// [OK] Runtime changes. + /// [OK] Export/Import with Presets + /// + [Range(0.0f, 1.0f)] + public float synchronization = 0.7f; + + /// + /// 深さ影響率 + /// Depth influence factor. + /// [OK] Runtime changes. + /// [OK] Export/Import with Presets + /// + [Range(0.0f, 1.0f)] + public float depthWeight = 0.0f; + + /// + /// 移動時の風速 + /// Wind speed when moving. + /// [OK] Runtime changes. + /// [OK] Export/Import with Presets + /// + [Range(0.0f, 10.0f)] + public float movingWind = 0.0f; + + //========================================================================================= + public bool IsValid() + { + return influence > Define.System.Epsilon; + } + + public void DataValidate() + { + influence = Mathf.Clamp(influence, 0.0f, 2.0f); + frequency = Mathf.Clamp(frequency, 0.0f, 2.0f); + turbulence = Mathf.Clamp(turbulence, 0.0f, 2.0f); + blend = Mathf.Clamp01(blend); + synchronization = Mathf.Clamp01(synchronization); + depthWeight = Mathf.Clamp01(depthWeight); + movingWind = Mathf.Clamp(movingWind, 0.0f, 10.0f); + } + + public WindSettings Clone() + { + return new WindSettings() + { + influence = influence, + frequency = frequency, + turbulence = turbulence, + blend = blend, + synchronization = synchronization, + depthWeight = depthWeight, + movingWind = movingWind, + }; + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/Cloth/Wind/WindSettings.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Cloth/Wind/WindSettings.cs.meta new file mode 100644 index 00000000..7080af79 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Cloth/Wind/WindSettings.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: ebacab05b884faa4886e2d90ca2f7d48 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Cloth/Wind/WindSettings.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Define.meta b/Assets/MagicaCloth2/Scripts/Core/Define.meta new file mode 100644 index 00000000..91aeb7d2 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Define.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 719b7a2fc5935ff438c1e1e6528027b9 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/MagicaCloth2/Scripts/Core/Define/ResultDefine.cs b/Assets/MagicaCloth2/Scripts/Core/Define/ResultDefine.cs new file mode 100644 index 00000000..b81b1a95 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Define/ResultDefine.cs @@ -0,0 +1,182 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp + +namespace MagicaCloth2 +{ + public static partial class Define + { + public enum Result + { + None = 0, + + /// + /// It is not an error, but the data is empty. + /// + Empty = 1, + + Success = 2, + Cancel = 3, + Process = 4, + + /////////////////////////////////////////////////////////////////// + // State(1000 - 9999) + /////////////////////////////////////////////////////////////////// + //EmptyData = 1000, + //Init_Complete = 1000, + //Cloth_Running = 2000, + + /////////////////////////////////////////////////////////////////// + // Warning(10000 - 19999) + /////////////////////////////////////////////////////////////////// + Warning = 10000, + + RenderMesh_UnknownWarning = 10100, + RenderMesh_VertexWeightIs5BonesOrMore, + + Init_NonUniformScale = 10200, + + /////////////////////////////////////////////////////////////////// + // Error(20000 - ) + /////////////////////////////////////////////////////////////////// + Error = 20000, + + // 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, + RenderSetup_UnknownError, + RenderSetup_InvalidSource, + RenderSetup_NoMeshOnRenderer, + RenderSetup_InvalidType, + RenderSetup_Unreadable, + RenderSetup_Over65535vertices, + + // VirtualMesh + VirtualMesh_UnknownError = 20300, + VirtualMesh_InvalidSetup, + VirtualMesh_InvalidRenderData, + VirtualMesh_ImportError, + VirtualMesh_SelectionException, + VirtualMesh_SelectionUnknownError, + VirtualMesh_InvalidSelection, + + // Create Cloth + CreateCloth_Exception = 20400, + CreateCloth_UnknownError, + CreateCloth_InvalidCloth, + CreateCloth_InvalidSerializeData, + CreateCloth_InvalidSetupList, + CreateCloth_NoRenderer, + CreateCloth_InvalidPaintMap, + CreateCloth_PaintMapNotReadable, + CreateCloth_PaintMapCountMismatch, + CreateCloth_CanNotStart, + CreateCloth_VertexAttributeListCountMismatch, + CreateCloth_VertexAttributeListIsNull, + CreateCloth_VertexAttributeListDataMismatch, + CreateCloth_InvalidVertexAttributeData, + + // Reduction + Reduction_Exception = 20500, + Reduction_UnknownError, + Reduction_InitError, + Reduction_SameDistanceException, + Reduction_SimpleDistanceException, + Reduction_ShapeDistanceException, + Reduction_MaxSideLengthZero, + Reduction_OrganizationError, + Reduction_StoreVirtualMeshError, + Reduction_CalcAverageException, + + // Optimize + Optimize_Exception = 20600, + + // ProxyMesh + ProxyMesh_Exception = 20700, + ProxyMesh_UnknownError, + ProxyMesh_ApplySelectionError, + ProxyMesh_ConvertError, + ProxyMesh_Over32767Vertices, + ProxyMesh_Over32767Edges, + ProxyMesh_Over32767Triangles, + + // MappingMesh + MappingMesh_Exception = 20800, + MappingMesh_UnknownError, + MappingMesh_ProxyError, + + // ClothInit + ClothInit_Exception = 22000, + ClothInit_FailedAddRenderer, + + // ClothProcess + ClothProcess_Exception = 22100, + ClothProcess_UnknownError, + ClothProcess_Invalid, + ClothProcess_InvalidRenderHandleList, + ClothProcess_GenerateSelectionError, + ClothProcess_OverflowTeamCount4096, + + // Constraint + Constraint_Exception = 22200, + Constraint_UnknownError, + Constraint_CreateDistanceException, + Constraint_CreateTriangleBendingException, + Constraint_CreateInertiaException, + Constraint_CreateSelfCollisionException, + + // MagicaMesh + MagicaMesh_UnknownError = 22500, + 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/MagicaCloth2/Scripts/Core/Define/ResultDefine.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Define/ResultDefine.cs.meta new file mode 100644 index 00000000..3d6bcf6c --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Define/ResultDefine.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 6565f8ffcbde83c40a754caa20db861a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Define/ResultDefine.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Define/SystemDefine.cs b/Assets/MagicaCloth2/Scripts/Core/Define/SystemDefine.cs new file mode 100644 index 00000000..36f45a2d --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Define/SystemDefine.cs @@ -0,0 +1,430 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using Unity.Mathematics; + +namespace MagicaCloth2 +{ + public static partial class Define + { + /// + /// システム関連デファイン + /// + public static class System + { + /// + /// プロジェクトセッティングに登録するDefineシンボル + /// + public const string DefineSymbol = "MAGICACLOTH2"; + + /// + /// 現在有効なPreBuildの最新バージョン + /// + public const int LatestPreBuildVersion = 2; + + /// + /// 計算を省略する最小の浮動小数点数 + /// + public const float Epsilon = 1e-8f; + + /// + /// MeshClothで設定可能な最大レンダラー数 + /// + public const int MaxRendererCount = 31; + + /// + /// 最小のグリッドサイズ定義(GridSize=0は動作しないため) + /// + public const float MinimumGridSize = 0.00001f; + + /// + /// 生成できるチーム数 + /// + public const int MaximumTeamCount = 4096; + + /// + /// シミュレーション周波数初期値 + /// + public const int DefaultSimulationFrequency = 90; + + /// + /// シミュレーション周波数最小値 + /// + public const int SimulationFrequency_Low = 30; + + /// + /// シミュレーション周波数最大値 + /// + public const int SimulationFrequency_Hi = 150; + + /// + /// 1フレームでの最大更新回数初期値 + /// + public const int DefaultMaxSimulationCountPerFrame = 3; + + /// + /// 1フレームでの最大更新回数最小 + /// + public const int MaxSimulationCountPerFrame_Low = 1; + + /// + /// 1フレームでの最大更新回数最大 + /// + public const int MaxSimulationCountPerFrame_Hi = 5; + + /// + /// 法線整列時に同一の面(レイヤー)として判定する隣接トライアングルのなす角(デグリー) + /// + public const float SameSurfaceAngle = 80.0f; + + /// + /// 未来予測時のルートからの距離制限倍率 + /// + public const float MaxDistanceRatioFutuerPrediction = 1.3f; + + /// + /// 分割ジョブを適用するプロキシメッシュメッシュの頂点数 + /// + public const int SplitProxyMeshVertexCount = 300; + + /// + /// [Reduction] + /// 有効フラグ。常にtrueとする。 + /// + public const bool ReductionEnable = true; + + /// + /// [Reduction] + /// 同一頂点として判定する距離(AABB最大距離の%)(0.0 ~ 1.0) + /// + public const float ReductionSameDistance = 0.001f; + + /// + /// [Reduction] + /// 極力ラインを作らない接続を行う + /// + public const bool ReductionDontMakeLine = true; + + /// + /// [Reduction] + /// 結合頂点位置の調整 + /// (0.0=接続頂点数の多いほど動かない, 1.0=完全に平均化) + /// + public const float ReductionJoinPositionAdjustment = 1.0f; + + /// + /// [Reduction] + /// 最大ステップ回数 + /// + public const int ReductionMaxStep = 100; + + /// + /// [ProxyMesh] + /// 有効な最大頂点数 + /// + public const int MaxProxyMeshVertexCount = 32767; + + /// + /// [ProxyMesh] + /// 有効な最大エッジ数 + /// + public const int MaxProxyMeshEdgeCount = 32767; + + /// + /// [ProxyMesh] + /// 有効な最大トライアングル数 + /// + public const int MaxProxyMeshTriangleCount = 32767; + + /// + /// [ProxyMesh] + /// トライアングルのペアと判定する角度(Deg) + /// + public const float ProxyMeshTrianglePairAngle = 20.0f; + + /// + /// [ProxyMesh] + /// BoneClothのMesh接続時にトライアングルとして判断される内角 + /// + public const float ProxyMeshBoneClothTriangleAngle = 120.0f; + + /// + /// [Simulation] + /// 摩擦(0.0 ~ 1.0)に対する増加重量 + /// + public const float FrictionMass = 3.0f; + + /// + /// [Simulation] + /// 深さ(0.0 ~ 1.0)に対する増加重量(深さ0.0のときに最大になる) + /// + public const float DepthMass = 5.0f; + + /// + /// [Simulation] + /// ステップごとの摩擦減衰率 + /// + public const float FrictionDampingRate = 0.6f; + + /// + /// [Simulation] + /// アトミック加算による移動ベクトルの平均化に使用する加算数に対する指数 + /// + public const float PositionAverageExponent = 0.5f; // 0.5? + + /// + /// [Simulation] + /// 未来予測に用いる実速度の最大速度クランプ(m/s) + /// これはセルフコジョンなどで意図しない表示突き抜けを防止するために必要! + /// + public const float MaxRealVelocity = 0.5f; + + /// + /// [Simulation] + /// パーティクルの最大速度(m/s) + /// + //public const float ParticleSpeedLimit = 3.0f; + + /// + /// [Tether] + /// 縮み剛性(0.0 ~ 1.0) + /// + public const float TetherCompressionStiffness = 1.0f; // 0.1? + + /// + /// [Tether] + /// 伸び剛性(0.0 ~ 1.0) + /// + public const float TetherStretchStiffness = 1.0f; // 1.0f? + + /// + /// [Tether] + /// 最大拡大割合(0.0 ~ 1.0) + /// 0.0=拡大しない + /// + public const float TetherStretchLimit = 0.03f; // 0.0? + + /// + /// [Tether] + /// stiffnessのフェード範囲(0.0 ~ 1.0) + /// + public const float TetherStiffnessWidth = 0.3f; // 0.2? + + /// + /// [Tether] + /// 拡大時の速度減衰(0.0 ~ 1.0) + /// + public const float TetherCompressionVelocityAttenuation = 0.7f; + + /// + /// [Tether] + /// 縮小時の速度減衰(0.0 ~ 1.0) + /// + public const float TetherStretchVelocityAttenuation = 0.7f; // 0.9f? + + /// + /// [Distance] + /// 速度減衰(0.0 ~ 1.0) + /// + public const float DistanceVelocityAttenuation = 0.3f; + + /// + /// [Distance] + /// 縦接続の剛性(0.0 ~ 1.0) + /// + public const float DistanceVerticalStiffness = 1.0f; + + /// + /// [Distance] + /// 横およびShear接続の剛性(0.0 ~ 1.0) + /// + public const float DistanceHorizontalStiffness = 0.5f; + + /// + /// [Triangle Bending] + /// TriangleBendを形成する最大の角度 + /// + public const float TriangleBendingMaxAngle = 120.0f; // 145? + + /// + /// [Volume] + /// Volumeを形成する最小のTriangleペア角度 + /// + public const float VolumeMinAngle = 90.0f; + + /// + /// [Angle Limit] + /// 角度制限の最大角度(deg) + /// + public const float MaxAngleLimit = 179.0f; + + /// + /// [Angle Limit] + /// 反復回数 + /// + public const int AngleLimitIteration = 3; + + /// + /// [Angle Limit] + /// 速度減衰(0.0 ~ 1.0) + /// + public const float AngleLimitAttenuation = 0.9f; + + /// + /// [Inertia] + /// 設定できる最大移動速度(m/s) + /// + public const float MaxMovementSpeedLimit = 10.0f; + + /// + /// [Inertia] + /// 設定できる最大回転速度(deg/s) + /// + public const float MaxRotationSpeedLimit = 1440.0f; + + /// + /// [Inertia] + /// 設定できる最大のパーティクル移動速度(m/s) + /// + public const float MaxParticleSpeedLimit = 10.0f; + + /// + /// [Collider Collision] + /// 一度に拡張するコライダー数 + /// + public const int ExpandedColliderCount = 8; + + /// + /// [Collider Collision] + /// 設定frictionに対するDynamicFrictionの割合(0.0 ~ 1.0) + /// + public const float ColliderCollisionDynamicFrictionRatio = 1.0f; + + /// + /// [Collider Collision] + /// 設定frictionに対するStaticFrictionの割合(0.0 ~ 1.0) + /// + public const float ColliderCollisionStaticFrictionRatio = 1.0f; + + /// + /// [Collider Collision] + /// 速度減衰(0.0 ~ 1.0) + /// + //public const float ColliderCollisionVelocityAttenuation = 0.0f; + + /// + /// [Custom Skinning] + /// ボーンラインからの角度による減衰率(0.0~1.0) + /// + public const float CustomSkinningAngularAttenuation = 1.0f; + + /// + /// [Custom Skinning] + /// 最近ポイントのウエイト強度(0.0~1.0) + /// + public const float CustomSkinningDistanceReduction = 0.6f; + + /// + /// [Custom Skinning] + /// 距離によりウエイトの減衰乗数(だいたい0.1 ~ 5.0) + /// + public const float CustomSkinningDistancePow = 2.0f; + + /// + /// [Self Collision] + /// 反復回数 + /// + public const int SelfCollisionSolverIteration = 4; // 4 + + /// + /// [Self Collision] + /// 無効グリッド座標 + /// + public const int SelfCollisionIgnoreGrid = 1000000; + + /// + /// [Self Collision] + /// 交差判定の分割数 + /// + public const int SelfCollisionIntersectDiv = 2; // 8 + + /// + /// [Self Collision] + /// セルフコリジョン解決時の固定パーティクル重量 + /// + public const float SelfCollisionFixedMass = 100.0f; + + /// + /// [Self Collision] + /// セルフコリジョン解決時の摩擦1.0に対する重量 + /// + public const float SelfCollisionFrictionMass = 10.0f; + + /// + /// [Self Collision] + /// セルフコリジョンのチーム重量係数 + /// + public const float SelfCollisionClothMass = 50.0f; + + /// + /// [Self Collision] + /// 厚み(thickness)に対するSCRスケール + /// + public const float SelfCollisionSCR = 2.0f; // 1.0 + + /// + /// [Self Collision] + /// PointTriangleの有効判定角度(deg) + /// + public static readonly float SelfCollisionPointTriangleAngleCos = math.cos(math.radians(60.0f)); + + /// + /// [Self Collision] + /// Thicknessの最小値(m) + /// + public const float SelfCollisionThicknessMin = 0.001f; + + /// + /// [Self Collision] + /// Thicknessの最大値(m) + /// + public const float SelfCollisionThicknessMax = 0.05f; + + /// + /// [Wind] + /// 風時間の最大値 + /// + public const float WindMaxTime = 10000.0f; + + /// + /// [Wind] + /// 風速係数の基準となる風速(m/s) + /// + public const float WindBaseSpeed = 7.5f; + + /// + /// [Spring] + /// BoneSpring利用時のDistanceConstraintのStiffness値 + /// + public const float BoneSpringDistanceStiffness = 0.5f; + + /// + /// [Spring] + /// BoneSpring利用時のTetherConstraintのCompressionLimit値 + /// + public const float BoneSpringTetherCompressionLimit = 0.8f; + + /// + /// [Spring] + /// BoneSpring利用時のfriction値 + /// + public const float BoneSpringCollisionFriction = 0.5f; + + /// + /// [Culling] + /// 距離カリングの最大距離 + /// + public const float DistanceCullingMaxLength = 100.0f; + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/Define/SystemDefine.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Define/SystemDefine.cs.meta new file mode 100644 index 00000000..4f119115 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Define/SystemDefine.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 3b695911c4ac0604d93d387125306f9c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Define/SystemDefine.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Interface.meta b/Assets/MagicaCloth2/Scripts/Core/Interface.meta new file mode 100644 index 00000000..cae01c76 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Interface.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: d7576f015bd32cb42aae4c953bd8dcc0 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/MagicaCloth2/Scripts/Core/Interface/ICount.cs b/Assets/MagicaCloth2/Scripts/Core/Interface/ICount.cs new file mode 100644 index 00000000..121c7f4d --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Interface/ICount.cs @@ -0,0 +1,14 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp + +namespace MagicaCloth2 +{ + /// + /// データカウントを返すインターフェース + /// + interface ICount + { + int Count(); + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/Interface/ICount.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Interface/ICount.cs.meta new file mode 100644 index 00000000..9eb00b88 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Interface/ICount.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 8ec05c78959350f489fd922165a79ad1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Interface/ICount.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Interface/IDataValidate.cs b/Assets/MagicaCloth2/Scripts/Core/Interface/IDataValidate.cs new file mode 100644 index 00000000..2c58f954 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Interface/IDataValidate.cs @@ -0,0 +1,14 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp + +namespace MagicaCloth2 +{ + /// + /// 対象データの検証を行うインターフェース + /// + interface IDataValidate + { + void DataValidate(); + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/Interface/IDataValidate.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Interface/IDataValidate.cs.meta new file mode 100644 index 00000000..c3b853d1 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Interface/IDataValidate.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 2aed426981579da48863288c708602e1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Interface/IDataValidate.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Interface/ITransform.cs b/Assets/MagicaCloth2/Scripts/Core/Interface/ITransform.cs new file mode 100644 index 00000000..44d55c95 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Interface/ITransform.cs @@ -0,0 +1,25 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using System.Collections.Generic; +using UnityEngine; + +namespace MagicaCloth2 +{ + interface ITransform + { + /// + /// 利用しているすべてのトランスフォームをtransformSetに追加する + /// + /// + void GetUsedTransform(HashSet transformSet); + + /// + /// 利用しているトランスフォームを置換する + /// key:置換対象トランスフォームのインスタンスID + /// value:入れ替えるトランスフォーム + /// + /// + void ReplaceTransform(Dictionary replaceDict); + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/Interface/ITransform.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Interface/ITransform.cs.meta new file mode 100644 index 00000000..c9f138ef --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Interface/ITransform.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 858cfe74dc6869c45a9b36ce74ac38fd +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Interface/ITransform.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Interface/IValid.cs b/Assets/MagicaCloth2/Scripts/Core/Interface/IValid.cs new file mode 100644 index 00000000..1de6a5a7 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Interface/IValid.cs @@ -0,0 +1,14 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp + +namespace MagicaCloth2 +{ + /// + /// 対象の有効性を返すインターフェース + /// + interface IValid + { + bool IsValid(); + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/Interface/IValid.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Interface/IValid.cs.meta new file mode 100644 index 00000000..532b2cd7 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Interface/IValid.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: eb1ee379472ac3645b05adb8c510f7d5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Interface/IValid.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Manager.meta b/Assets/MagicaCloth2/Scripts/Core/Manager.meta new file mode 100644 index 00000000..b8cbb6c6 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Manager.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 492826d943669524b9276f8ff4cd1229 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/MagicaCloth2/Scripts/Core/Manager/Cloth.meta b/Assets/MagicaCloth2/Scripts/Core/Manager/Cloth.meta new file mode 100644 index 00000000..b2c99317 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Manager/Cloth.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: db324c6d33cc19149bd3825ccfe7d94a +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/MagicaCloth2/Scripts/Core/Manager/Cloth/ClothManager.cs b/Assets/MagicaCloth2/Scripts/Core/Manager/Cloth/ClothManager.cs new file mode 100644 index 00000000..ae39b232 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Manager/Cloth/ClothManager.cs @@ -0,0 +1,337 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using System.Collections.Generic; +using System.Text; +using Unity.Jobs; +using Unity.Profiling; +using UnityEngine; + +namespace MagicaCloth2 +{ + /// + /// 各クロスコンポーネントの更新処理 + /// + public class ClothManager : IManager, IValid + { + // すべて + internal HashSet clothSet = new HashSet(256); + + // BoneCloth,BoneSpring + internal HashSet boneClothSet = new HashSet(); + + // MeshCloth + internal HashSet meshClothSet = new HashSet(); + + //========================================================================================= + Dictionary animatorVisibleDict = new Dictionary(30); + Dictionary rendererVisibleDict = new Dictionary(100); + + //========================================================================================= + /// + /// マスタージョブハンドル + /// + JobHandle masterJob = default; + + bool isValid = false; + + //========================================================================================= + public void Dispose() + { + isValid = false; + + clothSet.Clear(); + boneClothSet.Clear(); + meshClothSet.Clear(); + + // 作業バッファ + animatorVisibleDict.Clear(); + rendererVisibleDict.Clear(); + + // 更新処理 + MagicaManager.afterEarlyUpdateDelegate -= OnEarlyClothUpdate; + MagicaManager.firstPreUpdateDelegate -= OnFirstPreUpdate; + MagicaManager.afterLateUpdateDelegate -= OnAfterLateUpdate; + MagicaManager.beforeLateUpdateDelegate -= OnBeforeLateUpdate; + } + + public void EnterdEditMode() + { + Dispose(); + } + + public void Initialize() + { + clothSet.Clear(); + boneClothSet.Clear(); + meshClothSet.Clear(); + + // 作業バッファ + + // 更新処理 + MagicaManager.afterEarlyUpdateDelegate += OnEarlyClothUpdate; + MagicaManager.firstPreUpdateDelegate += OnFirstPreUpdate; + MagicaManager.afterLateUpdateDelegate += OnAfterLateUpdate; + MagicaManager.beforeLateUpdateDelegate += OnBeforeLateUpdate; + + isValid = true; + } + + public bool IsValid() + { + return isValid; + } + + //========================================================================================= + void ClearMasterJob() + { + masterJob = default; + } + + void CompleteMasterJob() + { + masterJob.Complete(); + } + + //========================================================================================= + internal int AddCloth(ClothProcess cprocess, in ClothParameters clothParams) + { + // この段階でProxyMeshは完成している + if (isValid == false) + return 0; + + // チーム登録 + var teamId = MagicaManager.Team.AddTeam(cprocess, clothParams); + if (teamId == 0) + return 0; + + clothSet.Add(cprocess); + switch (cprocess.clothType) + { + case ClothProcess.ClothType.BoneCloth: + case ClothProcess.ClothType.BoneSpring: + boneClothSet.Add(cprocess); + break; + case ClothProcess.ClothType.MeshCloth: + meshClothSet.Add(cprocess); + break; + default: + Develop.LogError($"Invalid cloth type! :{cprocess.clothType}"); + break; + } + + // チームマネージャの作業バッファへ登録 + MagicaManager.Team.comp2TeamIdMap.Add(cprocess.cloth.GetMagicaId(), teamId); + + return teamId; + } + + internal void RemoveCloth(ClothProcess cprocess) + { + if (isValid == false) + return; + + // チーム解除 + MagicaManager.Team.RemoveTeam(cprocess.TeamId); + + clothSet.Remove(cprocess); + boneClothSet.Remove(cprocess); + meshClothSet.Remove(cprocess); + } + + //========================================================================================= + /// + /// フレーム開始時に実行される更新処理 + /// + void OnEarlyClothUpdate() + { + //Debug.Log($"OnEarlyClothUpdate. F:{Time.frameCount}"); + if (MagicaManager.Team.TrueTeamCount > 0) // カリング判定があるのでDisableチームもまわす必要がある + { + // カメラカリング更新 + if (MagicaManager.Team.ActiveTeamCount > 0) + { + // この更新は次のTransform復元の前に行う必要がある + MagicaManager.Team.CameraCullingPostProcess(); + } + + // BoneClothのTransform復元更新 + ClearMasterJob(); + masterJob = MagicaManager.Bone.RestoreTransform(masterJob); + CompleteMasterJob(); + } + } + + /// + /// 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) + ClothUpdate(); + } + + void OnAfterLateUpdate() + { + if (MagicaManager.Time.updateLocation == TimeManager.UpdateLocation.AfterLateUpdate) + ClothUpdate(); + } + + //========================================================================================= + 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"); + + /// + /// クロスコンポーネントの更新 + /// + void ClothUpdate() + { + if (MagicaManager.IsPlaying() == false) + return; + + // ■コンポーネント0なら終了 + var tm = MagicaManager.Team; + if (tm.TrueTeamCount == 0) + return; + + //----------------------------------------------------------------- + // シミュレーション開始イベント + MagicaManager.OnPreSimulation?.Invoke(); + + //----------------------------------------------------------------- + var sm = MagicaManager.Simulation; + var bm = MagicaManager.Bone; + var wm = MagicaManager.Wind; + + //Debug.Log($"StartClothUpdate. F:{Time.frameCount}"); + //Develop.DebugLog($"StartClothUpdate. F:{Time.frameCount}, dtime:{Time.deltaTime}, stime:{Time.smoothDeltaTime}"); + + //----------------------------------------------------------------- + // ■時間マネージャ更新 + startClothUpdateTimeProfiler.Begin(); + MagicaManager.Time.FrameUpdate(); + startClothUpdateTimeProfiler.End(); + + // ■常に実行するチーム更新 + startClothUpdateTeamProfiler.Begin(); + tm.AlwaysTeamUpdate(); + startClothUpdateTeamProfiler.End(); + + // ■ここで実行チーム数が0ならば終了 + if (tm.ActiveTeamCount == 0) + return; + + startClothUpdatePrePareProfiler.Begin(); + + // ■常に実行する風ゾーン更新 + wm.AlwaysWindUpdate(); + + // ■作業バッファ更新 + sm.WorkBufferUpdate(); + + startClothUpdatePrePareProfiler.End(); + + //----------------------------------------------------------------- + startClothUpdateScheduleProfiler.Begin(); + + // マスタージョブ初期化 + ClearMasterJob(); + + // ■トランスフォーム情報の読み込み + masterJob = bm.ReadTransformSchedule(masterJob); + + // ■シミュレーションジョブ + masterJob = sm.ClothSimulationSchedule(masterJob); + + startClothUpdateScheduleProfiler.End(); + //----------------------------------------------------------------- + //JobHandle.ScheduleBatchedJobs(); + + //----------------------------------------------------------------- + // ■ジョブ完了待ちの間に行う処理 + // カメラカリングの準備 + tm.CameraCullingPreProcess(); + + //----------------------------------------------------------------- + // ■現在は即時実行のためここでジョブの完了待ちを行う + CompleteMasterJob(); + + //----------------------------------------------------------------- + // シミュレーション終了イベント + MagicaManager.OnPostSimulation?.Invoke(); + } + + //========================================================================================= + internal void ClearVisibleDict() + { + animatorVisibleDict.Clear(); + rendererVisibleDict.Clear(); + } + + internal bool CheckVisible(Animator ani, List renderers) + { + if (ani) + { + MagicaObjectId id = ani.GetMagicaId(); + if (animatorVisibleDict.ContainsKey(id)) + return animatorVisibleDict[id]; + + bool visible = CheckRendererVisible(renderers); + animatorVisibleDict.Add(id, visible); + return visible; + } + else + { + return CheckRendererVisible(renderers); + } + } + + bool CheckRendererVisible(List renderers) + { + foreach (var ren in renderers) + { + if (ren) + { + bool visible; + MagicaObjectId id = ren.GetMagicaId(); + if (rendererVisibleDict.ContainsKey(id)) + { + visible = rendererVisibleDict[id]; + } + else + { + visible = ren.isVisible; + rendererVisibleDict.Add(id, visible); + } + if (visible) + return true; + } + } + + return false; + } + + //========================================================================================= + public void InformationLog(StringBuilder allsb) + { + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/Manager/Cloth/ClothManager.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Manager/Cloth/ClothManager.cs.meta new file mode 100644 index 00000000..d30bdc16 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Manager/Cloth/ClothManager.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 8dec4d0537176214d8a66dccf5860cee +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Manager/Cloth/ClothManager.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Manager/Cloth/PreBuildManager.cs b/Assets/MagicaCloth2/Scripts/Core/Manager/Cloth/PreBuildManager.cs new file mode 100644 index 00000000..a4436f7c --- /dev/null +++ b/Assets/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/MagicaCloth2/Scripts/Core/Manager/Cloth/PreBuildManager.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Manager/Cloth/PreBuildManager.cs.meta new file mode 100644 index 00000000..1cd75d31 --- /dev/null +++ b/Assets/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.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Manager/Cloth/PreBuildManager.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Manager/IManager.cs b/Assets/MagicaCloth2/Scripts/Core/Manager/IManager.cs new file mode 100644 index 00000000..faa63d4e --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Manager/IManager.cs @@ -0,0 +1,28 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using System; +using System.Text; + +namespace MagicaCloth2 +{ + public interface IManager : IDisposable + { + /// + /// 初期化 + /// 実行状態に入ったときに呼ばれる + /// + void Initialize(); + + /// + /// ゲームプレイの実行が停止したときに呼ばれる(エディタ環境のみ) + /// + void EnterdEditMode(); + + /// + /// 情報ログ収集 + /// + /// + void InformationLog(StringBuilder allsb); + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/Manager/IManager.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Manager/IManager.cs.meta new file mode 100644 index 00000000..e22a1885 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Manager/IManager.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 3c48e53d99f78f84c894c528fea63af5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Manager/IManager.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Manager/MagicaManager.cs b/Assets/MagicaCloth2/Scripts/Core/Manager/MagicaManager.cs new file mode 100644 index 00000000..a10685fc --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Manager/MagicaManager.cs @@ -0,0 +1,484 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using System; +using System.Collections.Generic; +using UnityEngine; +using UnityEngine.LowLevel; +using System.Linq; +using UnityEngine.Scripting; +#if UNITY_EDITOR +using UnityEditor.Compilation; +using UnityEditor; +#if UNITY_2023_1_OR_NEWER +using UnityEditor.Build; +#endif +#endif + +// コードストリッピングを無効化する +[assembly: AlwaysLinkAssembly] + +namespace MagicaCloth2 +{ + /// + /// MagicaClothマネージャ + /// + public static partial class MagicaManager + { + //========================================================================================= + /// + /// 登録マネージャリスト + /// + static List managers = null; + + public static TimeManager Time => managers?[0] as TimeManager; + public static TeamManager Team => managers?[1] as TeamManager; + public static ClothManager Cloth => managers?[2] as ClothManager; + public static RenderManager Render => managers?[3] as RenderManager; + public static TransformManager Bone => managers?[4] as TransformManager; + public static VirtualMeshManager VMesh => managers?[5] as VirtualMeshManager; + 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 + public delegate void UpdateMethod(); + + /// + /// フレームの開始時、すべてのEarlyUpdateの後、FixedUpdate()の前 + /// + public static UpdateMethod afterEarlyUpdateDelegate; + + /// + /// FixedUpdate()の後 + /// + public static UpdateMethod afterFixedUpdateDelegate; + + /// + /// PreUpdate()の開始直後 + /// + public static UpdateMethod firstPreUpdateDelegate; + + /// + /// Update()の後 + /// + public static UpdateMethod afterUpdateDelegate; + + /// + /// LateUpdate()の前 + /// + public static UpdateMethod beforeLateUpdateDelegate; + + /// + /// LateUpdate()の後 + /// + public static UpdateMethod afterLateUpdateDelegate; + + /// + /// LateUpdate()後の遅延処理後、yield nullの後 + /// + public static UpdateMethod afterDelayedDelegate; + + /// + /// レンダリング完了後 + /// + public static UpdateMethod afterRenderingDelegate; + + /// + /// 汎用的な定期更新 + /// ゲーム実行中はUpdate()後に呼び出さる。 + /// エディタではEditorApplication.updateデリゲートにより呼び出される。 + /// + public static UpdateMethod defaultUpdateDelegate; + + + //========================================================================================= + static volatile bool isPlaying = false; + + //========================================================================================= + /// + /// Reload Domain 対策 + /// + [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] + static void Initialize() + { + Dispose(); + + // Reload Domainを設定しているとstatic変数が実行時に初期化されない + // そのためここでstatic変数の再初期化を行う必要がある + Develop.DebugLog("SubsystemRegistration"); + +#if UNITY_EDITOR + // スクリプトコンパイル開始コールバック + CompilationPipeline.compilationStarted += OnStarted; +#endif + + // 各マネージャの初期化 + managers = new List(); + managers.Add(new TimeManager()); // [0] + managers.Add(new TeamManager()); // [1] + managers.Add(new ClothManager()); // [2] + managers.Add(new RenderManager()); // [3] + managers.Add(new TransformManager()); // [4] + managers.Add(new VirtualMeshManager()); // [5] + 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; + } + +#if UNITY_EDITOR + /// + /// エディタの実行状態が変更された場合に呼び出される + /// + [InitializeOnLoadMethod] + static void PlayModeStateChange() + { + // プロジェクトセッティングにMagicaCloth2用デファインシンボルを登録する + try + { +#if UNITY_2023_1_OR_NEWER + var namedBuildTarget = NamedBuildTarget.FromBuildTargetGroup(EditorUserBuildSettings.selectedBuildTargetGroup); + PlayerSettings.GetScriptingDefineSymbols(namedBuildTarget, out string[] newDefines); + if (newDefines.Contains(Define.System.DefineSymbol) == false) + { + PlayerSettings.SetScriptingDefineSymbols(namedBuildTarget, newDefines.Concat(new string[] { Define.System.DefineSymbol }).ToArray()); + } +#else + var newDefines = PlayerSettings.GetScriptingDefineSymbolsForGroup(EditorUserBuildSettings.selectedBuildTargetGroup).Split(';'); + if (newDefines.Contains(Define.System.DefineSymbol) == false) + { + PlayerSettings.SetScriptingDefineSymbolsForGroup(EditorUserBuildSettings.selectedBuildTargetGroup, newDefines.Concat(new string[] { Define.System.DefineSymbol }).ToArray()); + } +#endif + } + catch (Exception e) + { + Debug.LogException(e); + } + + // エディタ状態変更時イベント処理 + EditorApplication.playModeStateChanged += (mode) => + { + Develop.DebugLog($"PlayModeStateChanged:{mode} F:{UnityEngine.Time.frameCount}"); + + if (mode == UnityEditor.PlayModeStateChange.EnteredEditMode) + { + // ★ここではマネージャを破棄しない + // ★スケジュールされたジョブなどはエディタ実行停止後も完了まで稼働し続けるため。 + + // 実行状態の終了 + isPlaying = false; + //isValid = false; + EnterdEditMode(); + + // エディタでの定期更新開始 + EditorApplication.update += EditoruUpdate; + } + + if (mode == UnityEditor.PlayModeStateChange.ExitingEditMode) + { + // エディタでの定期更新終了 + EditorApplication.update -= EditoruUpdate; + } + + + //if (mode == UnityEditor.PlayModeStateChange.ExitingEditMode || mode == UnityEditor.PlayModeStateChange.ExitingPlayMode) + //{ + // // 各マネージャの終了 + // // ★どうもこの呼出後に1フレームゲームが更新されてしまうようだ + // // ★なのですぐDispose()すると色々面倒なことになる + // //rendererManager?.Dispose(); + // //rendererManager = null; + //} + }; + } + + /// + /// スクリプトコンパイル開始 + /// + /// + static void OnStarted(object obj) + { + //Debug.Log($"スクリプトコンパイル開始"); + isPlaying = false; + EnterdEditMode(); + //Dispose(); + + } + + /// + /// スクリプトコンパイル後 + /// + //[DidReloadScripts(0)] + //static void ReloadScripts() + //{ + // //Initialize(); + //} + + /// + /// ゲームプレイの実行が停止したとき(エディタ環境のみ) + /// + static void EnterdEditMode() + { + //Debug.Log($"★Manager Enterd Edit Mode."); + if (managers != null) + { + //int index = 0; + foreach (var manager in managers) + { + //Debug.Log($"Dispose [{index}] start."); + manager.EnterdEditMode(); + //Debug.Log($"Dispose [{index}] end."); + //index++; + } + } + } + + /// + /// エディタでの定期更新 + /// + static void EditoruUpdate() + { + defaultUpdateDelegate?.Invoke(); + } +#endif + + /// + /// アプリ終了イベント + /// + static void OnAppQuitting() + { + Develop.DebugLog($"OnAppQuitting!"); + Dispose(); + } + + /// + /// マネージャの破棄 + /// + static void Dispose() + { + Develop.DebugLog("Manager Dispose!"); + + if (managers != null) + { + foreach (var manager in managers) + manager.Dispose(); + managers = null; + } + + // clear static member. + OnPreSimulation = null; + OnPostSimulation = null; + + Application.quitting -= OnAppQuitting; + + isPlaying = false; + } + + public static bool IsPlaying() + { + //return isPlaying; + return isPlaying && Application.isPlaying; + } + + //========================================================================================= + /// + /// カスタム更新ループ登録 + /// すでに登録されている場合は何もしない + /// Custom update loop registration. + /// Do nothing if already registered. + /// + public static void InitCustomGameLoop() + { + //Debug.Log("PhysicsManager.InitCustomGameLoop()"); + PlayerLoopSystem playerLoop = PlayerLoop.GetCurrentPlayerLoop(); + + // すでに設定されているならばスルー + if (CheckRegist(ref playerLoop)) + { + //Develop.DebugLog("SetCustomGameLoop Skip!!"); + return; + } + + // MagicaCloth用PlayerLoopを追加 + SetCustomGameLoop(ref playerLoop); + + PlayerLoop.SetPlayerLoop(playerLoop); + } + + static void SetCustomGameLoop(ref PlayerLoopSystem playerLoop) + { +#if false + // debug + foreach (var header in playerLoop.subSystemList) + { + Debug.LogFormat("------{0}------", header.type.Name); + foreach (var subSystem in header.subSystemList) + { + Debug.LogFormat("{0}.{1}", header.type.Name, subSystem.type.Name); + } + } +#endif + + // after early update + // フレームの開始時、すべてのEarlyUpdateの後、FixedUpdate()の前 + PlayerLoopSystem afterEarlyUpdate = new PlayerLoopSystem() + { + type = typeof(MagicaManager), + updateDelegate = () => afterEarlyUpdateDelegate?.Invoke() + }; + AddPlayerLoop(afterEarlyUpdate, ref playerLoop, "EarlyUpdate", string.Empty, firstLast: 1); + + // after fixed update + // FixedUpdate()の後 + PlayerLoopSystem afterFixedUpdate = new PlayerLoopSystem() + { + type = typeof(MagicaManager), + updateDelegate = () => + { + afterFixedUpdateDelegate?.Invoke(); + } + }; + 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() + { + type = typeof(MagicaManager), + updateDelegate = () => + { + afterUpdateDelegate?.Invoke(); + + // 実行時の汎用定期更新呼び出し + if (Application.isPlaying) + { + defaultUpdateDelegate?.Invoke(); + } + } + }; + AddPlayerLoop(afterUpdate, ref playerLoop, "Update", "ScriptRunDelayedTasks"); + + // before late update + // LateUpdate()の前 + PlayerLoopSystem beforeLateUpdate = new PlayerLoopSystem() + { + type = typeof(MagicaManager), + updateDelegate = () => beforeLateUpdateDelegate?.Invoke() + }; + AddPlayerLoop(beforeLateUpdate, ref playerLoop, "PreLateUpdate", "ScriptRunBehaviourLateUpdate", before: true); + + // after late update + // LateUpdate()の後 + PlayerLoopSystem afterLateUpdate = new PlayerLoopSystem() + { + type = typeof(MagicaManager), + updateDelegate = () => afterLateUpdateDelegate?.Invoke() + }; + AddPlayerLoop(afterLateUpdate, ref playerLoop, "PreLateUpdate", "ScriptRunBehaviourLateUpdate"); + + // after delayed update + // LateUpdate()後の遅延処理後、yield nullの後 + // LateUpdate()やアセットバンドルロード完了コールバックでコンポーネントをインスタンス化すると、 + // Start()が少し遅れてPostLateUpdateのScriptRunDelayedDynamicFrameRateで呼ばれることになる。 + // 遅延実行時にこの処理が入ると、すでにクロスシミュレーションのジョブが開始されているため、 + // Start()の初期化処理などでNativeリストにアクセスすると例外が発生してしまう。 + // 従って遅延実行時はクロスコンポーネントのStart()が完了するScriptRunDelayedDynamicFrameRate + // の後にシミュレーションを開始するようにする。 + PlayerLoopSystem afterDelayedUpdate = new PlayerLoopSystem() + { + type = typeof(MagicaManager), + updateDelegate = () => afterDelayedDelegate?.Invoke() + }; + AddPlayerLoop(afterDelayedUpdate, ref playerLoop, "PostLateUpdate", "ScriptRunDelayedDynamicFrameRate"); + + // after rendering + // レンダリング完了後 + PlayerLoopSystem afterRendering = new PlayerLoopSystem() + { + type = typeof(MagicaManager), + updateDelegate = () => afterRenderingDelegate?.Invoke() + }; + AddPlayerLoop(afterRendering, ref playerLoop, "PostLateUpdate", "FinishFrameRendering"); + } + + /// + /// methodをPlayerLoopの(categoryName:systemName)の次に追加する + /// + /// + /// + /// + /// + 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 (firstLast < 0) + { + // 最初に追加 + systemList.Insert(0, method); + } + else if (firstLast > 0) + { + // 最後に追加 + systemList.Add(method); + } + else + { + int index = systemList.FindIndex(h => h.type.Name.Contains(systemName)); + if (before) + systemList.Insert(index, method); + else + systemList.Insert(index + 1, method); + } + + category.subSystemList = systemList.ToArray(); + playerLoop.subSystemList[sysIndex] = category; + } + + /// + /// MagicaClothのカスタムループが登録されているかチェックする + /// + /// + /// + static bool CheckRegist(ref PlayerLoopSystem playerLoop) + { + var t = typeof(MagicaManager); + foreach (var subloop in playerLoop.subSystemList) + { + if (subloop.subSystemList != null && subloop.subSystemList.Any(x => x.type == t)) + { + return true; + } + } + return false; + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/Manager/MagicaManager.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Manager/MagicaManager.cs.meta new file mode 100644 index 00000000..4390ccaf --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Manager/MagicaManager.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 8bdae5377302cd04ab0a69a465d06991 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Manager/MagicaManager.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Manager/MagicaManagerAPI.cs b/Assets/MagicaCloth2/Scripts/Core/Manager/MagicaManagerAPI.cs new file mode 100644 index 00000000..514ace74 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Manager/MagicaManagerAPI.cs @@ -0,0 +1,224 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using System; +using UnityEngine; + +namespace MagicaCloth2 +{ + /// + /// MagicaCloth manager API + /// + public static partial class MagicaManager + { + /// + /// シミュレーション開始前イベント + /// Pre-simulation event. + /// + public static Action OnPreSimulation; + + /// + /// シミュレーション完了後イベント + /// Post-simulation event. + /// + public static Action OnPostSimulation; + + + /// + /// グローバルタイムスケールを変更します + /// Change the global time scale. + /// + /// 0.0-1.0 + public static void SetGlobalTimeScale(float timeScale) + { + if (IsPlaying()) + { + Time.GlobalTimeScale = Mathf.Clamp01(timeScale); + } + } + + /// + /// グローバルタイムスケールを取得します + /// Get the global time scale. + /// + /// + public static float GetGlobalTimeScale() + { + if (IsPlaying()) + { + return Time.GlobalTimeScale; + } + else + { + Develop.LogError("MagicaManager is not starting!"); + return 1.0f; + } + } + + /// + /// シミュレーションの周波数を設定します(30~150, 初期値90) + /// 周波数を上げると精度が高くなりますが負荷が上がります、下げるげると精度が低くなりますが負荷が下がります + /// そのため60以下に下げる場合には精度問題に十分注意してください + /// + /// Sets the simulation frequency (30~150, default 90). + /// Increasing the frequency increases the accuracy but increases the load, and decreasing the frequency decreases the accuracy but reduces the load. + /// Therefore, if you lower it below 60, be very careful about accuracy issues. + /// + /// + public static void SetSimulationFrequency(int freq) + { + if (IsPlaying()) + Time.simulationFrequency = Mathf.Clamp(freq, Define.System.SimulationFrequency_Low, Define.System.SimulationFrequency_Hi); + } + + /// + /// 現在のシミュレーション周波数を取得します + /// Get current simulation frequency. + /// + /// + public static int GetSimulationFrequency() + { + if (IsPlaying()) + return Time.simulationFrequency; + else + { + Develop.LogError("MagicaManager is not starting!"); + return 0; + } + } + + /// + /// 1フレームで実行される最大のシミュレーション回数を設定します(1~5, 初期値3) + /// シミュレーションはフレームレート(fps)とは非同期に実行されます + /// そのためfpsが下がると1フレームに実行されるシミュレーション回数が増えて負荷が高くなります + /// これはモバイル端末などで問題になる場合があります + /// 1フレームで実行されるシミュレーション回数を下げることで最大負荷を調整できます + /// 制限によりシミュレーションがスキップされた場合は補間機能により動作が補われます + /// + /// Set the maximum number of simulations to be executed in one frame (1 to 5, initial value 3) + /// The simulation runs asynchronously with the frame rate(fps). + /// Therefore, when the fps decreases, the number of simulations executed in one frame increases and the load increases. + /// This can be a problem on mobile devices, for example. + /// You can adjust the maximum load by lowering the number of simulations executed in one frame. + /// If the simulation is skipped due to restrictions, the interpolation function compensates for the motion. + /// + /// + public static void SetMaxSimulationCountPerFrame(int count) + { + if (IsPlaying()) + Time.maxSimulationCountPerFrame = Mathf.Clamp(count, Define.System.MaxSimulationCountPerFrame_Low, Define.System.MaxSimulationCountPerFrame_Hi); + } + + /// + /// 現在のフレームごとの最大シミュレーション回数を取得します + /// Gets the current maximum number of simulations per frame. + /// + /// + public static int GetMaxSimulationCountPerFrame() + { + if (IsPlaying()) + return Time.maxSimulationCountPerFrame; + else + { + Develop.LogError("MagicaManager is not starting!"); + return 0; + } + } + + /// + /// シミュレーションの更新場所を変更します + /// Change the simulation update location. + /// + /// + public static void SetUpdateLocation(TimeManager.UpdateLocation updateLocation) + { + if (IsPlaying()) + Time.updateLocation = updateLocation; + } + + /// + /// 現在のシミュレーションの更新場所を取得します + /// Get the current simulation update location. + /// + /// + public static TimeManager.UpdateLocation GetUpdateLocation() + { + if (IsPlaying()) + return Time.updateLocation; + else + { + Develop.LogError("MagicaManager is not starting!"); + 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/MagicaCloth2/Scripts/Core/Manager/MagicaManagerAPI.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Manager/MagicaManagerAPI.cs.meta new file mode 100644 index 00000000..42686139 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Manager/MagicaManagerAPI.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 5303b9f714439aa46a30b236862f8278 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Manager/MagicaManagerAPI.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Manager/MagicaSettings.cs b/Assets/MagicaCloth2/Scripts/Core/Manager/MagicaSettings.cs new file mode 100644 index 00000000..4dd56055 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Manager/MagicaSettings.cs @@ -0,0 +1,169 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using UnityEngine; + +namespace MagicaCloth2 +{ + /// + /// Magica manger settings component + /// + [AddComponentMenu("MagicaCloth2/MagicaSettings")] + [HelpURL("https://magicasoft.jp/en/mc2_settings_component/")] + public class MagicaSettings : ClothBehaviour + { + public enum RefreshMode + { + /// + /// コンポーネントのAwake()で1度だけ送信する + /// Send once at the component's Awake() + /// + OnAwake = 0, + + /// + /// 毎フレーム内容を送信する + /// 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, + } + + /// + /// コンポーネントの内容をマネージャに送信する方法 + /// How to send the contents of a component to the manager. + /// Refresh mode + /// + public RefreshMode refreshMode = RefreshMode.OnAwake; + + /// + /// シミュレーション周波数(30~150, 初期値90) + /// 周波数を上げると精度が高くなりますが負荷が上がります、下げるげると精度が低くなりますが負荷が下がります + /// そのため60以下に下げる場合には精度問題に十分注意してください + /// + /// Simulation frequency (30~150, default 90). + /// Increasing the frequency increases the accuracy but increases the load, and decreasing the frequency decreases the accuracy but reduces the load. + /// Therefore, if you lower it below 60, be very careful about accuracy issues. + /// + [Range(Define.System.SimulationFrequency_Low, Define.System.SimulationFrequency_Hi)] + public int simulationFrequency = Define.System.DefaultSimulationFrequency; + + /// + /// 1フレームの最大シミュレーション回数(1~5, 初期値3) + /// シミュレーションはフレームレート(fps)とは非同期に実行されます + /// そのためfpsが下がると1フレームに実行されるシミュレーション回数が増えて負荷が高くなります + /// これはモバイル端末などで問題になる場合があります + /// 1フレームで実行されるシミュレーション回数を下げることで最大負荷を調整できます + /// 制限によりシミュレーションがスキップされた場合は補間機能により動作が補われます + /// + /// Maximum number of simulations per frame (1 to 5, default value 3). + /// The simulation runs asynchronously with the frame rate(fps). + /// Therefore, when the fps decreases, the number of simulations executed in one frame increases and the load increases. + /// This can be a problem on mobile devices, for example. + /// You can adjust the maximum load by lowering the number of simulations executed in one frame. + /// If the simulation is skipped due to restrictions, the interpolation function compensates for the motion. + /// + [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で利用する場合に必要です。 + /// AfterLateUpdate : LateUpdate()の後に実行します。初期設定。 + /// + /// Simulation update location. + /// BeforeLateUpdate : Executes before LateUpdate(). This is required when using Unity 2D Animation. + /// AfterLateUpdate : Executes after LateUpdate(). Initial setting. + /// + 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; + + //========================================================================================= + protected void Awake() + { + if (refreshMode == RefreshMode.OnAwake) + Refresh(); + } + + protected void Start() + { + if (refreshMode == RefreshMode.OnStart) + Refresh(); + } + + protected void Update() + { + if (refreshMode == RefreshMode.EveryFrame) + Refresh(); + } + + protected void OnValidate() + { + if (Application.isPlaying) + Refresh(); + } + + //========================================================================================= + /// + /// コンポーネントの内容をマネージャに送信します + /// Sends the contents of the component to the manager. + /// + public void Refresh() + { + if (MagicaManager.IsPlaying()) + { + simulationFrequency = Mathf.Clamp(simulationFrequency, Define.System.SimulationFrequency_Low, Define.System.SimulationFrequency_Hi); + maxSimulationCountPerFrame = Mathf.Clamp(maxSimulationCountPerFrame, Define.System.MaxSimulationCountPerFrame_Low, Define.System.MaxSimulationCountPerFrame_Hi); + + MagicaManager.SetSimulationFrequency(simulationFrequency); + MagicaManager.SetMaxSimulationCountPerFrame(maxSimulationCountPerFrame); + MagicaManager.SetInitializationLocation(initializationLocation); + MagicaManager.SetUpdateLocation(updateLocation); + MagicaManager.SetSplitProxyMeshVertexCount(splitProxyMeshVertexCount); + + if (monitorPlayerLoop) + MagicaManager.InitCustomGameLoop(); + } + else + { + Develop.LogError("MagicaManager is not starting!"); + } + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/Manager/MagicaSettings.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Manager/MagicaSettings.cs.meta new file mode 100644 index 00000000..9aed950f --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Manager/MagicaSettings.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 9f2ecd6e147dc7c4f8f3c75ebc705f6b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: -50 + icon: {fileID: 2800000, guid: 4b0d1adb21ff82e4e8e9ea02f486a85f, type: 3} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Manager/MagicaSettings.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Manager/Render.meta b/Assets/MagicaCloth2/Scripts/Core/Manager/Render.meta new file mode 100644 index 00000000..30278450 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Manager/Render.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: d727233c727c4354e940f901aea4a9f7 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/MagicaCloth2/Scripts/Core/Manager/Render/RenderData.cs b/Assets/MagicaCloth2/Scripts/Core/Manager/Render/RenderData.cs new file mode 100644 index 00000000..14473bbe --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Manager/Render/RenderData.cs @@ -0,0 +1,427 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Unity.Collections; +using UnityEngine; + +namespace MagicaCloth2 +{ + /// + /// 描画対象の管理情報 + /// レンダラーまたはボーンの描画反映を行う + /// + public class RenderData : IDisposable, ITransform + { + /// + /// 参照カウント。0になると破棄される + /// + public int ReferenceCount { get; private set; } + + /// + /// 利用中のプロセス(=利用カウント) + /// + HashSet useProcessSet = new HashSet(); + + /// + /// Meshへの書き込み停止フラグ + /// + bool isSkipWriting; + + //========================================================================================= + // セットアップデータ + internal RenderSetupData setupData; + internal RenderSetupData.UniqueSerializationData preBuildUniqueSerializeData; + + internal string Name => setupData?.name ?? "(empty)"; + + internal bool HasSkinnedMesh => setupData?.hasSkinnedMesh ?? false; + internal bool HasBoneWeight => setupData?.hasBoneWeight ?? false; + + //========================================================================================= + // オリジナル情報 + 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; } + + // RenderDataWorkバッファへのインデックス(RenderManagerが管理) + internal int renderDataWorkIndex { get; private set; } = -1; + + //========================================================================================= + public void Dispose() + { + // オリジナルメッシュに戻す + SwapOriginalMesh(null); + + setupData?.Dispose(); + preBuildUniqueSerializeData = null; + + MagicaManager.Render.RemoveRenderDataWork(renderDataWorkIndex); + + if (customMesh) + GameObject.Destroy(customMesh); + } + + public void GetUsedTransform(HashSet transformSet) + { + setupData?.GetUsedTransform(transformSet); + } + + public void ReplaceTransform(Dictionary replaceDict) + { + setupData?.ReplaceTransform(replaceDict); + } + + /// + /// 初期化(メインスレッドのみ) + /// この処理はスレッド化できないので少し負荷がかかるが即時実行する + /// + /// + internal void Initialize( + Renderer ren, + RenderSetupData referenceSetupData, + RenderSetupData.UniqueSerializationData referencePreBuildUniqueSetupData, + RenderSetupSerializeData referenceInitSetupData + ) + { + Debug.Assert(ren); + + // セットアップデータ作成 + // PreBuildでは外部から受け渡される + if (referenceSetupData != null && referencePreBuildUniqueSetupData != null) + { + setupData = referenceSetupData; + preBuildUniqueSerializeData = referencePreBuildUniqueSetupData; + + 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; + + //========================================================================================= + internal int AddReferenceCount() + { + ReferenceCount++; + return ReferenceCount; + } + + internal int RemoveReferenceCount() + { + ReferenceCount--; + return ReferenceCount; + } + + //========================================================================================= + void SwapCustomMesh(ClothProcess process) + { + Debug.Assert(setupData != null); + + if (setupData.IsFaild()) + return; + if (originalMesh == null) + return; + if (MagicaManager.Render.IsSetRenderDataWorkFlag(renderDataWorkIndex, RenderManager.RenderDataFlag_UseCustomMesh)) + return; + + // カスタムメッシュの作成 + if (customMesh == null) + { + //Debug.Assert(setupData.originalMesh); + // クローン作成 + customMesh = GameObject.Instantiate(originalMesh); + customMesh.MarkDynamic(); + + // bind pose + if (HasBoneWeight) + { + 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(); + } + } + + // 作業バッファリセット + ResetCustomMeshWorkData(); + + // カスタムメッシュに表示切り替え + SetMesh(customMesh); + MagicaManager.Render.SetBitsRenderDataWorkFlag(renderDataWorkIndex, RenderManager.RenderDataFlag_UseCustomMesh, true); + + // Event + if (process != null && process.cloth) + 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; + + // オリジナルデータをコピーする + 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(ClothProcess process) + { + var rm = MagicaManager.Render; + + if (rm.IsSetRenderDataWorkFlag(renderDataWorkIndex, RenderManager.RenderDataFlag_UseCustomMesh) && setupData != null) + { + SetMesh(originalMesh); + + if (skinnedMeshRendere != null) + { + skinnedMeshRendere.bones = transformList.ToArray(); + } + } + rm.SetBitsRenderDataWorkFlag(renderDataWorkIndex, RenderManager.RenderDataFlag_UseCustomMesh, false); + + // Event + if (process != null && process.cloth) + process.cloth.OnRendererMeshChange?.Invoke(process.cloth, renderer, false); + } + + /// + /// レンダラーにメッシュを設定する + /// + /// + void SetMesh(Mesh mesh) + { + if (mesh == null) + return; + + if (setupData != null) + { + if (meshFilter != null) + { + meshFilter.mesh = mesh; + } + else if (skinnedMeshRendere != null) + { + skinnedMeshRendere.sharedMesh = mesh; + } + } + } + + //========================================================================================= + /// + /// 利用の開始 + /// 利用するということはメッシュに頂点を書き込むことを意味する + /// 通常コンポーネントがEnableになったときに行う + /// + public void StartUse(ClothProcess cprocess) + { + UpdateUse(cprocess, 1); + } + + /// + /// 利用の停止 + /// 停止するということはメッシュに頂点を書き込まないことを意味する + /// 通常コンポーネントがDisableになったときに行う + /// + public void EndUse(ClothProcess cprocess) + { + //Debug.Assert(useProcessSet.Count > 0); + UpdateUse(cprocess, -1); + } + + internal void UpdateUse(ClothProcess cprocess, int add) + { + if (add > 0) + { + useProcessSet.Add(cprocess); + } + else if (add < 0) + { + //Debug.Assert(useProcessSet.Count > 0); + if (useProcessSet.Contains(cprocess)) + useProcessSet.Remove(cprocess); + else + return; + } + + // Invisible状態 + bool invisible = useProcessSet.Any(x => (x.IsCameraCullingInvisible() && x.IsCameraCullingKeep() == false) || x.IsDistanceCullingInvisible()); + + // 状態変更 + bool modifyBoneWeight = false; + if (invisible || useProcessSet.Count == 0) + { + // 利用停止 + // オリジナルメッシュに切り替え + SwapOriginalMesh(cprocess); + } + else if (add == 0 && useProcessSet.Count > 0) + { + // カリング復帰 + // カスタムメッシュに切り替え、および作業バッファ作成 + // すでにカスタムメッシュが存在する場合は作業バッファのみ再初期化する + SwapCustomMesh(cprocess); + modifyBoneWeight = true; + } + else if (add > 0 && useProcessSet.Count == 1) + { + // 利用開始 + // カスタムメッシュに切り替え、および作業バッファ作成 + // すでにカスタムメッシュが存在する場合は作業バッファのみ再初期化する + SwapCustomMesh(cprocess); + modifyBoneWeight = true; + } + else if (add != 0) + { + // 複数から利用されている状態で1つが停止した。 + // バッファを最初期化する + ResetCustomMeshWorkData(); + 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)}"); + } + + //========================================================================================= + /// + /// Meshへの書き込みフラグを更新する + /// + internal void UpdateSkipWriting() + { + isSkipWriting = false; + foreach (var cprocess in useProcessSet) + { + if (cprocess.IsSkipWriting()) + isSkipWriting = true; + } + } + + //========================================================================================= + internal void WriteMesh() + { + 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 (wdata.flag.IsSet(RenderManager.RenderDataFlag_WritePositionNormal)) + { + 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 (wdata.flag.IsSet(RenderManager.RenderDataFlag_WriteTangent)) + { + customMesh.SetTangents(rm.renderMeshTangents.GetNativeArray(), wdata.renderMeshTangentChunk.startIndex, wdata.renderMeshTangentChunk.dataLength); + wdata.flag.SetBits(RenderManager.RenderDataFlag_WriteTangent, false); + //Debug.Log($"[{customMesh.name}] Write Tangent"); + } + if (wdata.flag.IsSet(RenderManager.RenderDataFlag_WriteBoneWeight)) + { + // 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"); + } + } + + //========================================================================================= + public override string ToString() + { + StringBuilder sb = new StringBuilder(); + + sb.Append($">>> [{Name}] ref:{ReferenceCount}, useProcess:{useProcessSet.Count}, HasSkinnedMesh:{HasSkinnedMesh}, HasBoneWeight:{HasBoneWeight}"); + sb.AppendLine(); + + return sb.ToString(); + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/Manager/Render/RenderData.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Manager/Render/RenderData.cs.meta new file mode 100644 index 00000000..efdab0df --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Manager/Render/RenderData.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: e66794d18ed5f514ebae30c42e05a9f1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Manager/Render/RenderData.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Manager/Render/RenderManager.cs b/Assets/MagicaCloth2/Scripts/Core/Manager/Render/RenderManager.cs new file mode 100644 index 00000000..7c305314 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Manager/Render/RenderManager.cs @@ -0,0 +1,403 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using System.Collections.Generic; +using System.Text; +using Unity.Collections; +using Unity.Mathematics; +using Unity.Profiling; +using UnityEngine; + +namespace MagicaCloth2 +{ + /// + /// 描画の管理とメッシュ更新マネージャ + /// + public class RenderManager : IManager, IValid + { + /// + /// 描画データをint型ハンドルで管理する + /// + 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; + + //========================================================================================= + public void Initialize() + { + 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; + + isValid = true; + } + + public void EnterdEditMode() + { + Dispose(); + } + + public void Dispose() + { + isValid = false; + + lock (renderDataDict) + { + foreach (var rinfo in renderDataDict.Values) + { + rinfo?.Dispose(); + } + } + 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; + } + + public bool IsValid() + { + return isValid; + } + + //========================================================================================= + /// + /// 管理するレンダラーの追加(メインスレッドのみ) + /// + /// + /// + public MagicaObjectId AddRenderer( + Renderer ren, + RenderSetupData referenceSetupData, + RenderSetupData.UniqueSerializationData referenceUniqueSetupData, + RenderSetupSerializeData referenceInitSetupData + ) + { + if (isValid == false) + return MagicaObjectId.Invalid; + Debug.Assert(ren); + + // 制御ハンドル + MagicaObjectId handle = ren.GetMagicaId(); + + lock (renderDataDict) + { + if (renderDataDict.ContainsKey(handle) == false) + { + // 新規 + var rdata = new RenderData(); + rdata.Initialize(ren, referenceSetupData, referenceUniqueSetupData, referenceInitSetupData); + renderDataDict.Add(handle, rdata); + } + + // 参照カウント+ + renderDataDict[handle].AddReferenceCount(); + } + + return handle; + } + + public bool RemoveRenderer(MagicaObjectId handle) + { + if (isValid == false) + return false; + + bool delete = false; + + //Debug.Log($"RemoveRenderer:{handle}"); + //Debug.Assert(ren); + Debug.Assert(renderDataDict.ContainsKey(handle)); + + lock (renderDataDict) + { + if (renderDataDict.ContainsKey(handle)) + { + var rdata = renderDataDict[handle]; + if (rdata.RemoveReferenceCount() == 0) + { + // 破棄する + rdata.Dispose(); + + renderDataDict.Remove(handle); + + delete = true; + } + } + } + + return delete; + } + + public RenderData GetRendererData(MagicaObjectId handle) + { + if (isValid == false) + return null; + + lock (renderDataDict) + { + if (renderDataDict.ContainsKey(handle)) + return renderDataDict[handle]; + else + return null; + + } + } + + //========================================================================================= + 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); + } + + //========================================================================================= + /// + /// 有効化 + /// + /// + public void StartUse(ClothProcess cprocess, MagicaObjectId handle) + { + GetRendererData(handle)?.StartUse(cprocess); + } + + /// + /// 無効化 + /// + /// + public void EndUse(ClothProcess cprocess, MagicaObjectId handle) + { + GetRendererData(handle)?.EndUse(cprocess); + } + + //========================================================================================= + 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(); + } + + //========================================================================================= + public void InformationLog(StringBuilder allsb) + { + StringBuilder sb = new StringBuilder(); + sb.AppendLine($"========== Render Manager =========="); + if (IsValid() == false) + { + sb.AppendLine($"Render Manager. Invalid."); + } + 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()); + } + } + sb.AppendLine(); + Debug.Log(sb.ToString()); + allsb.Append(sb); + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/Manager/Render/RenderManager.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Manager/Render/RenderManager.cs.meta new file mode 100644 index 00000000..73cabb52 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Manager/Render/RenderManager.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 99868f3bace6c8d4fa0de07238d7b777 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Manager/Render/RenderManager.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Manager/Render/RenderSetupData.cs b/Assets/MagicaCloth2/Scripts/Core/Manager/Render/RenderSetupData.cs new file mode 100644 index 00000000..893b4bfd --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Manager/Render/RenderSetupData.cs @@ -0,0 +1,911 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using System; +using System.Collections.Generic; +using Unity.Burst; +using Unity.Collections; +using Unity.Jobs; +using Unity.Mathematics; +using Unity.Profiling; +using UnityEngine; +using UnityEngine.Jobs; + +namespace MagicaCloth2 +{ + /// + /// 描画対象の基本情報 + /// レンダラーまたはボーン構成情報 + /// この情報をもとに仮想メッシュなどを作成する + /// またこの情報はキャラクターが動き出す前に取得しておく必要がある + /// そのためAwake()などで実行する + /// + public partial class RenderSetupData : IDisposable, ITransform + { + public ResultCode result; + public string name = string.Empty; + public bool isManaged; // pre-build DeserializeManager管理 + + // タイプ + public enum SetupType + { + MeshCloth = 0, + BoneCloth = 1, + BoneSpring = 2, + } + public SetupType setupType; + + // Mesh --------------------------------------------------------------- + // レンダラーとメッシュ情報 + public Renderer renderer; + public SkinnedMeshRenderer skinRenderer; + public MeshFilter meshFilter; + public Mesh originalMesh; + public int vertexCount; + public bool hasSkinnedMesh; // SkinnedMeshRendererを利用しているかどうか + public bool hasBoneWeight; // SkinnedMeshRendererでもボーンウエイトを持っていないケースあり! + 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 + { + // line only. + // ラインのみ + Line = 0, + + //Automatically mesh connection according to the interval of Transform. + // Transformの間隔に従い自動でメッシュ接続 + AutomaticMesh = 1, + + //Generate meshes in the order of Transforms registered in RootList and connect the beginning and end in a loop. + // RootListに登録されたTransformの順にメッシュを生成し、最初と最後をループ状に繋げる + SequentialLoopMesh = 2, + + // Generate meshes in the order of Transforms registered in RootList, but do not connect the beginning and end. + // RootListに登録されたTransformの順にメッシュを生成するが最初と最後を繋げない + SequentialNonLoopMesh = 3, + } + public BoneConnectionMode boneConnectionMode = BoneConnectionMode.Line; + public List collisionBoneIndexList; // BoneSpringのコリジョン有効Transformインデックスリスト + + // Common ------------------------------------------------------------- + // Transform情報 + // 通常メッシュはrenderTransorm100%のスキニングとして扱われる + public List transformList; // skin bonesは[0]~skinBoneCountまで + public List transformIdList; + public List transformParentIdList; // 親ID(0=なし) + public List> transformChildIdList; // 子IDリスト + public NativeArray transformPositions; + public NativeArray transformRotations; + public NativeArray transformLocalPositions; + public NativeArray transformLocalRotations; + public NativeArray transformScales; + public NativeArray transformInverseRotations; + public int renderTransformIndex; // 描画基準トランスフォーム + public float4x4 initRenderLocalToWorld; // 初期化時の基準マトリックス(LtoW) + public float4x4 initRenderWorldtoLocal; // 初期化時の基準マトリックス(WtoL) + public quaternion initRenderRotation; // 初期化時の基準回転 + public float3 initRenderScale; // 初期化時の基準スケール + + 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 readTransformProfiler = new ProfilerMarker("readTransform"); + + //========================================================================================= + public RenderSetupData() { } + + /// + /// レンダラーから基本情報を作成する(メインスレッドのみ) + /// タイプはMeshになる + /// + /// + public RenderSetupData(RenderSetupSerializeData referenceInitSetupData, Renderer ren) + { + //using (initProfiler.Auto()) + { + result.Clear(); + // Meshタイプに設定 + setupType = SetupType.MeshCloth; + + if (ren == null) + { + Develop.LogWarning("Renderer is null!"); + result.SetError(Define.Result.RenderSetup_InvalidSource); + return; + } + + // 初期化データの有無 + bool useInitData = referenceInitSetupData != null; + + name = ren.name; + + var sren = ren as SkinnedMeshRenderer; + + hasSkinnedMesh = sren ? true : false; + hasBoneWeight = false; + skinRenderer = sren; + Mesh mesh; + + // 必要なトランスフォーム情報 + // トランスフォームのクラスとインスタンスIDを収集する + // 描画の基準トランスフォーム + var renderTransform = ren.transform; + + 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 + // このスキニングボーンの取得が特に重くメモリアロケーションも頻発する問題児 + // しかし回避方法がないため現状やむなし + var bones = sren.bones; + if (bones == null || bones.Length == 0) + { + // ブレンドシェイプではボーンや頂点ウエイトが無くてもSkinnedMeshRendererが利用される + // ブレンドシェイプの機能がSkinnedMeshRendererにしか無いため + // そのため、このようなケースではSkinnedMeshRendererであるが通常メッシュとして扱うことにする + // bones + skinBoneCount = 1; + transformList = new List(skinBoneCount); + transformList.Add(renderTransform); + + // rootBone + skinRootBoneIndex = 0; + + // render + renderTransformIndex = 0; + } + else + { + skinBoneCount = bones.Length; + transformList = new List(skinBoneCount + 2); + transformList.AddRange(bones); + + // rootBone + var rootBone = sren.rootBone ? sren.rootBone : renderTransform; + skinRootBoneIndex = transformList.Count; + transformList.Add(rootBone); + + // render + renderTransformIndex = transformList.Count; + transformList.Add(renderTransform); + + hasBoneWeight = true; + } + } + else + { + // bones + skinBoneCount = 1; + transformList = new List(skinBoneCount); + transformList.Add(renderTransform); + + // rootBone + skinRootBoneIndex = 0; + + // render + renderTransformIndex = 0; + } + + // トランスフォーム情報の読み取り + ReadTransformInformation(includeChilds: false, referenceInitSetupData, ren.transform); + + // bindpose / weights + if (sren) + { + mesh = sren.sharedMesh; + if (mesh == null) + { + Develop.LogWarning("SkinnedMeshRenderer.sharedMesh is null!"); + result.SetError(Define.Result.RenderSetup_NoMeshOnRenderer); + return; + } + + if (hasBoneWeight) + { + bindPoseList = new List(mesh.bindposes); + + // どうもコピーを作らないとダメらしい.. + // ※具体的にはメッシュのクローンを作成したときに壊れる + 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() + { + vcnt = vcnt, + bonesPerVertexArray = bonesPerVertexArray, + result = bonesPerVertexResult, + }; + job.Run(); + result.SetWarning(bonesPerVertexResult.Value); +#endif + } + else + { + bindPoseList = new List(1); + bindPoseList.Add(Matrix4x4.identity); + } + } + else + { + if (!ren.TryGetComponent(out var filter)) + { + result.SetError(Define.Result.RenderSetup_InvalidSource); + return; + } + mesh = filter.sharedMesh; + if (mesh == null) + { + Develop.LogWarning("MeshFilter.sharedMesh is null!"); + result.SetError(Define.Result.RenderSetup_NoMeshOnRenderer); + return; + } + + bindPoseList = new List(1); + bindPoseList.Add(Matrix4x4.identity); + meshFilter = filter; + } + + if (mesh.isReadable == false) + { + result.SetError(Define.Result.RenderSetup_Unreadable); + return; + } + if (mesh.vertexCount > 65535) + { + result.SetError(Define.Result.RenderSetup_Over65535vertices); + return; + } + + // スレッドでメッシュデータを構築するためにオリジナルのMeshDataを取得する + // mesh data array + meshDataArray = Mesh.AcquireReadOnlyMeshData(mesh); + + // rendererとmeshを記録 + renderer = ren; + originalMesh = mesh; + vertexCount = mesh.vertexCount; + + // 完了 + result.SetSuccess(); + } + } + +#if UNITY_EDITOR + /// + /// 5ウエイト以上の検出 + /// + [BurstCompile] + struct VertexWeight5BoneCheckJob : IJob + { + public int vcnt; + + [Unity.Collections.ReadOnly] + public NativeArray bonesPerVertexArray; + + [Unity.Collections.WriteOnly] + public NativeReference result; + + public void Execute() + { + result.Value = Define.Result.None; + + for (int i = 0; i < vcnt; i++) + { + if (bonesPerVertexArray[i] >= 5) + { + result.Value = Define.Result.RenderMesh_VertexWeightIs5BonesOrMore; + break; + } + } + } + } +#endif + + /// + /// ルートボーンリストから基本情報を作成する(メインスレッドのみ) + /// タイプはBoneになる + /// + /// + /// + public RenderSetupData( + RenderSetupSerializeData referenceInitSetupData, + SetupType setType, + Transform renderTransform, + List rootTransforms, + List collisionBones, + BoneConnectionMode connectionMode = BoneConnectionMode.Line, + string name = "(no name)" + ) + { + result.Clear(); + + //using (initProfiler.Auto()) + try + { + bool useInitData = referenceInitSetupData != null; + + // Boneタイプに設定 + setupType = setType; + + // 接続モード + boneConnectionMode = connectionMode; + + if (renderTransform == null) + { + //Debug.LogWarning("render transform is null!"); + result.SetError(Define.Result.RenderSetup_InvalidSource); + return; + } + if (rootTransforms == null || rootTransforms.Count == 0) + { + //Debug.LogWarning("rootBones is empty!"); + result.SetError(Define.Result.RenderSetup_InvalidSource); + return; + } + + this.name = name; + + // 必要なトランスフォーム情報 + if (useInitData) + { + // 初期化データがある場合はコピーして終わり + transformList = new List(referenceInitSetupData.transformArray); + skinBoneCount = referenceInitSetupData.skinBoneCount; + renderTransformIndex = referenceInitSetupData.renderTransformIndex; + } + else + { + 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) + { + 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 + rootTransformIdList = new List(rootTransforms.Count); + foreach (var t in rootTransforms) + { + rootTransformIdList.Add(t.GetMagicaId()); + } + + // collision transform (use BoneSpring) + if (collisionBones != null) + { + collisionBoneIndexList = new List(collisionBones.Count); + foreach (var t in collisionBones) + { + if (t) + { + int index = transformList.IndexOf(t); + collisionBoneIndexList.Add(index); + //Debug.Log($"collision bones:{t.name}, index:{index}"); + } + } + } + + // トランスフォーム情報の読み取り + ReadTransformInformation(includeChilds: true, referenceInitSetupData, renderTransform); + + // 完了 + result.SetSuccess(); + } + catch (MagicaClothProcessingException) + { + if (result.IsError() == false) + result.SetError(Define.Result.RenderSetup_UnknownError); + result.DebugLog(); + } + catch (Exception exception) + { + Debug.LogException(exception); + result.SetError(Define.Result.RenderSetup_Exception); + } + } + + /// + /// トランスフォーム情報の読み取り(メインスレッドのみ) + /// この情報だけはキャラクターが動く前に取得する必要がある + /// + void ReadTransformInformation(bool includeChilds, RenderSetupSerializeData referenceInitSetupData, Transform rendererTransform) + { + readTransformProfiler.Begin(); + + int tcnt = transformList.Count; + bool useInitData = referenceInitSetupData != null; + + // バッファ作成 + transformPositions = new NativeArray(tcnt, Allocator.Persistent); + transformRotations = 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); + + // 読み取り + if (useInitData) + { + Debug.Assert(tcnt == referenceInitSetupData.transformCount); + + // 初期化データがある場合はコピーして終わり + int ucnt = referenceInitSetupData.useTransformCount; + + 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; + MagicaObjectId id = MagicaObjectId.Invalid; + MagicaObjectId pid = MagicaObjectId.Invalid; + + var t = transformList[i]; + if (t) + { + id = t.GetMagicaId(); + if (includeChilds && t.parent) + pid = t.parent.GetMagicaId(); + } + transformIdList.Add(id); + transformParentIdList.Add(pid); + } + + // child id + if (includeChilds) + { + transformChildIdList = new List>(tcnt); + for (int i = 0; i < tcnt; i++) + { + var t = transformList[i]; + var clist = new FixedList512Bytes(); + if (t && t.childCount > 0) + { + for (int j = 0; j < t.childCount; j++) + { + var ct = t.GetChild(j); + clist.Add(ct.GetMagicaId()); + } + } + 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; + } + } + } + + /// + /// 最低限のTransform情報を収集する + /// + [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; + + public void Execute(int index, TransformAccess transform) + { + if (transform.isValid == false) + return; + + transform.GetPositionAndRotation(out var pos, out var rot); + float4x4 LtoW = transform.localToWorldMatrix; + + positions[index] = pos; + rotations[index] = rot; + localPositions[index] = transform.localPosition; + localRotations[index] = transform.localRotation; + + // マトリックスから正確なスケール値を算出する(これはTransform.lossyScaleと等価) + var irot = math.inverse(rot); + var m2 = math.mul(new float4x4(irot, float3.zero), LtoW); + var scl = new float3(m2.c0.x, m2.c1.y, m2.c2.z); + scales[index] = scl; + + // 逆回転 + inverseRotations[index] = irot; + } + } + + public void Dispose() + { + // Pre-Build DeserializeManager管理中は破棄させない + if (isManaged) + return; + + 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) + { + if (meshDataArray.Length > 0) + meshDataArray.Dispose(); + } + } + + public void GetUsedTransform(HashSet transformSet) + { + if (transformList != null) + { + foreach (var t in transformList) + if (t) + transformSet.Add(t); + } + } + + public void ReplaceTransform(Dictionary replaceDict) + { + if (rootTransformIdList != null) + { + for (int i = 0; i < rootTransformIdList.Count; i++) + { + MagicaObjectId id = rootTransformIdList[i]; + if (replaceDict.ContainsKey(id)) + { + rootTransformIdList[i] = replaceDict[id].GetMagicaId(); + } + } + } + for (int i = 0; i < TransformCount; i++) + { + MagicaObjectId id = transformIdList[i]; + if (replaceDict.ContainsKey(id)) + { + var t = replaceDict[id]; + transformIdList[i] = t.GetMagicaId(); + transformList[i] = t; + } + MagicaObjectId pid = transformParentIdList[i]; + if (replaceDict.ContainsKey(pid)) + { + var t = replaceDict[pid]; + transformParentIdList[i] = t.GetMagicaId(); + } + + if (transformChildIdList != null) + { + var cidlist = transformChildIdList[i]; + for (int j = 0; j < cidlist.Length; j++) + { + MagicaObjectId cid = cidlist[j]; + if (replaceDict.ContainsKey(cid)) + { + var t = replaceDict[cid]; + cidlist[j] = t.GetMagicaId(); + } + } + transformChildIdList[i] = cidlist; + } + } + } + + //========================================================================================= + /// + /// 描画基準トランスフォームを取得する + /// + /// + public Transform GetRendeerTransform() + { + return transformList[renderTransformIndex]; + } + + public MagicaObjectId GetRenderTransformId() + { + return transformIdList[renderTransformIndex]; + } + + public float4x4 GetRendeerLocalToWorldMatrix() + { + int index = renderTransformIndex; + var pos = transformPositions[index]; + var rot = transformRotations[index]; + var scl = transformScales[index]; + return float4x4.TRS(pos, rot, scl); + } + + /// + /// スキンレンダラーのルートトランスフォームを取得する + /// + /// + public Transform GetSkinRootTransform() + { + return transformList[skinRootBoneIndex]; + } + + public MagicaObjectId GetSkinRootTransformId() + { + return transformIdList[skinRootBoneIndex]; + } + + public int GetTransformIndexFromId(MagicaObjectId id) + { + return transformIdList.IndexOf(id); + } + + /// + /// 指定indexの親トランスフォームのインデックスを返す(-1=なし) + /// + /// + /// true=センタートランスフォームは除外する + /// なし(-1) + public int GetParentTransformIndex(int index, bool centerExcluded) + { + MagicaObjectId pid = transformParentIdList[index]; + int i = transformIdList.IndexOf(pid); + if (centerExcluded && i == renderTransformIndex) + i = -1; + return i; + } + + //========================================================================================= + /// + /// オリジナルメッシュのボーンウエイトをBoneWeight構造体のNativeArrayで取得する + /// + /// + public void GetBoneWeightsRun(NativeArray weights) + { + var job = new GetBoneWeightJos() + { + vcnt = vertexCount, + bonesPerVertexArray = bonesPerVertexArray, + boneWeightArray = boneWeightArray, + boneWeights = weights, + }; + job.Run(); + } + + [BurstCompile] + struct GetBoneWeightJos : IJob + { + public int vcnt; + + [Unity.Collections.ReadOnly] + public NativeArray bonesPerVertexArray; + [Unity.Collections.ReadOnly] + public NativeArray boneWeightArray; + + [Unity.Collections.WriteOnly] + public NativeArray boneWeights; + + public void Execute() + { + int index = 0; + for (int i = 0; i < vcnt; i++) + { + var bw = new BoneWeight(); + + var cnt = bonesPerVertexArray[i]; + for (int j = 0; j < cnt; j++) + { + var bw1 = boneWeightArray[index]; + index++; + + switch (j) + { + case 0: + bw.weight0 = bw1.weight; + bw.boneIndex0 = bw1.boneIndex; + break; + case 1: + bw.weight1 = bw1.weight; + bw.boneIndex1 = bw1.boneIndex; + break; + case 2: + bw.weight2 = bw1.weight; + bw.boneIndex2 = bw1.boneIndex; + break; + case 3: + bw.weight3 = bw1.weight; + bw.boneIndex3 = bw1.boneIndex; + break; + } + } + + boneWeights[i] = bw; + } + } + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/Manager/Render/RenderSetupData.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Manager/Render/RenderSetupData.cs.meta new file mode 100644 index 00000000..9302df84 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Manager/Render/RenderSetupData.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 617681c5418abb546afd305310ef7cb9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Manager/Render/RenderSetupData.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Manager/Render/RenderSetupDataSerialization.cs b/Assets/MagicaCloth2/Scripts/Core/Manager/Render/RenderSetupDataSerialization.cs new file mode 100644 index 00000000..8389defa --- /dev/null +++ b/Assets/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) + { + MagicaObjectId id = t.GetMagicaId(); + if (id.IsValid() && 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/MagicaCloth2/Scripts/Core/Manager/Render/RenderSetupDataSerialization.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Manager/Render/RenderSetupDataSerialization.cs.meta new file mode 100644 index 00000000..6c0fb338 --- /dev/null +++ b/Assets/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.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Manager/Render/RenderSetupDataSerialization.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Manager/Render/RenderSetupSerializeData.cs b/Assets/MagicaCloth2/Scripts/Core/Manager/Render/RenderSetupSerializeData.cs new file mode 100644 index 00000000..48687e6c --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Manager/Render/RenderSetupSerializeData.cs @@ -0,0 +1,355 @@ +// 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; + + if (!ren.TryGetComponent(out var filter)) + 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.GetMagicaId())) + { + transformArray[i] = replaceDict[t.GetMagicaId()]; + } + } + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/Manager/Render/RenderSetupSerializeData.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Manager/Render/RenderSetupSerializeData.cs.meta new file mode 100644 index 00000000..9813e5d3 --- /dev/null +++ b/Assets/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.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Manager/Render/RenderSetupSerializeData.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Manager/Simulation.meta b/Assets/MagicaCloth2/Scripts/Core/Manager/Simulation.meta new file mode 100644 index 00000000..217f1e4e --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Manager/Simulation.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 3103c5a568f55db44a99370d1e982fd5 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/MagicaCloth2/Scripts/Core/Manager/Simulation/ColliderManager.cs b/Assets/MagicaCloth2/Scripts/Core/Manager/Simulation/ColliderManager.cs new file mode 100644 index 00000000..be2dc640 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Manager/Simulation/ColliderManager.cs @@ -0,0 +1,1317 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Unity.Collections; +using Unity.Mathematics; +using UnityEngine; + +namespace MagicaCloth2 +{ + /// + /// コライダーの管理 + /// MC1と違いコライダーはパーティクルとは別に管理される + /// コライダーはチームごとに分けて管理される。 + /// 同じコライダーをチームAとチームBが共有していたとしてもそれぞれ別のコライダーとして登録される。 + /// + public class ColliderManager : IManager, IValid + { + /// + /// チームID + /// + public ExNativeArray teamIdArray; + + /// + /// コライダー種類(最大15まで) + /// + public enum ColliderType : byte + { + None = 0, + Sphere = 1, + CapsuleX_Center = 2, + CapsuleY_Center = 3, + CapsuleZ_Center = 4, + CapsuleX_Start = 5, + CapsuleY_Start = 6, + CapsuleZ_Start = 7, + Plane = 8, + Box = 9, + } + + /// + /// シンメトリータイプ(最大15まで) + /// + 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; + + /// + /// トランスフォームからの中心ローカルオフセット位置 + /// + public ExNativeArray centerArray; + + /// + /// コライダーのサイズ情報 + /// Sphere(x:半径) + /// Capsule(x:始点半径, y:終点半径, z:長さ) + /// Box(x:サイズX, y:サイズY, z:サイズZ) + /// + public ExNativeArray sizeArray; + + /// + /// 現フレーム姿勢 + /// トランスフォームからスナップされた姿勢(ワールド) + /// センターオフセットも計算される + /// + public ExNativeArray framePositions; + public ExNativeArray frameRotations; + public ExNativeArray frameScales; + + /// + /// 1つ前のフレーム姿勢(ワールド) + /// + public ExNativeArray oldFramePositions; + public ExNativeArray oldFrameRotations; + + /// + /// 現ステップでの姿勢(ワールド) + /// + public ExNativeArray nowPositions; + public ExNativeArray nowRotations; + + /// + /// 前ステップでの姿勢(ワールド) + /// + public ExNativeArray oldPositions; + public ExNativeArray oldRotations; + + /// + /// シンメトリー用のメインコライダーへのローカルインデックス配列 + /// + public ExNativeArray mainColliderIndices; + + /// + /// 登録コライダーコンポーネント + /// 現在はデバッグ用 + /// + HashSet colliderSet = new HashSet(); + + bool isValid = false; + + //========================================================================================= + /// + /// ステップごとの作業データ + /// + internal struct WorkData + { + public AABB aabb; + public float2 radius; + public float3x2 oldPos; + public float3x2 nextPos; + public quaternion inverseOldRot; + public quaternion rot; + } + + internal ExNativeArray workDataArray; + + //========================================================================================= + public void Dispose() + { + isValid = false; + + teamIdArray?.Dispose(); + flagArray?.Dispose(); + centerArray?.Dispose(); + sizeArray?.Dispose(); + framePositions?.Dispose(); + frameRotations?.Dispose(); + frameScales?.Dispose(); + nowPositions?.Dispose(); + nowRotations?.Dispose(); + oldFramePositions?.Dispose(); + oldFrameRotations?.Dispose(); + oldPositions?.Dispose(); + oldRotations?.Dispose(); + workDataArray?.Dispose(); + mainColliderIndices?.Dispose(); + + teamIdArray = null; + flagArray = null; + sizeArray = null; + framePositions = null; + frameRotations = null; + frameScales = null; + nowPositions = null; + nowRotations = null; + oldFramePositions = null; + oldFrameRotations = null; + oldPositions = null; + oldRotations = null; + workDataArray = null; + mainColliderIndices = null; + + colliderSet.Clear(); + } + + public void EnterdEditMode() + { + Dispose(); + } + + public void Initialize() + { + Dispose(); + + const int capacity = 256; + teamIdArray = new ExNativeArray(capacity); + flagArray = new ExNativeArray(capacity); + centerArray = new ExNativeArray(capacity); + sizeArray = new ExNativeArray(capacity); + framePositions = new ExNativeArray(capacity); + frameRotations = new ExNativeArray(capacity); + frameScales = new ExNativeArray(capacity); + nowPositions = new ExNativeArray(capacity); + nowRotations = new ExNativeArray(capacity); + oldFramePositions = new ExNativeArray(capacity); + oldFrameRotations = new ExNativeArray(capacity); + oldPositions = new ExNativeArray(capacity); + oldRotations = new ExNativeArray(capacity); + workDataArray = new ExNativeArray(capacity); + mainColliderIndices = new ExNativeArray(capacity); + + isValid = true; + } + + public bool IsValid() + { + return isValid; + } + + //========================================================================================= + /// + /// チームにコライダー領域を登録する + /// 最初から最大コライダー数で領域を初期化しておく + /// + /// + public void Register(ClothProcess cprocess) + { + if (isValid == false) + return; + + // コライダー数 + 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(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; + + // 初期コライダー登録 + for (int i = 0; i < clist.Count; i++) + { + var col = clist[i]; + if (col && cprocess.colliderDict.ContainsKey(col) == false) + AddCollider(cprocess, col); + } + } + } + + /// + /// チームからコライダー領域を解除する + /// + /// + public void Exit(ClothProcess cprocess) + { + if (isValid == false) + return; + + int teamId = cprocess.TeamId; + + // コライダー解除 + foreach (var col in cprocess.colliderDict.Keys) + { + if (col) + { + if (col.Exit(teamId)) + { + // 利用者0 + colliderSet.Remove(col); + } + } + } + cprocess.colliderDict.Clear(); + + ref var tdata = ref MagicaManager.Team.GetTeamDataRef(teamId); + + var c = tdata.colliderChunk; + teamIdArray.RemoveAndFill(c); // 0クリア + flagArray.RemoveAndFill(c); // 0クリア + centerArray.Remove(c); + sizeArray.Remove(c); + framePositions.Remove(c); + frameRotations.Remove(c); + frameScales.Remove(c); + nowPositions.Remove(c); + nowRotations.Remove(c); + oldFramePositions.Remove(c); + oldFrameRotations.Remove(c); + oldPositions.Remove(c); + oldRotations.Remove(c); + workDataArray.Remove(c); + mainColliderIndices.Remove(c); + + tdata.colliderChunk.Clear(); + tdata.colliderCount = 0; + + // コライダートランスフォーム解除 + MagicaManager.Bone.RemoveTransform(tdata.colliderTransformChunk); + tdata.colliderTransformChunk.Clear(); + } + + //========================================================================================= + /// + /// コライダーのリスト内容を更新する + /// これはMagicaClothコンポーネント側のコライダーリストが変更された場合 + /// つまりパラメータの変更ではない + /// + /// + internal void UpdateColliders(ClothProcess cprocess) + { + if (isValid == false) + return; + + // ここではコライダーリストへのコンポーネント追加削除だけで、シンメトリーなどの切り替えは考慮しなくていい + var clist = cprocess.cloth.SerializeData.colliderCollisionConstraint.colliderList; + + // 現在の登録コライダーと比較し不要なコライダーを削除する + var keys = cprocess.colliderDict.Keys.ToList(); + foreach (ColliderComponent col in keys) + { + if (col && clist.Contains(col) == false) + { + // コライダー削除 + RemoveCollider(col, cprocess.TeamId); + } + } + + // 現在の登録コライダーと比較し必要なコライダーを追加する + foreach (var col in clist) + { + if (col && cprocess.colliderDict.ContainsKey(col) == false) + { + AddCollider(cprocess, col); + } + } + } + + /// + /// コライダーの個別登録 + /// + /// + /// + void AddCollider(ClothProcess cprocess, ColliderComponent col) + { + if (isValid == false) + return; + if (col == null) + return; + 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) + { + // 新規確保 + int newCount = Define.System.ExpandedColliderCount; + tdata.colliderChunk = teamIdArray.AddRange(newCount, (short)cprocess.TeamId); + flagArray.AddRange(newCount, default); + centerArray.AddRange(newCount); + sizeArray.AddRange(newCount); + framePositions.AddRange(newCount); + frameRotations.AddRange(newCount); + frameScales.AddRange(newCount); + nowPositions.AddRange(newCount); + nowRotations.AddRange(newCount); + oldFramePositions.AddRange(newCount); + oldFrameRotations.AddRange(newCount); + oldPositions.AddRange(newCount); + oldRotations.AddRange(newCount); + workDataArray.AddRange(newCount); + mainColliderIndices.AddRange(newCount); + Transform t = cprocess.cloth.ClothTransform; + tdata.colliderTransformChunk = MagicaManager.Bone.AddTransform(newCount, cprocess.TeamId, t); // 領域のみ + tdata.colliderCount = 0; + } + else if (tdata.UseColliderCount == tdata.colliderChunk.dataLength) + { + // コライダー配列のキャパシティ上限なら拡張する + // 拡張 + int newCount = tdata.colliderChunk.dataLength + Define.System.ExpandedColliderCount; + var oldColliderChunk = tdata.colliderChunk; + tdata.colliderChunk = teamIdArray.Expand(oldColliderChunk, newCount); + flagArray.ExpandAndFill(oldColliderChunk, newCount); // 旧領域のフラグはクリアする必要あり + centerArray.Expand(oldColliderChunk, newCount); + sizeArray.Expand(oldColliderChunk, newCount); + framePositions.Expand(oldColliderChunk, newCount); + frameRotations.Expand(oldColliderChunk, newCount); + frameScales.Expand(oldColliderChunk, newCount); + nowPositions.Expand(oldColliderChunk, newCount); + nowRotations.Expand(oldColliderChunk, newCount); + oldFramePositions.Expand(oldColliderChunk, newCount); + oldFrameRotations.Expand(oldColliderChunk, newCount); + 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); + } + + // 追加インデックス + 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) + /// + /// + /// + internal void RemoveCollider(ColliderComponent col, int teamId) + { + 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) + return; + var cprocess = MagicaManager.Team.GetClothProcess(teamId); + if (cprocess == null) + return; + 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 + localIndex; + int transformIndex = tdata.colliderTransformChunk.startIndex + localIndex; + + int swapLocalIndex = ccnt - 1; + int swapArrayIndex = tdata.colliderChunk.startIndex + swapLocalIndex; + int swapTransformIndex = tdata.colliderTransformChunk.startIndex + swapLocalIndex; + + if (arrayIndex < swapArrayIndex) + { + // remove swap back + flagArray[arrayIndex] = flagArray[swapArrayIndex]; + teamIdArray[arrayIndex] = teamIdArray[swapArrayIndex]; + centerArray[arrayIndex] = centerArray[swapArrayIndex]; + sizeArray[arrayIndex] = sizeArray[swapArrayIndex]; + framePositions[arrayIndex] = framePositions[swapArrayIndex]; + frameRotations[arrayIndex] = frameRotations[swapArrayIndex]; + frameScales[arrayIndex] = frameScales[swapArrayIndex]; + nowPositions[arrayIndex] = nowPositions[swapArrayIndex]; + nowRotations[arrayIndex] = nowRotations[swapArrayIndex]; + oldFramePositions[arrayIndex] = oldFramePositions[swapArrayIndex]; + oldFrameRotations[arrayIndex] = oldFrameRotations[swapArrayIndex]; + oldPositions[arrayIndex] = oldPositions[swapArrayIndex]; + oldRotations[arrayIndex] = oldRotations[swapArrayIndex]; + mainColliderIndices[arrayIndex] = mainColliderIndices[swapArrayIndex]; + + flagArray[swapArrayIndex] = default; + teamIdArray[swapArrayIndex] = 0; + + // transform + MagicaManager.Bone.CopyTransform(swapTransformIndex, transformIndex); + MagicaManager.Bone.SetTransform(null, default, swapTransformIndex, 0); + + // cprocess + 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 + { + // remove + flagArray[arrayIndex] = default; + teamIdArray[arrayIndex] = 0; + + // transform + MagicaManager.Bone.SetTransform(null, default, transformIndex, 0); + } + 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--; + } + + /// + /// 有効状態の変更 + /// + /// + /// + /// + internal void EnableCollider(ColliderComponent col, int teamId, bool sw) + { + if (IsValid() == false) + return; + ref var tdata = ref MagicaManager.Team.GetTeamDataRef(teamId); + if (tdata.IsValid == false) + return; + var cprocess = MagicaManager.Team.GetClothProcess(teamId); + + 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); + } + } + + /// + /// チーム有効状態変更に伴うコライダー状態の変更 + /// + /// + /// + internal void EnableTeamCollider(int teamId) + { + if (IsValid() == false) + return; + ref var tdata = ref MagicaManager.Team.GetTeamDataRef(teamId); + if (tdata.IsValid == false) + return; + if (tdata.UseColliderCount == 0) + return; + + bool teamEnable = tdata.IsEnable; + var c = tdata.colliderTransformChunk; + for (int i = 0; i < c.dataLength; i++) + { + int arrayIndex = tdata.colliderChunk.startIndex + i; + int transformIndex = c.startIndex + i; + + // フラグ + var flag = flagArray[arrayIndex]; + //flag.SetFlag(Flag_Enable, sw); // コライダーのEnableフラグはコライダー固有のものなので変更する必要はない + flag.SetFlag(Flag_Reset, true); // Enable/Disableどちらでもリセット + flagArray[arrayIndex] = flag; + + // 有効状態 + bool t_enable = teamEnable && flag.IsSet(Flag_Enable); + MagicaManager.Bone.EnableTransform(transformIndex, t_enable); + } + } + + /// + /// コライダーコンポーネントのパラメータ変更を反映する + /// シンメトリーの変更なども反映させる + /// + /// + /// + internal void UpdateParameters(ColliderComponent col, int teamId, bool changeSymmetry) + { + if (IsValid() == false) + return; + + ref var tdata = ref MagicaManager.Team.GetTeamDataRef(teamId); + if (tdata.IsValid == false) + return; + var cprocess = MagicaManager.Team.GetClothProcess(teamId); + if (cprocess.colliderDict.ContainsKey(col) == false) + return; + 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 static void SimulationPreUpdate( + DataChunk chunk, + // team + ref TeamManager.TeamData tdata, + ref InertiaConstraint.CenterData cdata, + // collider + 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) + continue; + + var center = centerArray[index]; + int l_index = index - tdata.colliderChunk.startIndex; + int t_index = tdata.colliderTransformChunk.startIndex + l_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); + + // コライダー姿勢(ワールド) + 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; + frameRotations[index] = wrot; + frameScales[index] = wscl; + + // リセット処理 + if (tdata.IsReset || flag.IsSet(Flag_Reset) || isZeroScale) + { + oldFramePositions[index] = wpos; + oldFrameRotations[index] = wrot; + nowPositions[index] = wpos; + nowRotations[index] = wrot; + oldPositions[index] = wpos; + oldRotations[index] = wrot; + + flag.SetFlag(Flag_Reset, false); + } + else if (tdata.IsInertiaShift || tdata.IsNegativeScaleTeleport) + { + // 慣性全体シフト + var oldFramePosition = oldFramePositions[index]; + var oldFrameRotation = oldFrameRotations[index]; + var nowPosition = nowPositions[index]; + var nowRotation = nowRotations[index]; + var oldPosition = oldPositions[index]; + var oldRotation = oldRotations[index]; + + // マイナススケール + if (tdata.IsNegativeScaleTeleport) + { + // 本体のスケール反転に合わせてシミュレーションに影響が出ないように必要な座標系を同様に軸反転させる + // コライダーはセンター空間で反転させる + // 回転に関してはパーティクルとは異なり法線接線をスケール方向により反転させて組み直す + + // センター空間軸反転用マトリックス + 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 static void SimulationStartStep( + // team + ref TeamManager.TeamData tdata, + ref InertiaConstraint.CenterData cdata, + // collider + 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++) + { + var flag = flagArray[cindex]; + 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); + quaternion rot = math.slerp(oldFrameRotations[cindex], frameRotations[cindex], tdata.frameInterpolation); + rot = math.normalize(rot); // 必要 + nowPositions[cindex] = pos; + nowRotations[cindex] = rot; + //Debug.Log($"cpos:{pos}, coldpos:{oldPos}"); + + // コライダー慣性シフト + // old姿勢をシフトさせる + var oldpos = oldPositions[cindex]; + var oldrot = oldRotations[cindex]; + + // ローカル慣性シフト + oldpos = math.lerp(oldpos, pos, cdata.stepMoveInertiaRatio); + oldrot = math.slerp(oldrot, rot, cdata.stepRotationInertiaRatio); + oldPositions[cindex] = oldpos; + oldRotations[cindex] = math.normalize(oldrot); + + // ステップ作業データの構築 + var type = DataUtility.GetColliderType(flag); + var work = new WorkData(); + var csize = sizeArray[cindex]; + var cscl = frameScales[cindex]; + work.inverseOldRot = math.inverse(oldrot); + work.rot = rot; + if (type == ColliderType.Sphere) + { + // radius + float radius = csize.x * math.abs(cscl.x); // X軸のみを見る + work.radius = radius; + + // aabb + var aabb = new AABB(math.min(oldpos, pos), math.max(oldpos, pos)); + aabb.Expand(radius); + work.aabb = aabb; + + // oldpos + work.oldPos.c0 = oldpos; + + // nextpos + work.nextPos.c0 = pos; + } + else if (type >= ColliderType.CapsuleX_Center && type <= ColliderType.CapsuleZ_Start) + { + // 中央揃え + bool alignedCenter = type >= ColliderType.CapsuleX_Center && type <= ColliderType.CapsuleZ_Center; + + // 方向性 + float3 dir = (type == ColliderType.CapsuleX_Center || type == ColliderType.CapsuleX_Start) ? math.right() + : (type == ColliderType.CapsuleY_Center || type == ColliderType.CapsuleY_Start) ? math.up() + : math.forward(); + + // スケール + //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 = 終点半径 + // z = 長さ + csize *= scl; + + float sr = csize.x; + float er = csize.y; + 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); + elen = math.max(elen - er, 0.0f); + + // 移動前カプセル始点と終点 + float3 soldpos = oldpos + math.mul(oldrot, dir * slen); + float3 eoldpos = oldpos - math.mul(oldrot, dir * elen); + + // 移動後カプセル始点と終点 + float3 spos = pos + math.mul(rot, dir * slen); + float3 epos = pos - math.mul(rot, dir * elen); + + // AABB + var aabbC = new AABB(math.min(soldpos, spos) - sr, math.max(soldpos, spos) + sr); + var aabbC1 = new AABB(math.min(eoldpos, epos) - er, math.max(eoldpos, epos) + er); + aabbC.Encapsulate(aabbC1); + + // 格納 + work.aabb = aabbC; + work.radius = new float2(sr, er); + work.oldPos = new float3x2(soldpos, eoldpos); + work.nextPos = new float3x2(spos, epos); + } + else if (type == ColliderType.Plane) + { + // 押し出し法線方向をoldposに格納する + // マイナススケール + 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; + } + + workDataArray[cindex] = work; + } + } + + /// + /// シミュレーションステップ後処理 + /// old姿勢の格納 + /// + internal static void SimulationEndStep( + DataChunk chunk, + // team + ref TeamManager.TeamData tdata, + // collider + 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++) + { + oldPositions[cindex] = nowPositions[cindex]; + oldRotations[cindex] = nowRotations[cindex]; + } + } + + /// + /// シミュレーション更新後処理 + /// + internal static void SimulationPostUpdate( + // team + ref TeamManager.TeamData tdata, + // collider + ref NativeArray framePositions, + ref NativeArray frameRotations, + ref NativeArray oldFramePositions, + ref NativeArray oldFrameRotations + ) + { + if (tdata.colliderCount == 0) + return; + if (tdata.IsRunning == false) + return; + + int cindex = tdata.colliderChunk.startIndex; + for (int k = 0; k < tdata.colliderChunk.dataLength; k++, cindex++) + { + // コライダー履歴更新 + oldFramePositions[cindex] = framePositions[cindex]; + oldFrameRotations[cindex] = frameRotations[cindex]; + + } + } + + //========================================================================================= + public void InformationLog(StringBuilder allsb) + { + StringBuilder sb = new StringBuilder(); + sb.AppendLine($"========== Collider Manager =========="); + if (IsValid() == false) + { + sb.AppendLine($"Collider Manager. Invalid."); + } + else + { + int cnt = teamIdArray?.Count ?? 0; + + sb.AppendLine($"Use:{cnt}"); + sb.AppendLine($" -flagArray:{flagArray.ToSummary()}"); + sb.AppendLine($" -centerArray:{centerArray.ToSummary()}"); + sb.AppendLine($" -sizeArray:{sizeArray.ToSummary()}"); + sb.AppendLine($" -framePositions:{framePositions.ToSummary()}"); + sb.AppendLine($" -frameRotations:{frameRotations.ToSummary()}"); + sb.AppendLine($" -frameScales:{frameScales.ToSummary()}"); + sb.AppendLine($" -oldFramePositions:{oldFramePositions.ToSummary()}"); + sb.AppendLine($" -oldFrameRotations:{oldFrameRotations.ToSummary()}"); + sb.AppendLine($" -nowPositions:{nowPositions.ToSummary()}"); + sb.AppendLine($" -nowRotations:{nowRotations.ToSummary()}"); + sb.AppendLine($" -oldPositions:{oldPositions.ToSummary()}"); + sb.AppendLine($" -oldRotations:{oldRotations.ToSummary()}"); + sb.AppendLine($" -mainColliderIndices:{mainColliderIndices.ToSummary()}"); + + sb.AppendLine($"[Colliders]"); + 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); + 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 Components:{colliderSet.Count}]"); + foreach (var col in colliderSet) + { + 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(); + Debug.Log(sb.ToString()); + allsb.Append(sb); + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/Manager/Simulation/ColliderManager.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Manager/Simulation/ColliderManager.cs.meta new file mode 100644 index 00000000..a4a6a952 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Manager/Simulation/ColliderManager.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 423ad2b7aa4749f4b88eac13b3b21d54 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Manager/Simulation/ColliderManager.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Manager/Simulation/SimulationManager.cs b/Assets/MagicaCloth2/Scripts/Core/Manager/Simulation/SimulationManager.cs new file mode 100644 index 00000000..e8fee479 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Manager/Simulation/SimulationManager.cs @@ -0,0 +1,1476 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using System.Text; +using Unity.Collections; +using Unity.Jobs; +using Unity.Mathematics; +using UnityEngine; + +namespace MagicaCloth2 +{ + public partial class SimulationManager : IManager, IValid + { + /// + /// チームID + /// + public ExNativeArray teamIdArray; + + /// + /// 現在のシミュレーション座標 + /// + public ExNativeArray nextPosArray; + + /// + /// 1つ前のシミュレーション座標 + /// + public ExNativeArray oldPosArray; + + /// + /// 1つ前のシミュレーション回転(todo:現在未使用) + /// + public ExNativeArray oldRotArray; + + /// + /// 現在のアニメーション姿勢座標 + /// カスタムスキニングの結果も反映されている + /// + public ExNativeArray basePosArray; + + /// + /// 現在のアニメーション姿勢回転 + /// カスタムスキニングの結果も反映されている + /// + public ExNativeArray baseRotArray; + + /// + /// 1つ前の原点座標 + /// + public ExNativeArray oldPositionArray; + + /// + /// 1つ前の原点回転 + /// + public ExNativeArray oldRotationArray; + + /// + /// 速度計算用座標 + /// + public ExNativeArray velocityPosArray; + + /// + /// 表示座標 + /// + public ExNativeArray dispPosArray; + + /// + /// 速度 + /// + public ExNativeArray velocityArray; + + /// + /// 実速度 + /// + public ExNativeArray realVelocityArray; + + /// + /// 摩擦(0.0 ~ 1.0) + /// + public ExNativeArray frictionArray; + + /// + /// 静止摩擦係数 + /// + public ExNativeArray staticFrictionArray; + + /// + /// 接触コライダーの衝突法線 + /// + public ExNativeArray collisionNormalArray; + + public int ParticleCount => nextPosArray?.Count ?? 0; + + //========================================================================================= + /// + /// 制約 + /// + public DistanceConstraint distanceConstraint; + public TriangleBendingConstraint bendingConstraint; + public TetherConstraint tetherConstraint; + public AngleConstraint angleConstraint; + public InertiaConstraint inertiaConstraint; + public ColliderCollisionConstraint colliderCollisionConstraint; + public MotionConstraint motionConstraint; + public SelfCollisionConstraint selfCollisionConstraint; + + //========================================================================================= + /// + /// ステップごとのシミュレーションの基準となる姿勢座標 + /// 初期姿勢とアニメーション姿勢をAnimatinBlendRatioで補間したもの + /// + public NativeArray stepBasicPositionBuffer; + + /// + /// ステップごとのシミュレーションの基準となる姿勢回転 + /// 初期姿勢とアニメーション姿勢をAnimatinBlendRatioで補間したもの + /// + public NativeArray stepBasicRotationBuffer; + + /// + /// 作業用バッファ + /// + internal NativeArray tempVectorBufferA; + internal NativeArray tempVectorBufferB; + internal NativeArray tempCountBuffer; + internal NativeArray tempFloatBufferA; + internal NativeArray tempRotationBufferA; + internal NativeArray tempRotationBufferB; + + /// + /// ステップ実行カウンター + /// + internal int SimulationStepCount { get; private set; } + + /// + /// 実行環境で利用できるワーカースレッド数 + /// + internal int WorkerCount => Unity.Jobs.LowLevel.Unsafe.JobsUtility.JobWorkerCount; + + /// + /// 分割ジョブを適用するプロキシメッシュの頂点数 + /// + internal int splitProxyMeshVertexCount = Define.System.SplitProxyMeshVertexCount; + + bool isValid = false; + + //========================================================================================= + public void Dispose() + { + isValid = false; + + teamIdArray?.Dispose(); + nextPosArray?.Dispose(); + oldPosArray?.Dispose(); + oldRotArray?.Dispose(); + basePosArray?.Dispose(); + baseRotArray?.Dispose(); + oldPositionArray?.Dispose(); + oldRotationArray?.Dispose(); + velocityPosArray?.Dispose(); + dispPosArray?.Dispose(); + velocityArray?.Dispose(); + realVelocityArray?.Dispose(); + frictionArray?.Dispose(); + staticFrictionArray?.Dispose(); + collisionNormalArray?.Dispose(); + + teamIdArray = null; + nextPosArray = null; + oldPosArray = null; + oldRotArray = null; + basePosArray = null; + baseRotArray = null; + oldPositionArray = null; + oldRotationArray = null; + velocityPosArray = null; + dispPosArray = null; + velocityArray = null; + realVelocityArray = null; + frictionArray = null; + staticFrictionArray = null; + collisionNormalArray = null; + + 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(); + tetherConstraint?.Dispose(); + angleConstraint?.Dispose(); + inertiaConstraint?.Dispose(); + colliderCollisionConstraint?.Dispose(); + motionConstraint?.Dispose(); + selfCollisionConstraint?.Dispose(); + distanceConstraint = null; + bendingConstraint = null; + tetherConstraint = null; + angleConstraint = null; + inertiaConstraint = null; + colliderCollisionConstraint = null; + motionConstraint = null; + selfCollisionConstraint = null; + } + + public void EnterdEditMode() + { + Dispose(); + } + + public void Initialize() + { + Dispose(); + + const int capacity = 0; // 1024? + teamIdArray = new ExNativeArray(capacity); + nextPosArray = new ExNativeArray(capacity); + oldPosArray = new ExNativeArray(capacity); + oldRotArray = new ExNativeArray(capacity); + basePosArray = new ExNativeArray(capacity); + baseRotArray = new ExNativeArray(capacity); + oldPositionArray = new ExNativeArray(capacity); + oldRotationArray = new ExNativeArray(capacity); + velocityPosArray = new ExNativeArray(capacity); + dispPosArray = new ExNativeArray(capacity); + velocityArray = new ExNativeArray(capacity); + realVelocityArray = new ExNativeArray(capacity); + frictionArray = new ExNativeArray(capacity); + staticFrictionArray = new ExNativeArray(capacity); + collisionNormalArray = new ExNativeArray(capacity); + + // 制約 + distanceConstraint = new DistanceConstraint(); + bendingConstraint = new TriangleBendingConstraint(); + tetherConstraint = new TetherConstraint(); + angleConstraint = new AngleConstraint(); + inertiaConstraint = new InertiaConstraint(); + colliderCollisionConstraint = new ColliderCollisionConstraint(); + motionConstraint = new MotionConstraint(); + selfCollisionConstraint = new SelfCollisionConstraint(); + + SimulationStepCount = 0; + + isValid = true; + + Develop.DebugLog($"JobWorkerCount:{Unity.Jobs.LowLevel.Unsafe.JobsUtility.JobWorkerCount}"); + //Develop.DebugLog($"MaxJobThreadCount:{Unity.Jobs.LowLevel.Unsafe.JobsUtility.MaxJobThreadCount}"); + } + + public bool IsValid() + { + return isValid; + } + + //========================================================================================= + /// + /// プロキシメッシュをマネージャに登録する + /// + internal void RegisterProxyMesh(ClothProcess cprocess) + { + if (isValid == false) + return; + + int teamId = cprocess.TeamId; + var proxyMesh = cprocess.ProxyMeshContainer.shareVirtualMesh; + ref var tdata = ref MagicaManager.Team.GetTeamDataRef(teamId); + + int pcnt = proxyMesh.VertexCount; + tdata.particleChunk = teamIdArray.AddRange(pcnt, (short)teamId); + nextPosArray.AddRange(pcnt); + oldPosArray.AddRange(pcnt); + oldRotArray.AddRange(pcnt); + basePosArray.AddRange(pcnt); + baseRotArray.AddRange(pcnt); + oldPositionArray.AddRange(pcnt); + oldRotationArray.AddRange(pcnt); + velocityPosArray.AddRange(pcnt); + dispPosArray.AddRange(pcnt); + velocityArray.AddRange(pcnt); + realVelocityArray.AddRange(pcnt); + frictionArray.AddRange(pcnt); + staticFrictionArray.AddRange(pcnt); + collisionNormalArray.AddRange(pcnt); + } + + /// + /// 制約データを登録する + /// + /// + internal void RegisterConstraint(ClothProcess cprocess) + { + if (isValid == false) + return; + + int teamId = cprocess.TeamId; + + // 慣性制約データをコピー(すでに領域は確保済みなのでコピーする) + MagicaManager.Team.centerDataArray[teamId] = cprocess.inertiaConstraintData.centerData; + + // 制約データを登録する + distanceConstraint.Register(cprocess); + bendingConstraint.Register(cprocess); + inertiaConstraint.Register(cprocess); + selfCollisionConstraint.Register(cprocess); + } + + + /// + /// プロキシメッシュをマネージャから解除する + /// + internal void ExitProxyMesh(ClothProcess cprocess) + { + if (isValid == false) + return; + + int teamId = cprocess.TeamId; + ref var tdata = ref MagicaManager.Team.GetTeamDataRef(teamId); + tdata.flag.SetBits(TeamManager.Flag_Exit, true); // 消滅フラグ + + var c = tdata.particleChunk; + teamIdArray.RemoveAndFill(c); + nextPosArray.Remove(c); + oldPosArray.Remove(c); + oldRotArray.Remove(c); + basePosArray.Remove(c); + baseRotArray.Remove(c); + oldPositionArray.Remove(c); + oldRotationArray.Remove(c); + velocityPosArray.Remove(c); + dispPosArray.Remove(c); + velocityArray.Remove(c); + realVelocityArray.Remove(c); + frictionArray.Remove(c); + staticFrictionArray.Remove(c); + collisionNormalArray.Remove(c); + + tdata.particleChunk.Clear(); + + // 制約データを解除する + distanceConstraint.Exit(cprocess); + bendingConstraint.Exit(cprocess); + inertiaConstraint.Exit(cprocess); + selfCollisionConstraint.Exit(cprocess); + } + + //========================================================================================= + /// + /// 作業バッファの更新 + /// + internal void WorkBufferUpdate() + { + int pcnt = ParticleCount; + + // 汎用作業バッファ + // 拡張時には0クリアされる + stepBasicPositionBuffer.MC2Resize(pcnt); + stepBasicRotationBuffer.MC2Resize(pcnt); + + // 汎用バッファ + // 拡張時には0クリアされる + tempVectorBufferA.MC2Resize(pcnt); + tempVectorBufferB.MC2Resize(pcnt); + tempCountBuffer.MC2Resize(pcnt); + tempFloatBufferA.MC2Resize(pcnt); + tempRotationBufferA.MC2Resize(pcnt); + tempRotationBufferB.MC2Resize(pcnt); + + // 制約 + selfCollisionConstraint.WorkBufferUpdate(); + } + + //========================================================================================= + // Simulation + //========================================================================================= + /// + /// シミュレーションメインスケジュール + /// + /// + /// + internal JobHandle ClothSimulationSchedule(JobHandle jobHandle) + { + var tm = MagicaManager.Team; + var bm = MagicaManager.Bone; + var vm = MagicaManager.VMesh; + var wm = MagicaManager.Wind; + var cm = MagicaManager.Collider; + var tim = MagicaManager.Time; + + int normalClothTeamCount = tm.batchNormalClothTeamList.Length; + int splitClothTeamCount = tm.batchSplitClothTeamList.Length; + bool useNormalClothJob = normalClothTeamCount > 0; + bool useSplitClothJob = splitClothTeamCount > 0; + + if (useNormalClothJob == false && useSplitClothJob == false) + return jobHandle; + + // 最大更新回数 + 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) + { + // コンタクトキューとリスト + selfCollisionConstraint.contactQueue.Clear(); + selfCollisionConstraint.contactList.Clear(); + selfCollisionConstraint.intersectQueue.Clear(); + selfCollisionConstraint.intersectList.Clear(); + + // 分割ジョブ内での各種コリジョンの有無 + bool useEdgeCollision = tm.teamStatus.Value.z > 0; + bool useSelfCollision = tm.teamStatus.Value.w > 0; + + // セルフコリジョンのインターセクト解決 + bool useIntersect = selfCollisionConstraint.IntersectCount > 0; + + // プロキシメッシュをスキニングし基本姿勢を求める + var splitPre_A_Job = new SplitPre_A_Job() + { + workerCount = workerCount, + + // team + batchSelfTeamList = tm.batchSplitClothTeamList, + teamDataArray = tm.teamDataArray.GetNativeArray(), + + // 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() + { + 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() + { + 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); + + // インターセクトバッファをリストに変換 + var selfConvertIntersectList_job = new SelfCollisionConstraint.SelfConvertIntersectListJob() + { + intersectQueue = selfCollisionConstraint.intersectQueue, + intersectList = selfCollisionConstraint.intersectList, + }; + selfIntersectJobHandle = selfConvertIntersectList_job.Schedule(selfIntersectJobHandle); + useIntersectJob = true; + } + + // ■ステップループ + for (int updateIndex = 0; updateIndex < maxUpdateCount; updateIndex++) + { + bool isFirstStep = updateIndex == 0; + + // チーム更新 + // コライダーの更新 + var splitStep_A_job = new SplitStep_A_Job() + { + 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); + + // 速度更新、外力の影響、慣性シフト + var splitStep_B_job = new SplitStep_B_Job() + { + 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, + // temp + tempVectorBufferA = tempVectorBufferA, + tempVectorBufferB = tempVectorBufferB, + tempCountBuffer = tempCountBuffer, + tempFloatBufferA = tempFloatBufferA, + }; + splitClothJobHandle = splitStep_B_job.Schedule(splitClothTeamCount * workerCount, 1, splitClothJobHandle); + + // ベースラインの基準姿勢を計算 + var splitStep_C_job = new SplitStep_C_Job() + { + 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() + { + 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() + { + 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); + + // トライアングルベンド + var splitStep_Triangle_job = new SplitStep_Triangle_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(), + 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); + + // トライアングルベンド集計 + // コライダーコリジョンPoint + var splitStep_E_job = new SplitStep_E_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(), + 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); + + // コライダーコリジョンEdge + if (useEdgeCollision) + { + var splitStep_Edge_job = new SplitStep_Edge_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(), + 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); + } + + // セルフコリジョン + if (isFirstStep) + { + // ■初回ステップ + // (チームごと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); + + // (チームごと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); + + // コンタクトバッファの生成(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); + + // コンタクトバッファをリストに変換 + // ここは並列化できない + var selfStep_ConvertContactList_job = new SelfCollisionConstraint.SelfStep_ConvertContactListJob() + { + contactQueue = selfCollisionConstraint.contactQueue, + contactList = selfCollisionConstraint.contactList, + }; + splitClothJobHandle = selfStep_ConvertContactList_job.Schedule(splitClothJobHandle); + } + else + { + // ■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); + } + + // セルフコリジョン + // コンタクトバッファ解決(反復) + 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 + { + // ■セルフコリジョンなし + // コライダーコリジョンEdge集計 + // 距離 + // モーション + // 座標確定 + // コライダーの後更新 + var splitStep_FG_NoSelf_job = new SplitStep_FG_NoSelf_Job() + { + 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); + } + } + + // シミュレーション後処理 + // 表示位置の計算 + var splitPost_DisplayPos_job = new SplitPost_DisplayPos_Job() + { + workerCount = workerCount, + simulationDeltaTime = MagicaManager.Time.SimulationDeltaTime, + + // 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(), + + // temp + tempVectorBufferA = tempVectorBufferA, + tempRotationBufferA = tempRotationBufferA, + }; + 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(), + + // temp + tempVectorBufferA = tempVectorBufferA, + tempRotationBufferB = tempRotationBufferB, + }; + 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); + } + } + + // ■一括シミュレーションジョブ + // セルフコリジョンなし、かつプロキシメッシュの頂点数が一定値未満のジョブ + // 1つの巨大なジョブ内ですべてを完結させる + if (useNormalClothJob) + { + var normalJob = new SimulationNormalJob() + { + batchNormalTeamList = tm.batchNormalClothTeamList, + simulationPower = tim.SimulationPower, + simulationDeltaTime = tim.SimulationDeltaTime, + mappingCount = tm.MappingCount, + + // team + 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(), + 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; + } + + //========================================================================================= + public void InformationLog(StringBuilder allsb) + { + StringBuilder sb = new StringBuilder(); + sb.AppendLine($"========== Simulation Manager =========="); + if (IsValid() == false) + { + sb.AppendLine($"Simulation Manager. Invalid"); + } + else + { + sb.AppendLine($"Simulation Manager. Particle:{ParticleCount}"); + sb.AppendLine($" -teamIdArray:{teamIdArray.ToSummary()}"); + sb.AppendLine($" -nextPosArray:{nextPosArray.ToSummary()}"); + sb.AppendLine($" -oldPosArray:{oldPosArray.ToSummary()}"); + sb.AppendLine($" -oldRotArray:{oldRotArray.ToSummary()}"); + sb.AppendLine($" -basePosArray:{basePosArray.ToSummary()}"); + sb.AppendLine($" -baseRotArray:{baseRotArray.ToSummary()}"); + sb.AppendLine($" -oldPositionArray:{oldPositionArray.ToSummary()}"); + sb.AppendLine($" -oldRotationArray:{oldRotationArray.ToSummary()}"); + sb.AppendLine($" -velocityPosArray:{velocityPosArray.ToSummary()}"); + sb.AppendLine($" -dispPosArray:{dispPosArray.ToSummary()}"); + sb.AppendLine($" -velocityArray:{velocityArray.ToSummary()}"); + sb.AppendLine($" -realVelocityArray:{realVelocityArray.ToSummary()}"); + sb.AppendLine($" -frictionArray:{frictionArray.ToSummary()}"); + sb.AppendLine($" -staticFrictionArray:{staticFrictionArray.ToSummary()}"); + sb.AppendLine($" -collisionNormalArray:{collisionNormalArray.ToSummary()}"); + + // 制約 + sb.Append(distanceConstraint.ToString()); + sb.Append(bendingConstraint.ToString()); + sb.Append(angleConstraint.ToString()); + sb.Append(inertiaConstraint.ToString()); + sb.Append(colliderCollisionConstraint.ToString()); + sb.Append(selfCollisionConstraint.ToString()); + + // 汎用バッファ + sb.AppendLine($"[Buffer]"); + 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(); + } + sb.AppendLine(); + Debug.Log(sb.ToString()); + allsb.Append(sb); + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/Manager/Simulation/SimulationManager.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Manager/Simulation/SimulationManager.cs.meta new file mode 100644 index 00000000..155c7467 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Manager/Simulation/SimulationManager.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 5b7ca58a6015eba4e83341a9e6f3473e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Manager/Simulation/SimulationManager.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Manager/Simulation/SimulationManagerNormal.cs b/Assets/MagicaCloth2/Scripts/Core/Manager/Simulation/SimulationManagerNormal.cs new file mode 100644 index 00000000..e5a3dd53 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Manager/Simulation/SimulationManagerNormal.cs @@ -0,0 +1,1797 @@ +// 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 transformRotationArray; + [Unity.Collections.ReadOnly] + public NativeArray transformScaleArray; + [Unity.Collections.ReadOnly] + public NativeArray transformLocalToWorldMatrixArray; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray transformLocalPositionArray; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray transformLocalRotationArray; + [Unity.Collections.ReadOnly] + public NativeArray transformLocalScaleArray; + + // vmesh + [Unity.Collections.ReadOnly] + public NativeArray attributes; + [Unity.Collections.ReadOnly] + public NativeArray depthArray; + [Unity.Collections.ReadOnly] + public NativeArray localPositions; + [Unity.Collections.ReadOnly] + public NativeArray localNormals; + [Unity.Collections.ReadOnly] + public NativeArray localTangents; + [Unity.Collections.ReadOnly] + public NativeArray boneWeights; + [Unity.Collections.ReadOnly] + public NativeArray skinBoneTransformIndices; + [Unity.Collections.ReadOnly] + public NativeArray skinBoneBindPoses; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray positions; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray rotations; + [Unity.Collections.ReadOnly] + public NativeArray vertexBindPoseRotations; + [Unity.Collections.ReadOnly] + public NativeArray vertexDepths; + [Unity.Collections.ReadOnly] + public NativeArray vertexRootIndices; + [Unity.Collections.ReadOnly] + public NativeArray vertexParentIndices; + [Unity.Collections.ReadOnly] + public NativeArray baseLineStartDataIndices; + [Unity.Collections.ReadOnly] + public NativeArray baseLineDataCounts; + [Unity.Collections.ReadOnly] + public NativeArray baseLineData; + [Unity.Collections.ReadOnly] + public NativeArray vertexLocalPositions; + [Unity.Collections.ReadOnly] + public NativeArray vertexLocalRotations; + [Unity.Collections.ReadOnly] + public NativeArray vertexChildIndexArray; + [Unity.Collections.ReadOnly] + public NativeArray vertexChildDataArray; + [Unity.Collections.ReadOnly] + public NativeArray baseLineFlags; + [Unity.Collections.ReadOnly] + public NativeArray triangles; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray triangleNormals; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray triangleTangents; + [Unity.Collections.ReadOnly] + public NativeArray uvs; + [Unity.Collections.ReadOnly] + public NativeArray> vertexToTriangles; + [Unity.Collections.ReadOnly] + public NativeArray normalAdjustmentRotations; + [Unity.Collections.ReadOnly] + public NativeArray vertexToTransformRotations; + [Unity.Collections.ReadOnly] + public NativeArray edges; + + // particle + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray nextPosArray; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray oldPosArray; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray oldRotArray; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray basePosArray; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray baseRotArray; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray oldPositionArray; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray oldRotationArray; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray velocityPosArray; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray dispPosArray; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray velocityArray; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray realVelocityArray; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray frictionArray; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray staticFrictionArray; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray collisionNormalArray; + + // collider + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray colliderFlagArray; + [Unity.Collections.ReadOnly] + public NativeArray colliderCenterArray; + [Unity.Collections.ReadOnly] + public NativeArray colliderSizeArray; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray colliderFramePositions; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray colliderFrameRotations; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray colliderFrameScales; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray colliderOldFramePositions; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray colliderOldFrameRotations; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray colliderNowPositions; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray colliderNowRotations; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray colliderOldPositions; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray colliderOldRotations; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray colliderWorkDataArray; + [Unity.Collections.ReadOnly] + public NativeArray colliderMainColliderIndices; + + // inertia + [Unity.Collections.ReadOnly] + public NativeArray fixedArray; + + // distance + [Unity.Collections.ReadOnly] + public NativeArray distanceIndexArray; + [Unity.Collections.ReadOnly] + public NativeArray distanceDataArray; + [Unity.Collections.ReadOnly] + public NativeArray distanceDistanceArray; + + // triangleBending + [Unity.Collections.ReadOnly] + public NativeArray bendingTrianglePairArray; + [Unity.Collections.ReadOnly] + public NativeArray bendingRestAngleOrVolumeArray; + [Unity.Collections.ReadOnly] + public NativeArray bendingSignOrVolumeArray; + + // buffer + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray stepBasicPositionBuffer; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray stepBasicRotationBuffer; + + // buffer2 + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray tempVectorBufferA; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray tempVectorBufferB; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray tempCountBuffer; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray tempFloatBufferA; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray tempRotationBufferA; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray tempRotationBufferB; + + // バッチチームのローカルインデックスごと + public void Execute(int localIndex) + { + //Debug.Log(localIndex); + // チームID + int teamId = batchNormalTeamList[localIndex]; + + // !通常タイプではセルフコリジョンが無いため、相互参照を考えずに該当チームを処理すれば良い + + // 各ベースポインタ + TeamManager.TeamData* teamPt = (TeamManager.TeamData*)teamDataArray.GetUnsafePtr(); + ClothParameters* paramPt = (ClothParameters*)parameterArray.GetUnsafeReadOnlyPtr(); + InertiaConstraint.CenterData* centerPt = (InertiaConstraint.CenterData*)centerDataArray.GetUnsafePtr(); + TeamWindData* windPt = (TeamWindData*)teamWindArray.GetUnsafePtr(); + + ref var tdata = ref *(teamPt + teamId); + ref var cdata = ref *(centerPt + teamId); + ref var param = ref *(paramPt + teamId); + ref var wdata = ref *(windPt + teamId); + + if (tdata.IsProcess == false) + return; + if (tdata.ParticleCount == 0) + return; + + // ■プロキシメッシュをスキニングし基本姿勢を求める + VirtualMeshManager.SimulationPreProxyMeshUpdate( + new DataChunk(0, tdata.proxyCommonChunk.dataLength), + // team + teamId, + ref tdata, + // vmesh + attributes, + localPositions, + localNormals, + localTangents, + boneWeights, + skinBoneTransformIndices, + skinBoneBindPoses, + ref positions, + ref rotations, + // transform + transformLocalToWorldMatrixArray + ); + + // チームのセンター姿勢の決定とテレポート判定および慣性用の移動量計算 + TeamManager.SimulationCalcCenterAndInertiaAndWind( + simulationDeltaTime, + // team + teamId, + ref tdata, + ref cdata, + ref wdata, + ref param, + // vmesh + positions, + rotations, + vertexBindPoseRotations, + // inertia + fixedArray, + // transform + transformPositionArray, + transformRotationArray, + transformScaleArray, + // wind + windZoneCount, + windDataArray + ); + + // パーティクルの全体慣性およびリセットの適用 + SimulationPreTeamUpdate( + new DataChunk(0, tdata.particleChunk.dataLength), + // team + ref tdata, + param, + cdata, + // vmesh + positions, + rotations, + vertexDepths, + // particle + ref nextPosArray, + ref oldPosArray, + ref oldRotArray, + ref basePosArray, + ref baseRotArray, + ref oldPositionArray, + ref oldRotationArray, + ref velocityPosArray, + ref dispPosArray, + ref velocityArray, + ref realVelocityArray, + ref frictionArray, + ref staticFrictionArray, + ref collisionNormalArray + ); + + // ■コライダーのローカル姿勢を求める、および全体慣性とリセットの適用 + if (tdata.colliderCount > 0) + { + ColliderManager.SimulationPreUpdate( + new DataChunk(0, tdata.colliderChunk.dataLength), + // team + ref tdata, + ref cdata, + // collider + ref colliderFlagArray, + ref colliderCenterArray, + ref colliderFramePositions, + ref colliderFrameRotations, + ref colliderFrameScales, + ref colliderOldFramePositions, + ref colliderOldFrameRotations, + ref colliderNowPositions, + ref colliderNowRotations, + ref colliderOldPositions, + ref colliderOldRotations, + ref colliderMainColliderIndices, + // transform + ref transformPositionArray, + ref transformRotationArray, + ref transformScaleArray, + ref transformLocalPositionArray, + ref transformLocalRotationArray, + ref transformLocalScaleArray + ); + } + + // ステップ実行 + for (int updateIndex = 0; updateIndex < tdata.updateCount; updateIndex++) + { + // ステップごとのチーム更新 + TeamManager.SimulationStepTeamUpdate( + updateIndex, + simulationDeltaTime, + // team + teamId, + ref tdata, + ref param, + ref cdata, + ref wdata + ); + + // コライダーの更新 + if (tdata.colliderCount > 0) + { + ColliderManager.SimulationStartStep( + // team + ref tdata, + ref cdata, + // collider + ref colliderFlagArray, + ref colliderSizeArray, + ref colliderFramePositions, + ref colliderFrameRotations, + ref colliderFrameScales, + ref colliderOldFramePositions, + ref colliderOldFrameRotations, + ref colliderNowPositions, + ref colliderNowRotations, + ref colliderOldPositions, + ref colliderOldRotations, + ref colliderWorkDataArray + ); + } + + // 速度更新、外力の影響、慣性シフト + SimulationStepUpdateParticles( + new DataChunk(0, tdata.particleChunk.dataLength), + simulationPower, + simulationDeltaTime, + // team + teamId, + ref tdata, + ref cdata, + ref param, + ref wdata, + // wind + ref windDataArray, + // vmesh + ref attributes, + ref depthArray, + ref positions, + ref rotations, + ref vertexRootIndices, + // particle + ref nextPosArray, + ref oldPosArray, + ref basePosArray, + ref baseRotArray, + ref oldPositionArray, + ref oldRotationArray, + ref velocityPosArray, + ref velocityArray, + ref frictionArray, + // buffer + ref stepBasicPositionBuffer, + ref stepBasicRotationBuffer, + // temp + ref tempVectorBufferA, + ref tempVectorBufferB, + ref tempCountBuffer, + ref tempFloatBufferA + ); + + // 制約解決のためのステップごとの基準姿勢を計算 + // ベースラインごと + // アニメーションポーズ使用の有無 + // 初期姿勢の計算が不要なら抜ける + SimulationStepUpdateBaseLinePose( + new DataChunk(0, tdata.baseLineChunk.dataLength), + // team + ref tdata, + // vmesh + ref attributes, + ref vertexParentIndices, + ref baseLineStartDataIndices, + ref baseLineDataCounts, + ref baseLineData, + ref vertexLocalPositions, + ref vertexLocalRotations, + // particle + ref basePosArray, + ref baseRotArray, + // buffer + ref stepBasicPositionBuffer, + ref stepBasicRotationBuffer + ); + + // 制約の解決 ================================================================ + TetherConstraint.SolverConstraint( + new DataChunk(0, tdata.particleChunk.dataLength), + // team + ref tdata, + ref param, + ref cdata, + // vmesh + ref attributes, + ref depthArray, + ref vertexRootIndices, + // particle + ref nextPosArray, + ref velocityPosArray, + ref frictionArray, + // buffer + ref stepBasicPositionBuffer + ); + + DistanceConstraint.SolverConstraint( + new DataChunk(0, tdata.particleChunk.dataLength), + simulationPower, + // team + ref tdata, + ref param, + // vmesh + ref attributes, + ref depthArray, + // particle + ref nextPosArray, + ref basePosArray, + ref velocityPosArray, + ref frictionArray, + // constraint + ref distanceIndexArray, + ref distanceDataArray, + ref distanceDistanceArray + ); + + AngleConstraint.SolverConstraint( + new DataChunk(0, tdata.baseLineChunk.dataLength), + simulationPower, + // team + ref tdata, + ref param, + // vmesh + ref attributes, + ref depthArray, + ref vertexParentIndices, + ref baseLineStartDataIndices, + ref baseLineDataCounts, + ref baseLineData, + // particle + ref nextPosArray, + ref velocityPosArray, + ref frictionArray, + // buffer + ref stepBasicPositionBuffer, + ref stepBasicRotationBuffer, + // buffer2 + ref tempFloatBufferA, + ref tempVectorBufferA, + ref tempRotationBufferA, + ref tempRotationBufferB, + ref tempVectorBufferB + ); + + // バッファクリア + SimulationClearTempBuffer( + new DataChunk(0, tdata.particleChunk.dataLength), + // team + ref tdata, + // buffer2 + ref tempVectorBufferA, + ref tempVectorBufferB, + ref tempCountBuffer, + ref tempFloatBufferA + ); + + TriangleBendingConstraint.SolverConstraint( + new DataChunk(0, tdata.bendingPairChunk.dataLength), + simulationPower, + // team + ref tdata, + ref param, + // vmesh + ref attributes, + ref depthArray, + // particle + ref nextPosArray, + ref frictionArray, + // constraints + ref bendingTrianglePairArray, + ref bendingRestAngleOrVolumeArray, + ref bendingSignOrVolumeArray, + // buffer2 + ref tempVectorBufferA, + ref tempCountBuffer + ); + + TriangleBendingConstraint.SumConstraint( + new DataChunk(0, tdata.particleChunk.dataLength), + // team + ref tdata, + ref param, + // vmesh + ref attributes, + // particle + ref nextPosArray, + // buffer2 + ref tempVectorBufferA, + ref tempCountBuffer + ); + + // コライダーコリジョン + if (param.colliderCollisionConstraint.mode == ColliderCollisionConstraint.Mode.Point) + { + ColliderCollisionConstraint.SolverPointConstraint( + new DataChunk(0, tdata.particleChunk.dataLength), + // team + ref tdata, + ref param, + // vmesh + ref attributes, + ref depthArray, + // particle + ref nextPosArray, + ref frictionArray, + ref collisionNormalArray, + ref velocityPosArray, + ref basePosArray, + // collider + ref colliderFlagArray, + ref colliderWorkDataArray + ); + } + else if (param.colliderCollisionConstraint.mode == ColliderCollisionConstraint.Mode.Edge) + { + ColliderCollisionConstraint.SolverEdgeConstraint( + new DataChunk(0, tdata.proxyEdgeChunk.dataLength), + // team + ref tdata, + ref param, + // vmesh + ref attributes, + ref depthArray, + ref edges, + // particle + ref nextPosArray, + // collider + ref colliderFlagArray, + ref colliderWorkDataArray, + // buffer2 + ref tempVectorBufferA, + ref tempVectorBufferB, + ref tempCountBuffer, + ref tempFloatBufferA + ); + ColliderCollisionConstraint.SumEdgeConstraint( + new DataChunk(0, tdata.particleChunk.dataLength), + // team + ref tdata, + ref param, + // particle + ref nextPosArray, + ref frictionArray, + ref collisionNormalArray, + // buffer2 + ref tempVectorBufferA, + ref tempVectorBufferB, + ref tempCountBuffer, + ref tempFloatBufferA + ); + } + + // コライダー衝突後はパーティクルが乱れる可能性があるためもう一度距離制約で整える。 + // これは裏返り防止などに効果大。 + DistanceConstraint.SolverConstraint( + new DataChunk(0, tdata.particleChunk.dataLength), + simulationPower, + // team + ref tdata, + ref param, + // vmesh + ref attributes, + ref depthArray, + // particle + ref nextPosArray, + ref basePosArray, + ref velocityPosArray, + ref frictionArray, + // constraint + ref distanceIndexArray, + ref distanceDataArray, + ref distanceDistanceArray + ); + + // モーション制約はコライダーより優先 + MotionConstraint.SolverConstraint( + new DataChunk(0, tdata.particleChunk.dataLength), + // team + ref tdata, + ref param, + // vmesh + ref attributes, + ref depthArray, + // particle + ref basePosArray, + ref baseRotArray, + ref nextPosArray, + ref velocityPosArray, + ref frictionArray, + ref collisionNormalArray + ); + + // 座標確定 + SimulationStepPostTeam( + new DataChunk(0, tdata.particleChunk.dataLength), + simulationDeltaTime, + // team + teamId, + ref tdata, + ref cdata, + ref param, + // vmesh + ref attributes, + ref depthArray, + // particle + ref oldPosArray, + ref velocityArray, + ref nextPosArray, + ref velocityPosArray, + ref frictionArray, + ref staticFrictionArray, + ref collisionNormalArray, + ref realVelocityArray + ); + + // コライダーの後更新 + ColliderManager.SimulationEndStep( + new DataChunk(0, tdata.colliderChunk.dataLength), + // team + ref tdata, + // collider + ref colliderNowPositions, + ref colliderNowRotations, + ref colliderOldPositions, + ref colliderOldRotations + ); + } + + // ■表示位置の決定 + SimulationCalcDisplayPosition( + new DataChunk(0, tdata.particleChunk.dataLength), + simulationDeltaTime, + // team + ref tdata, + // particle + ref oldPosArray, + ref realVelocityArray, + ref oldPositionArray, + ref oldRotationArray, + ref dispPosArray, + // vmesh + ref attributes, + ref positions, + ref rotations, + ref vertexRootIndices, + // temp + ref tempVectorBufferA, + ref tempRotationBufferA + ); + + // ■クロスシミュレーション後の頂点姿勢計算 + // プロキシメッシュの頂点から法線接線を求め姿勢を確定させる + // ラインがある場合はベースラインごとに姿勢を整える + // BoneClothの場合は頂点姿勢を連動するトランスフォームデータにコピーする + VirtualMeshManager.SimulationPostProxyMeshUpdateLine( + new DataChunk(0, tdata.baseLineChunk.dataLength), + // team + ref tdata, + ref param, + // vmesh + ref attributes, + ref positions, + ref rotations, + ref vertexLocalPositions, + ref vertexLocalRotations, + ref vertexChildIndexArray, + ref vertexChildDataArray, + ref baseLineFlags, + ref baseLineStartDataIndices, + ref baseLineDataCounts, + ref baseLineData, + // temp + ref tempVectorBufferA, + ref tempRotationBufferA + ); + VirtualMeshManager.SimulationPostProxyMeshUpdateTriangle( + new DataChunk(0, tdata.proxyTriangleChunk.dataLength), + // team + ref tdata, + // vmesh + ref positions, + ref triangles, + ref triangleNormals, + ref triangleTangents, + ref uvs + ); + VirtualMeshManager.SimulationPostProxyMeshUpdateTriangleSum( + new DataChunk(0, tdata.proxyCommonChunk.dataLength), + // team + ref tdata, + // vmesh + ref rotations, + ref triangleNormals, + ref triangleTangents, + ref vertexToTriangles, + ref normalAdjustmentRotations + ); + VirtualMeshManager.SimulationPostProxyMeshUpdateWorldTransform( + new DataChunk(0, tdata.proxyCommonChunk.dataLength), + // team + ref tdata, + // vmesh + ref positions, + ref rotations, + ref vertexToTransformRotations, + // transform + ref transformPositionArray, + ref transformRotationArray + ); + VirtualMeshManager.SimulationPostProxyMeshUpdateLocalTransform( + // team + ref tdata, + // vmesh + ref attributes, + ref vertexParentIndices, + // transform + ref transformPositionArray, + ref transformRotationArray, + ref transformScaleArray, + ref transformLocalPositionArray, + ref transformLocalRotationArray + ); + + // ■コライダー更新後処理 + ColliderManager.SimulationPostUpdate( + // team + ref tdata, + // collider + ref colliderFramePositions, + ref colliderFrameRotations, + ref colliderOldFramePositions, + ref colliderOldFrameRotations + ); + + // ■チーム更新後処理 + TeamManager.SimulationPostTeamUpdate( + // team + ref tdata, + ref cdata + ); + } + } + + //========================================================================================= + /// + /// シミュレーション実行前処理 + /// -リセット + /// -移動影響 + /// + static void SimulationPreTeamUpdate( + DataChunk chunk, + // team + ref TeamManager.TeamData tdata, + in ClothParameters param, + in InertiaConstraint.CenterData cdata, + // vmesh + in NativeArray positions, + in NativeArray rotations, + in NativeArray vertexDepths, + // particle + ref NativeArray nextPosArray, + ref NativeArray oldPosArray, + ref NativeArray oldRotArray, + ref NativeArray basePosArray, + ref NativeArray baseRotArray, + ref NativeArray oldPositionArray, + ref NativeArray oldRotationArray, + ref NativeArray velocityPosArray, + ref NativeArray dispPosArray, + ref NativeArray velocityArray, + ref NativeArray realVelocityArray, + ref NativeArray frictionArray, + ref NativeArray staticFrictionArray, + ref NativeArray collisionNormalArray + ) + { + // パーティクルごと + var pc = tdata.particleChunk; + //int pindex = pc.startIndex; + int pindex = pc.startIndex + chunk.startIndex; + //int vindex = tdata.proxyCommonChunk.startIndex; + int vindex = tdata.proxyCommonChunk.startIndex + chunk.startIndex; + if (tdata.IsReset) + { + // リセット + //for (int i = 0; i < pc.dataLength; i++, pindex++, vindex++) + for (int i = 0; i < chunk.dataLength; i++, pindex++, vindex++) + { + 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; + } + } + else if (tdata.IsInertiaShift || tdata.IsNegativeScaleTeleport) + { + // シフト、テレポート + //for (int i = 0; i < pc.dataLength; i++, pindex++, vindex++) + for (int i = 0; i < chunk.dataLength; i++, pindex++, vindex++) + { + var oldPos = oldPosArray[pindex]; + var oldRot = oldRotArray[pindex]; + var oldPosition = oldPositionArray[pindex]; + var oldRotation = oldRotationArray[pindex]; + var dispPos = dispPosArray[pindex]; + var velocity = velocityArray[pindex]; + var realVelocity = realVelocityArray[pindex]; + + // ■マイナススケール + if (tdata.IsNegativeScaleTeleport) + { + // 本体のスケール反転に合わせてシミュレーションに影響が出ないように必要な座標系を同様に軸反転させる + // パーティクルはセンター空間で軸反転させる + // 軸反転用マトリックス + float4x4 negativeM = cdata.negativeScaleMatrix; + + oldPos = MathUtility.TransformPoint(oldPos, negativeM); + oldRot = MathUtility.TransformRotation(oldRot, negativeM, 1); + + oldPosition = MathUtility.TransformPoint(oldPosition, negativeM); + oldRotation = MathUtility.TransformRotation(oldRotation, negativeM, 1); + + dispPos = MathUtility.TransformPoint(dispPos, negativeM); + + velocity = MathUtility.TransformVector(velocity, negativeM); + realVelocity = MathUtility.TransformVector(realVelocity, negativeM); + } + + // ■慣性全体シフト + if (tdata.IsInertiaShift) + { + // cdata.frameComponentShiftVector : 全体シフトベクトル + // cdata.frameComponentShiftRotation : 全体シフト回転 + // cdata.oldComponentWorldPosition : フレーム移動前のコンポーネント中心位置 + + oldPos = MathUtility.ShiftPosition(oldPos, cdata.oldComponentWorldPosition, cdata.frameComponentShiftVector, cdata.frameComponentShiftRotation); + oldRot = math.mul(cdata.frameComponentShiftRotation, oldRot); + + oldPosition = MathUtility.ShiftPosition(oldPosition, cdata.oldComponentWorldPosition, cdata.frameComponentShiftVector, cdata.frameComponentShiftRotation); + oldRotation = math.mul(cdata.frameComponentShiftRotation, oldRotation); + + dispPos = MathUtility.ShiftPosition(dispPos, cdata.oldComponentWorldPosition, cdata.frameComponentShiftVector, cdata.frameComponentShiftRotation); + + velocity = math.mul(cdata.frameComponentShiftRotation, velocity); + realVelocity = math.mul(cdata.frameComponentShiftRotation, realVelocity); + } + + oldPosArray[pindex] = oldPos; + oldRotArray[pindex] = oldRot; + oldPositionArray[pindex] = oldPosition; + oldRotationArray[pindex] = oldRotation; + dispPosArray[pindex] = dispPos; + velocityArray[pindex] = velocity; + realVelocityArray[pindex] = realVelocity; + } + } + } + + static float3 WindBatchJob( + int teamId, + in WindParams windParams, + int vindex, + int pindex, + float depth, + ref NativeArray vertexRootIndices, + ref TeamWindData teamWindData, + ref NativeArray windDataArray, + ref NativeArray frictionArray + ) + { + float3 windForce = 0; + + // 基準ルート座標 + // (1)チームごとにずらす + // (2)同期率によりルートラインごとにずらす + // (3)チームの座標やパーティクルの座標は計算に入れない + int rootIndex = vertexRootIndices[vindex]; + float3 windPos = (teamId + 1) * 4.19230645f + (rootIndex * 0.0023963f * (1.0f - windParams.synchronization) * 100); + + // ゾーンごとの風影響計算 + int cnt = teamWindData.ZoneCount; + for (int i = 0; i < cnt; i++) + { + var windInfo = teamWindData.windZoneList[i]; + var windData = windDataArray[windInfo.windId]; + windForce += WindForceBlendBatchJob(windInfo, windParams, windPos, windData.turbulence); + } + +#if true + // 移動風影響計算 + if (windParams.movingWind > 0.01f) + { + windForce += WindForceBlendBatchJob(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; + } + + static void SimulationStepUpdateParticles( + DataChunk chunk, + float4 simulationPower, + float simulationDeltaTime, + // team + int teamId, + ref TeamManager.TeamData tdata, + ref InertiaConstraint.CenterData cdata, + ref ClothParameters param, + ref TeamWindData wdata, + // wind + ref NativeArray windDataArray, + // vmesh + ref NativeArray attributes, + ref NativeArray depthArray, + ref NativeArray positions, + ref NativeArray rotations, + ref NativeArray vertexRootIndices, + // particle + ref NativeArray nextPosArray, + ref NativeArray oldPosArray, + ref NativeArray basePosArray, + ref NativeArray baseRotArray, + ref NativeArray oldPositionArray, + ref NativeArray oldRotationArray, + ref NativeArray velocityPosArray, + ref NativeArray velocityArray, + ref NativeArray frictionArray, + // buffer + ref NativeArray stepBasicPositionBuffer, + ref NativeArray stepBasicRotationBuffer, + // temp buffer + ref NativeArray tempVectorBufferA, + ref NativeArray tempVectorBufferB, + ref NativeArray tempCountBuffer, + ref NativeArray tempFloatBufferA + ) + { + // 速度更新、外力の影響、慣性シフト + //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 i = 0; i < tdata.particleChunk.dataLength; i++, pindex++, vindex++) + for (int i = 0; i < chunk.dataLength; i++, pindex++, vindex++) + { + // 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; + + // ステップ基本位置 + stepBasicPositionBuffer[pindex] = basePos; + stepBasicRotationBuffer[pindex] = baseRot; + + // 移動パーティクル + if (attr.IsMove() || tdata.IsSpring) + { + // 重量 + //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); // 二次曲線 + //Debug.Log($"[{pindex}] inertiaDepth:{inertiaDepth}"); + 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.MC2EvaluateCurveClamp01(depth); + velocity *= math.saturate(1.0f - damping * simulationPower.z); + + // 外力 + float3 force = 0; + + // 重力 + float3 gforce = param.worldGravityDirection * (param.gravity * tdata.gravityRatio); + force += gforce; + + // 外力 + float3 exForce = 0; + float mass = MathUtility.CalcMass(depth); + switch (tdata.forceMode) + { + 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; + + // 風力 + force += WindBatchJob( + teamId, + //tdata, + param.wind, + //cdata, + vindex, + pindex, + depth, + ref vertexRootIndices, + ref wdata, + ref windDataArray, + ref frictionArray + ); + + // 外力チームスケール倍率 + 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); + SpringBatchJob(param.springConstraint, param.normalAxis, ref nextPos, basePos, baseRot, (tdata.time + pindex * 49.6198f) * 2.4512f + math.csum(nextPos), tdata.scaleRatio); + } + + // 速度計算用の移動前の位置 + velocityPosArray[pindex] = velocityPos; + + // 予測位置格納 + nextPosArray[pindex] = nextPos; + + // 作業バッファクリア + tempVectorBufferA[pindex] = 0; + tempVectorBufferB[pindex] = 0; + tempCountBuffer[pindex] = 0; + tempFloatBufferA[pindex] = 0; + } + } + + static void SpringBatchJob( + 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) + { + v *= (limitDistance / len); + } + + // 楕円クランプ + if (springParams.normalLimitRatio < 1.0f) + { + // もっとスマートにならないか.. + 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) + { + v -= (math.abs(ylen) - y) * math.sign(ylen) * dir; + } + } + } + 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; + } + + static void SimulationStepUpdateBaseLinePose( + DataChunk chunk, + // team + ref TeamManager.TeamData tdata, + // vmesh + ref NativeArray attributes, + ref NativeArray vertexParentIndices, + ref NativeArray baseLineStartDataIndices, + ref NativeArray baseLineDataCounts, + ref NativeArray baseLineData, + ref NativeArray vertexLocalPositions, + ref NativeArray vertexLocalRotations, + // particle + ref NativeArray basePosArray, + ref NativeArray baseRotArray, + // buffer + ref NativeArray stepBasicPositionBuffer, + ref NativeArray stepBasicRotationBuffer + ) + { + // 制約解決のためのステップごとの基準姿勢を計算 + // ベースラインごと + // アニメーションポーズ使用の有無 + // 初期姿勢の計算が不要なら抜ける + float blendRatio = tdata.animationPoseRatio; + if (blendRatio <= 0.99f) + { + int b_datastart = tdata.baseLineDataChunk.startIndex; + int p_start = tdata.particleChunk.startIndex; + int v_start = tdata.proxyCommonChunk.startIndex; + + // チームスケール + float3 scl = tdata.initScale * tdata.scaleRatio; + + //int bindex = tdata.baseLineChunk.startIndex; + int bindex = tdata.baseLineChunk.startIndex + chunk.startIndex; + //for (int k = 0; k < tdata.baseLineChunk.dataLength; k++, bindex++) + for (int k = 0; k < chunk.dataLength; k++, bindex++) + { + int b_start = baseLineStartDataIndices[bindex]; + int b_cnt = baseLineDataCounts[bindex]; + int 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; + 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() && p_index >= 0) + { + // 移動 + // 親から姿勢を算出する + var lpos = vertexLocalPositions[vindex]; + var lrot = vertexLocalRotations[vindex]; + var ppos = stepBasicPositionBuffer[p_pindex]; + var prot = stepBasicRotationBuffer[p_pindex]; + + // マイナススケール + lpos *= tdata.negativeScaleDirection; + lrot = lrot.value * tdata.negativeScaleQuaternionValue; + + stepBasicPositionBuffer[pindex] = math.mul(prot, lpos * scl) + ppos; + stepBasicRotationBuffer[pindex] = math.mul(prot, lrot); + } + else + { + // マイナススケール + var prot = stepBasicRotationBuffer[pindex]; + var lw = float4x4.TRS(0, prot, tdata.negativeScaleDirection); + quaternion rot = MathUtility.ToRotation(lw.c1.xyz, lw.c2.xyz); + stepBasicRotationBuffer[pindex] = rot; + } + } + } + + // アニメーション姿勢とブレンド + 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; + + var bpos = basePosArray[pindex]; + var brot = baseRotArray[pindex]; + + stepBasicPositionBuffer[pindex] = math.lerp(stepBasicPositionBuffer[pindex], bpos, blendRatio); + stepBasicRotationBuffer[pindex] = math.slerp(stepBasicRotationBuffer[pindex], brot, blendRatio); + } + } + } + } + } + + static float3 WindForceBlendBatchJob( + in TeamWindInfo windInfo, + in WindParams windParams, + in float3 windPos, + float windTurbulence + ) + { + float windMain = windInfo.main; + if (windMain < 0.01f) + return 0; + + //Debug.Log($"windMain:{windMain}"); + + // 風速係数 + 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; + } + + /// + /// 座標確定 + /// + static void SimulationStepPostTeam( + DataChunk chunk, + float simulationDeltaTime, + // team + int teamId, + ref TeamManager.TeamData tdata, + ref InertiaConstraint.CenterData cdata, + ref ClothParameters param, + // vmesh + ref NativeArray attributes, + ref NativeArray depthArray, + // particle + ref NativeArray oldPosArray, + ref NativeArray velocityArray, + ref NativeArray nextPosArray, + ref NativeArray velocityPosArray, + ref NativeArray frictionArray, + ref NativeArray staticFrictionArray, + ref NativeArray collisionNormalArray, + ref NativeArray realVelocityArray + ) + { + // 座標確定 + //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++) + { + var attr = attributes[vindex]; + var depth = depthArray[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 && friction > Define.System.Epsilon; // 接触の有無 + float staticFrictionParam = param.colliderCollisionConstraint.staticFriction * tdata.scaleRatio; + float dynamicFrictionParam = param.colliderCollisionConstraint.dynamicFriction; +#endif + +#if true + // ■静止摩擦 + float staticFriction = staticFrictionArray[pindex]; + if (isCollision && 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?) + } + else + { + // 接線速度に応じて係数を減少 + var vel = tangentVelocity - staticFrictionParam; + var value = math.max(vel / 0.2f, 0.05f); + staticFriction = math.saturate(staticFriction - value); + } + + // 接線方向に位置を巻き戻す + tanv *= staticFriction; + nextPos -= tanv; + velocityOldPos -= tanv; + } + 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 (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) + { + 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); + } + } +#endif + // 安定化用の速度割合 + velocity *= tdata.velocityWeight; + + // 書き戻し + velocityArray[pindex] = velocity; + } + + // 実速度 + float3 realVelocity = (nextPos - oldPos) / simulationDeltaTime; + realVelocityArray[pindex] = realVelocity; + + // 今回の予測位置を記録 + oldPosArray[pindex] = nextPos; + } + } + + /// + /// シミュレーション完了後の表示位置の計算 + /// - 未来予測 + /// + static void SimulationCalcDisplayPosition( + DataChunk chunk, + float simulationDeltaTime, + // team + ref TeamManager.TeamData tdata, + // particle + ref NativeArray oldPosArray, + ref NativeArray realVelocityArray, + ref NativeArray oldPositionArray, + ref NativeArray oldRotationArray, + ref NativeArray dispPosArray, + // vmesh + ref NativeArray attributes, + ref NativeArray positions, + ref NativeArray rotations, + ref NativeArray vertexRootIndices, + // temp + ref NativeArray tempVectorBufferA, + ref NativeArray tempRotationBufferA + ) + { + //int pindex = tdata.particleChunk.startIndex; + int pindex = tdata.particleChunk.startIndex + chunk.startIndex; + int v_start = tdata.proxyCommonChunk.startIndex; + //int vindex = v_start; + 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++) + { + var attr = attributes[vindex]; + + var pos = positions[vindex]; + var rot = rotations[vindex]; + //Debug.Log($"DispRot [{vindex}] nor:{MathUtility.ToNormal(rot)}, tan:{MathUtility.ToTangent(rot)}"); + + if (attr.IsMove() || tdata.IsSpring) + { + // 移動パーティクル + var dpos = oldPosArray[pindex]; + +#if !MC2_DISABLE_FUTURE + // 未来予測 + // 最終計算位置と実速度から次のステップ位置を予測し、その間のフレーム時間位置を表示位置とする + float3 velocity = realVelocityArray[pindex] * simulationDeltaTime; + float3 fpos = dpos + velocity; + float interval = (tdata.nowUpdateTime + simulationDeltaTime) - tdata.oldTime; + float t = interval > 0.0f ? (tdata.time - tdata.oldTime) / interval : 0.0f; + fpos = math.lerp(dispPosArray[pindex], fpos, t); + // ルートからの距離クランプ(安全対策) + int rootIndex = vertexRootIndices[vindex]; + if (rootIndex >= 0) + { + var rootPos = positions[v_start + rootIndex]; + float originalDist = math.distance(rootPos, pos); + float clampDist = originalDist * Define.System.MaxDistanceRatioFutuerPrediction; // 許容限界距離 + var v = fpos - rootPos; + v = MathUtility.ClampVector(v, clampDist); + fpos = rootPos + v; + } + + 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; + } + + // マイナススケール + // 回転をマイナススケールを適用した表示計算用の回転に変換する + if (tdata.IsNegativeScale) + { + var lw = float4x4.TRS(0, rot, tdata.negativeScaleDirection); + rot = MathUtility.ToRotation(lw.c1.xyz, lw.c2.xyz); + rotations[vindex] = rot; + } + + // BoneClothのベースライン姿勢制御のために基本姿勢をtempに保存 + tempVectorBufferA[pindex] = pos; + tempRotationBufferA[pindex] = rot; + } + } + + unsafe static void SimulationClearTempBuffer( + DataChunk chunk, + // team + ref TeamManager.TeamData tdata, + // buffer2 + ref NativeArray tempVectorBufferA, + ref NativeArray tempVectorBufferB, + ref NativeArray tempCountBuffer, + ref NativeArray tempFloatBufferA + //ref NativeArray tempRotationBufferA, + //ref NativeArray tempRotationBufferB, + ) + { + int pindex = tdata.particleChunk.startIndex + chunk.startIndex; + for (int i = 0; i < chunk.dataLength; i++, pindex++) + { + tempVectorBufferA[pindex] = 0; + tempVectorBufferB[pindex] = 0; + tempCountBuffer[pindex] = 0; + tempFloatBufferA[pindex] = 0; + } + } + } +} + diff --git a/Assets/MagicaCloth2/Scripts/Core/Manager/Simulation/SimulationManagerNormal.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Manager/Simulation/SimulationManagerNormal.cs.meta new file mode 100644 index 00000000..169a9cbc --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Manager/Simulation/SimulationManagerNormal.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 1678d975c7bf0f343bf9eb89afc158fe +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Manager/Simulation/SimulationManagerNormal.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Manager/Simulation/SimulationManagerSplit.cs b/Assets/MagicaCloth2/Scripts/Core/Manager/Simulation/SimulationManagerSplit.cs new file mode 100644 index 00000000..d85f72d4 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Manager/Simulation/SimulationManagerSplit.cs @@ -0,0 +1,2373 @@ +// 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 +{ + /// + /// Split + /// セルフコリジョンあり、もしくはプロキシメッシュの頂点数が一定値以上のジョブ + /// オリジナルと同様にジョブを分割し同期しながら実行する + /// ただし最適化を行いオリジナルより軽量化している + /// + public partial class SimulationManager + { + /// + /// プロキシメッシュをスキニングし基本姿勢を求める + /// + [BurstCompile] + unsafe struct SplitPre_A_Job : IJobParallelFor + { + public int workerCount; + + // team + [Unity.Collections.ReadOnly] + public NativeList batchSelfTeamList; + [Unity.Collections.ReadOnly] + public NativeArray teamDataArray; + + // transform + [Unity.Collections.ReadOnly] + public NativeArray transformLocalToWorldMatrixArray; + + // vmesh + [Unity.Collections.ReadOnly] + public NativeArray attributes; + [Unity.Collections.ReadOnly] + public NativeArray localPositions; + [Unity.Collections.ReadOnly] + public NativeArray localNormals; + [Unity.Collections.ReadOnly] + public NativeArray localTangents; + [Unity.Collections.ReadOnly] + public NativeArray boneWeights; + [Unity.Collections.ReadOnly] + public NativeArray skinBoneTransformIndices; + [Unity.Collections.ReadOnly] + public NativeArray skinBoneBindPoses; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray positions; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray rotations; + + // バッチ内のローカルチームインデックスごと + public void Execute(int index) + { + // チームIDとワーカーID + int localIndex = index / workerCount; + int workerIndex = index % workerCount; + + //Debug.Log(localIndex); + + // 各ベースポインタ + TeamManager.TeamData* teamPt = (TeamManager.TeamData*)teamDataArray.GetUnsafeReadOnlyPtr(); + + int teamId = batchSelfTeamList[localIndex]; + + //Debug.Log($"{localIndex}, {teamId}"); + + ref var tdata = ref *(teamPt + teamId); + + if (tdata.IsProcess == false) + return; + if (tdata.ParticleCount == 0) + return; + + // 範囲 + var chunk = MathUtility.GetWorkerChunk(tdata.proxyCommonChunk.dataLength, workerCount, workerIndex); + if (chunk.IsValid == false) + return; + + // ■プロキシメッシュをスキニングし基本姿勢を求める + VirtualMeshManager.SimulationPreProxyMeshUpdate( + //new DataChunk(0, tdata.proxyCommonChunk.dataLength), + chunk, + // team + teamId, + ref tdata, + // vmesh + attributes, + localPositions, + localNormals, + localTangents, + boneWeights, + skinBoneTransformIndices, + skinBoneBindPoses, + ref positions, + ref rotations, + // transform + transformLocalToWorldMatrixArray + ); + } + } + + /// + /// チームのセンター姿勢の決定と慣性用の移動量計算 + /// + [BurstCompile] + unsafe struct SplitPre_B_Job : IJobParallelFor + { + public float simulationDeltaTime; + + // team + [Unity.Collections.ReadOnly] + public NativeList batchSelfTeamList; + [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 + [Unity.Collections.ReadOnly] + public NativeArray transformPositionArray; + [Unity.Collections.ReadOnly] + public NativeArray transformRotationArray; + [Unity.Collections.ReadOnly] + public NativeArray transformScaleArray; + + // vmesh + [Unity.Collections.ReadOnly] + public NativeArray positions; + [Unity.Collections.ReadOnly] + public NativeArray rotations; + [Unity.Collections.ReadOnly] + public NativeArray vertexBindPoseRotations; + + + // inertia + [Unity.Collections.ReadOnly] + public NativeArray fixedArray; + + // バッチ内のローカルチームインデックスごと + public void Execute(int localIndex) + { + //Debug.Log(localIndex); + + // 各ベースポインタ + TeamManager.TeamData* teamPt = (TeamManager.TeamData*)teamDataArray.GetUnsafePtr(); + ClothParameters* paramPt = (ClothParameters*)parameterArray.GetUnsafeReadOnlyPtr(); + InertiaConstraint.CenterData* centerPt = (InertiaConstraint.CenterData*)centerDataArray.GetUnsafePtr(); + TeamWindData* windPt = (TeamWindData*)teamWindArray.GetUnsafePtr(); + + int teamId = batchSelfTeamList[localIndex]; + ref var tdata = ref *(teamPt + teamId); + ref var cdata = ref *(centerPt + teamId); + ref var param = ref *(paramPt + teamId); + ref var wdata = ref *(windPt + teamId); + + if (tdata.IsProcess == false) + return; + if (tdata.ParticleCount == 0) + return; + + // チームのセンター姿勢の決定と慣性用の移動量計算 + TeamManager.SimulationCalcCenterAndInertiaAndWind( + simulationDeltaTime, + // team + teamId, + ref tdata, + ref cdata, + ref wdata, + ref param, + // vmesh + positions, + rotations, + vertexBindPoseRotations, + // inertia + fixedArray, + // transform + transformPositionArray, + transformRotationArray, + transformScaleArray, + // wind + windZoneCount, + windDataArray + ); + } + } + + /// + /// パーティクルの全体慣性およびリセットの適用 + /// コライダーのローカル姿勢を求める、および全体慣性とリセットの適用 + /// + [BurstCompile] + unsafe struct SplitPre_C_Job : IJobParallelFor + { + public int workerCount; + + // team + [Unity.Collections.ReadOnly] + public NativeList batchSelfTeamList; + [Unity.Collections.ReadOnly] + public NativeArray teamDataArray; + [Unity.Collections.ReadOnly] + public NativeArray centerDataArray; + [Unity.Collections.ReadOnly] + public NativeArray parameterArray; + + // transform + [Unity.Collections.ReadOnly] + public NativeArray transformPositionArray; + [Unity.Collections.ReadOnly] + public NativeArray transformRotationArray; + [Unity.Collections.ReadOnly] + public NativeArray transformScaleArray; + [Unity.Collections.ReadOnly] + public NativeArray transformLocalPositionArray; + [Unity.Collections.ReadOnly] + public NativeArray transformLocalRotationArray; + [Unity.Collections.ReadOnly] + public NativeArray transformLocalScaleArray; + + // vmesh + [Unity.Collections.ReadOnly] + public NativeArray positions; + [Unity.Collections.ReadOnly] + public NativeArray rotations; + [Unity.Collections.ReadOnly] + public NativeArray vertexDepths; + + // particle + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray nextPosArray; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray oldPosArray; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray oldRotArray; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray basePosArray; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray baseRotArray; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray oldPositionArray; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray oldRotationArray; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray velocityPosArray; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray dispPosArray; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray velocityArray; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray realVelocityArray; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray frictionArray; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray staticFrictionArray; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray collisionNormalArray; + + // collider + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray colliderFlagArray; + [Unity.Collections.ReadOnly] + public NativeArray colliderCenterArray; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray colliderFramePositions; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray colliderFrameRotations; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray colliderFrameScales; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray colliderOldFramePositions; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray colliderOldFrameRotations; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray colliderNowPositions; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray colliderNowRotations; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray colliderOldPositions; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray colliderOldRotations; + [Unity.Collections.ReadOnly] + public NativeArray colliderMainColliderIndices; + + // バッチ内のローカルチームインデックスごと + public void Execute(int index) + { + // チームIDとワーカーID + int localIndex = index / workerCount; + int workerIndex = index % workerCount; + //Debug.Log(localIndex); + + // 各ベースポインタ + TeamManager.TeamData* teamPt = (TeamManager.TeamData*)teamDataArray.GetUnsafeReadOnlyPtr(); + ClothParameters* paramPt = (ClothParameters*)parameterArray.GetUnsafeReadOnlyPtr(); + InertiaConstraint.CenterData* centerPt = (InertiaConstraint.CenterData*)centerDataArray.GetUnsafeReadOnlyPtr(); + + int teamId = batchSelfTeamList[localIndex]; + ref var tdata = ref *(teamPt + teamId); + ref var cdata = ref *(centerPt + teamId); + ref var param = ref *(paramPt + teamId); + + if (tdata.IsProcess == false) + return; + if (tdata.ParticleCount == 0) + return; + + // パーティクルの全体慣性およびリセットの適用 + var p_chunk = MathUtility.GetWorkerChunk(tdata.particleChunk.dataLength, workerCount, workerIndex); + if (p_chunk.IsValid) + { + SimulationPreTeamUpdate( + p_chunk, + // team + ref tdata, + param, + cdata, + // vmesh + positions, + rotations, + vertexDepths, + // particle + ref nextPosArray, + ref oldPosArray, + ref oldRotArray, + ref basePosArray, + ref baseRotArray, + ref oldPositionArray, + ref oldRotationArray, + ref velocityPosArray, + ref dispPosArray, + ref velocityArray, + ref realVelocityArray, + ref frictionArray, + ref staticFrictionArray, + ref collisionNormalArray + ); + } + + // ■コライダーのローカル姿勢を求める、および全体慣性とリセットの適用 + if (tdata.colliderCount > 0) + { + var c_chunk = MathUtility.GetWorkerChunk(tdata.colliderChunk.dataLength, workerCount, workerIndex); + if (c_chunk.IsValid) + { + ColliderManager.SimulationPreUpdate( + c_chunk, + // team + ref tdata, + ref cdata, + // collider + ref colliderFlagArray, + ref colliderCenterArray, + ref colliderFramePositions, + ref colliderFrameRotations, + ref colliderFrameScales, + ref colliderOldFramePositions, + ref colliderOldFrameRotations, + ref colliderNowPositions, + ref colliderNowRotations, + ref colliderOldPositions, + ref colliderOldRotations, + ref colliderMainColliderIndices, + // transform + ref transformPositionArray, + ref transformRotationArray, + ref transformScaleArray, + ref transformLocalPositionArray, + ref transformLocalRotationArray, + ref transformLocalScaleArray + ); + } + } + } + } + + /// + /// チーム更新 + /// コライダーの更新 + /// + [BurstCompile] + unsafe struct SplitStep_A_Job : IJobParallelFor + { + public int updateIndex; + public float4 simulationPower; + public float simulationDeltaTime; + + // team + [Unity.Collections.ReadOnly] + public NativeList batchSelfTeamList; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray teamDataArray; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray centerDataArray; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray teamWindArray; + [Unity.Collections.ReadOnly] + public NativeArray parameterArray; + + // collider + [Unity.Collections.ReadOnly] + public NativeArray colliderFlagArray; + [Unity.Collections.ReadOnly] + public NativeArray colliderSizeArray; + [Unity.Collections.ReadOnly] + public NativeArray colliderFramePositions; + [Unity.Collections.ReadOnly] + public NativeArray colliderFrameRotations; + [Unity.Collections.ReadOnly] + public NativeArray colliderFrameScales; + [Unity.Collections.ReadOnly] + public NativeArray colliderOldFramePositions; + [Unity.Collections.ReadOnly] + public NativeArray colliderOldFrameRotations; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray colliderNowPositions; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray colliderNowRotations; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray colliderOldPositions; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray colliderOldRotations; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray colliderWorkDataArray; + + // バッチ内のローカルチームインデックスごと + public void Execute(int localIndex) + { + // 各ベースポインタ + TeamManager.TeamData* teamPt = (TeamManager.TeamData*)teamDataArray.GetUnsafePtr(); + ClothParameters* paramPt = (ClothParameters*)parameterArray.GetUnsafeReadOnlyPtr(); + InertiaConstraint.CenterData* centerPt = (InertiaConstraint.CenterData*)centerDataArray.GetUnsafePtr(); + TeamWindData* windPt = (TeamWindData*)teamWindArray.GetUnsafePtr(); + + int teamId = batchSelfTeamList[localIndex]; + ref var tdata = ref *(teamPt + teamId); + ref var cdata = ref *(centerPt + teamId); + ref var param = ref *(paramPt + teamId); + ref var wdata = ref *(windPt + teamId); + + if (updateIndex >= tdata.updateCount) + return; + if (tdata.IsProcess == false) + return; + if (tdata.ParticleCount == 0) + return; + + // ステップ実行 + // ステップごとのチーム更新 + TeamManager.SimulationStepTeamUpdate( + updateIndex, + simulationDeltaTime, + // team + teamId, + ref tdata, + ref param, + ref cdata, + ref wdata + ); + + // コライダーの更新 + if (tdata.colliderCount > 0) + { + ColliderManager.SimulationStartStep( + // team + ref tdata, + ref cdata, + // collider + ref colliderFlagArray, + ref colliderSizeArray, + ref colliderFramePositions, + ref colliderFrameRotations, + ref colliderFrameScales, + ref colliderOldFramePositions, + ref colliderOldFrameRotations, + ref colliderNowPositions, + ref colliderNowRotations, + ref colliderOldPositions, + ref colliderOldRotations, + ref colliderWorkDataArray + ); + } + } + } + + /// + /// 速度更新、外力の影響、慣性シフト + /// + [BurstCompile] + unsafe struct SplitStep_B_Job : IJobParallelFor + { + public int workerCount; + public int updateIndex; + public float4 simulationPower; + public float simulationDeltaTime; + + // team + [Unity.Collections.ReadOnly] + public NativeList batchSelfTeamList; + [Unity.Collections.ReadOnly] + public NativeArray teamDataArray; + [Unity.Collections.ReadOnly] + public NativeArray centerDataArray; + [Unity.Collections.ReadOnly] + public NativeArray teamWindArray; + [Unity.Collections.ReadOnly] + public NativeArray parameterArray; + + // wind + public int windZoneCount; + [Unity.Collections.ReadOnly] + public NativeArray windDataArray; + + // 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; + + // particle + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray nextPosArray; + [Unity.Collections.ReadOnly] + public NativeArray oldPosArray; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray basePosArray; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray baseRotArray; + [Unity.Collections.ReadOnly] + public NativeArray oldPositionArray; + [Unity.Collections.ReadOnly] + public NativeArray oldRotationArray; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray velocityPosArray; + [Unity.Collections.ReadOnly] + public NativeArray velocityArray; + [Unity.Collections.ReadOnly] + public NativeArray frictionArray; + + // buffer + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray stepBasicPositionBuffer; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray stepBasicRotationBuffer; + + // temp + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray tempVectorBufferA; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray tempVectorBufferB; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray tempCountBuffer; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray tempFloatBufferA; + + // バッチ内のローカルチームインデックスごと + public void Execute(int index) + { + // チームIDとワーカーID + int localIndex = index / workerCount; + int workerIndex = index % workerCount; + + // 各ベースポインタ + TeamManager.TeamData* teamPt = (TeamManager.TeamData*)teamDataArray.GetUnsafeReadOnlyPtr(); + ClothParameters* paramPt = (ClothParameters*)parameterArray.GetUnsafeReadOnlyPtr(); + InertiaConstraint.CenterData* centerPt = (InertiaConstraint.CenterData*)centerDataArray.GetUnsafeReadOnlyPtr(); + TeamWindData* windPt = (TeamWindData*)teamWindArray.GetUnsafeReadOnlyPtr(); + + int teamId = batchSelfTeamList[localIndex]; + ref var tdata = ref *(teamPt + teamId); + ref var cdata = ref *(centerPt + teamId); + ref var param = ref *(paramPt + teamId); + ref var wdata = ref *(windPt + teamId); + + if (updateIndex >= tdata.updateCount) + return; + if (tdata.IsProcess == false) + return; + if (tdata.ParticleCount == 0) + return; + + // 範囲 + var chunk = MathUtility.GetWorkerChunk(tdata.particleChunk.dataLength, workerCount, workerIndex); + if (chunk.IsValid == false) + return; + + // 速度更新、外力の影響、慣性シフト + SimulationStepUpdateParticles( + //new DataChunk(0, tdata.particleChunk.dataLength), + chunk, + simulationPower, + simulationDeltaTime, + // team + teamId, + ref tdata, + ref cdata, + ref param, + ref wdata, + // wind + ref windDataArray, + // vmesh + ref attributes, + ref depthArray, + ref positions, + ref rotations, + ref vertexRootIndices, + // particle + ref nextPosArray, + ref oldPosArray, + ref basePosArray, + ref baseRotArray, + ref oldPositionArray, + ref oldRotationArray, + ref velocityPosArray, + ref velocityArray, + ref frictionArray, + // buffer + ref stepBasicPositionBuffer, + ref stepBasicRotationBuffer, + // temp + ref tempVectorBufferA, + ref tempVectorBufferB, + ref tempCountBuffer, + ref tempFloatBufferA + ); + } + } + + /// + /// ベースラインの基準姿勢を計算 + /// + [BurstCompile] + unsafe struct SplitStep_C_Job : IJobParallelFor + { + public int workerCount; + public int updateIndex; + + // team + [Unity.Collections.ReadOnly] + public NativeList batchSelfTeamList; + [Unity.Collections.ReadOnly] + public NativeArray teamDataArray; + + // vmesh + [Unity.Collections.ReadOnly] + public NativeArray attributes; + [Unity.Collections.ReadOnly] + public NativeArray vertexRootIndices; + [Unity.Collections.ReadOnly] + public NativeArray vertexParentIndices; + [Unity.Collections.ReadOnly] + public NativeArray baseLineStartDataIndices; + [Unity.Collections.ReadOnly] + public NativeArray baseLineDataCounts; + [Unity.Collections.ReadOnly] + public NativeArray baseLineData; + [Unity.Collections.ReadOnly] + public NativeArray vertexLocalPositions; + [Unity.Collections.ReadOnly] + public NativeArray vertexLocalRotations; + + // particle + [Unity.Collections.ReadOnly] + public NativeArray basePosArray; + [Unity.Collections.ReadOnly] + public NativeArray baseRotArray; + + // buffer + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray stepBasicPositionBuffer; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray stepBasicRotationBuffer; + + // バッチ内のローカルチームインデックスごと + public void Execute(int index) + { + // チームIDとワーカーID + int localIndex = index / workerCount; + int workerIndex = index % workerCount; + + // 各ベースポインタ + TeamManager.TeamData* teamPt = (TeamManager.TeamData*)teamDataArray.GetUnsafeReadOnlyPtr(); + + int teamId = batchSelfTeamList[localIndex]; + ref var tdata = ref *(teamPt + teamId); + + if (updateIndex >= tdata.updateCount) + return; + if (tdata.IsProcess == false) + return; + if (tdata.ParticleCount == 0) + return; + + // 範囲 + var chunk = MathUtility.GetWorkerChunk(tdata.baseLineChunk.dataLength, workerCount, workerIndex); + if (chunk.IsValid == false) + return; + + // 制約解決のためのステップごとの基準姿勢を計算 + // ベースラインごと + // アニメーションポーズ使用の有無 + SimulationStepUpdateBaseLinePose( + //new DataChunk(0, tdata.baseLineChunk.dataLength), + chunk, + // team + ref tdata, + // vmesh + ref attributes, + ref vertexParentIndices, + ref baseLineStartDataIndices, + ref baseLineDataCounts, + ref baseLineData, + ref vertexLocalPositions, + ref vertexLocalRotations, + // particle + ref basePosArray, + ref baseRotArray, + // buffer + ref stepBasicPositionBuffer, + ref stepBasicRotationBuffer + ); + } + } + + /// + /// テザー + /// 距離 + /// + [BurstCompile] + unsafe struct SplitStep_D_Job : IJobParallelFor + { + public int workerCount; + public int updateIndex; + public float4 simulationPower; + + // team + [Unity.Collections.ReadOnly] + public NativeList batchSelfTeamList; + [Unity.Collections.ReadOnly] + public NativeArray teamDataArray; + [Unity.Collections.ReadOnly] + public NativeArray centerDataArray; + [Unity.Collections.ReadOnly] + public NativeArray parameterArray; + + // vmesh + [Unity.Collections.ReadOnly] + public NativeArray attributes; + [Unity.Collections.ReadOnly] + public NativeArray depthArray; + [Unity.Collections.ReadOnly] + public NativeArray vertexRootIndices; + + // particle + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray nextPosArray; + [Unity.Collections.ReadOnly] + public NativeArray basePosArray; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray velocityPosArray; + [Unity.Collections.ReadOnly] + public NativeArray frictionArray; + + // distance + [Unity.Collections.ReadOnly] + public NativeArray distanceIndexArray; + [Unity.Collections.ReadOnly] + public NativeArray distanceDataArray; + [Unity.Collections.ReadOnly] + public NativeArray distanceDistanceArray; + + // buffer + [Unity.Collections.ReadOnly] + public NativeArray stepBasicPositionBuffer; + + // バッチ内のローカルチームインデックスごと + public void Execute(int index) + { + // チームIDとワーカーID + int localIndex = index / workerCount; + int workerIndex = index % workerCount; + + // 各ベースポインタ + TeamManager.TeamData* teamPt = (TeamManager.TeamData*)teamDataArray.GetUnsafeReadOnlyPtr(); + ClothParameters* paramPt = (ClothParameters*)parameterArray.GetUnsafeReadOnlyPtr(); + InertiaConstraint.CenterData* centerPt = (InertiaConstraint.CenterData*)centerDataArray.GetUnsafeReadOnlyPtr(); + + int teamId = batchSelfTeamList[localIndex]; + ref var tdata = ref *(teamPt + teamId); + ref var cdata = ref *(centerPt + teamId); + ref var param = ref *(paramPt + teamId); + + if (updateIndex >= tdata.updateCount) + return; + if (tdata.IsProcess == false) + return; + if (tdata.ParticleCount == 0) + return; + + // 範囲 + var chunk = MathUtility.GetWorkerChunk(tdata.particleChunk.dataLength, workerCount, workerIndex); + if (chunk.IsValid == false) + return; + + TetherConstraint.SolverConstraint( + //new DataChunk(0, tdata.particleChunk.dataLength), + chunk, + // team + ref tdata, + ref param, + ref cdata, + // vmesh + ref attributes, + ref depthArray, + ref vertexRootIndices, + // particle + ref nextPosArray, + ref velocityPosArray, + ref frictionArray, + // buffer + ref stepBasicPositionBuffer + ); + + DistanceConstraint.SolverConstraint( + //new DataChunk(0, tdata.particleChunk.dataLength), + chunk, + simulationPower, + // team + ref tdata, + ref param, + // vmesh + ref attributes, + ref depthArray, + // particle + ref nextPosArray, + ref basePosArray, + ref velocityPosArray, + ref frictionArray, + // constraint + ref distanceIndexArray, + ref distanceDataArray, + ref distanceDistanceArray + ); + } + } + + /// + /// アングル + /// + [BurstCompile] + unsafe struct SplitStep_Angle_Job : IJobParallelFor + { + public int workerCount; + public int updateIndex; + public float4 simulationPower; + + // team + [Unity.Collections.ReadOnly] + public NativeList batchSelfTeamList; + [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; + [Unity.Collections.ReadOnly] + public NativeArray vertexRootIndices; + [Unity.Collections.ReadOnly] + public NativeArray vertexParentIndices; + [Unity.Collections.ReadOnly] + public NativeArray baseLineStartDataIndices; + [Unity.Collections.ReadOnly] + public NativeArray baseLineDataCounts; + [Unity.Collections.ReadOnly] + public NativeArray baseLineData; + + // particle + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray nextPosArray; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray velocityPosArray; + [Unity.Collections.ReadOnly] + public NativeArray frictionArray; + + // distance + [Unity.Collections.ReadOnly] + public NativeArray distanceIndexArray; + [Unity.Collections.ReadOnly] + public NativeArray distanceDataArray; + [Unity.Collections.ReadOnly] + public NativeArray distanceDistanceArray; + + // buffer + [Unity.Collections.ReadOnly] + public NativeArray stepBasicPositionBuffer; + [Unity.Collections.ReadOnly] + public NativeArray stepBasicRotationBuffer; + + // buffer2 + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray tempVectorBufferA; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray tempVectorBufferB; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray tempFloatBufferA; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray tempRotationBufferA; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray tempRotationBufferB; + + // バッチ内のローカルチームインデックスごと + // ワーカー分割 + public void Execute(int index) + { + // チームIDとワーカーID + int localIndex = index / workerCount; + int workerIndex = index % workerCount; + + // 各ベースポインタ + TeamManager.TeamData* teamPt = (TeamManager.TeamData*)teamDataArray.GetUnsafeReadOnlyPtr(); + ClothParameters* paramPt = (ClothParameters*)parameterArray.GetUnsafeReadOnlyPtr(); + + int teamId = batchSelfTeamList[localIndex]; + ref var tdata = ref *(teamPt + teamId); + ref var param = ref *(paramPt + teamId); + + if (updateIndex >= tdata.updateCount) + return; + if (tdata.IsProcess == false) + return; + if (tdata.ParticleCount == 0) + return; + + // 範囲 + var chunk = MathUtility.GetWorkerChunk(tdata.baseLineChunk.dataLength, workerCount, workerIndex); + if (chunk.IsValid == false) + return; + + AngleConstraint.SolverConstraint( + chunk, + simulationPower, + // team + ref tdata, + ref param, + // vmesh + ref attributes, + ref depthArray, + ref vertexParentIndices, + ref baseLineStartDataIndices, + ref baseLineDataCounts, + ref baseLineData, + // particle + ref nextPosArray, + ref velocityPosArray, + ref frictionArray, + // buffer + ref stepBasicPositionBuffer, + ref stepBasicRotationBuffer, + // buffer2 + ref tempFloatBufferA, + ref tempVectorBufferA, + ref tempRotationBufferA, + ref tempRotationBufferB, + ref tempVectorBufferB + ); + } + } + + /// + /// トライアングルベンド + /// + [BurstCompile] + unsafe struct SplitStep_Triangle_Job : IJobParallelFor + { + public int workerCount; + public int updateIndex; + public float4 simulationPower; + + // team + [Unity.Collections.ReadOnly] + public NativeList batchSelfTeamList; + [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 + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray nextPosArray; + [Unity.Collections.ReadOnly] + public NativeArray frictionArray; + + // triangle bending + [Unity.Collections.ReadOnly] + public NativeArray bendingTrianglePairArray; + [Unity.Collections.ReadOnly] + public NativeArray bendingRestAngleOrVolumeArray; + [Unity.Collections.ReadOnly] + public NativeArray bendingSignOrVolumeArray; + + // buffer2 + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray tempVectorBufferA; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray tempCountBuffer; + + // バッチ内のローカルチームインデックスごと + // ワーカー分割 + public void Execute(int index) + { + // チームIDとワーカーID + int localIndex = index / workerCount; + int workerIndex = index % workerCount; + + // 各ベースポインタ + TeamManager.TeamData* teamPt = (TeamManager.TeamData*)teamDataArray.GetUnsafeReadOnlyPtr(); + ClothParameters* paramPt = (ClothParameters*)parameterArray.GetUnsafeReadOnlyPtr(); + + int teamId = batchSelfTeamList[localIndex]; + ref var tdata = ref *(teamPt + teamId); + ref var param = ref *(paramPt + teamId); + + if (updateIndex >= tdata.updateCount) + return; + if (tdata.IsProcess == false) + return; + if (tdata.ParticleCount == 0) + return; + + // 範囲 + var chunk = MathUtility.GetWorkerChunk(tdata.bendingPairChunk.dataLength, workerCount, workerIndex); + if (chunk.IsValid == false) + return; + + TriangleBendingConstraint.SolverConstraint( + chunk, + simulationPower, + // team + ref tdata, + ref param, + // vmesh + ref attributes, + ref depthArray, + // particle + ref nextPosArray, + ref frictionArray, + // constraints + ref bendingTrianglePairArray, + ref bendingRestAngleOrVolumeArray, + ref bendingSignOrVolumeArray, + // buffer2 + ref tempVectorBufferA, + ref tempCountBuffer + ); + } + } + + /// + /// トライアングルベンド集計 + /// コライダーコリジョンPoint + /// + [BurstCompile] + unsafe struct SplitStep_E_Job : IJobParallelFor + { + public int workerCount; + public int updateIndex; + public float4 simulationPower; + + // team + [Unity.Collections.ReadOnly] + public NativeList batchSelfTeamList; + [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 + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray nextPosArray; + [Unity.Collections.ReadOnly] + public NativeArray basePosArray; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray velocityPosArray; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray frictionArray; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray collisionNormalArray; + + // collider + [Unity.Collections.ReadOnly] + public NativeArray colliderFlagArray; + [Unity.Collections.ReadOnly] + public NativeArray colliderWorkDataArray; + + // buffer2 + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray tempVectorBufferA; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray tempCountBuffer; + + // バッチ内のローカルチームインデックスごと + // ワーカー分割 + public void Execute(int index) + { + // チームIDとワーカーID + int localIndex = index / workerCount; + int workerIndex = index % workerCount; + + // 各ベースポインタ + TeamManager.TeamData* teamPt = (TeamManager.TeamData*)teamDataArray.GetUnsafeReadOnlyPtr(); + ClothParameters* paramPt = (ClothParameters*)parameterArray.GetUnsafeReadOnlyPtr(); + + int teamId = batchSelfTeamList[localIndex]; + ref var tdata = ref *(teamPt + teamId); + ref var param = ref *(paramPt + teamId); + + if (updateIndex >= tdata.updateCount) + return; + if (tdata.IsProcess == false) + return; + if (tdata.ParticleCount == 0) + return; + + // 範囲 + var chunk = MathUtility.GetWorkerChunk(tdata.particleChunk.dataLength, workerCount, workerIndex); + if (chunk.IsValid == false) + return; + + TriangleBendingConstraint.SumConstraint( + //new DataChunk(0, tdata.particleChunk.dataLength), + chunk, + // team + ref tdata, + ref param, + // vmesh + ref attributes, + // particle + ref nextPosArray, + // buffer2 + ref tempVectorBufferA, + ref tempCountBuffer + ); + + // コライダーコリジョン + if (tdata.UseColliderCount > 0 && param.colliderCollisionConstraint.mode == ColliderCollisionConstraint.Mode.Point) + { + // Pointコリジョン + ColliderCollisionConstraint.SolverPointConstraint( + //new DataChunk(0, tdata.particleChunk.dataLength), + chunk, + // team + ref tdata, + ref param, + // vmesh + ref attributes, + ref depthArray, + // particle + ref nextPosArray, + ref frictionArray, + ref collisionNormalArray, + ref velocityPosArray, + ref basePosArray, + // collider + ref colliderFlagArray, + ref colliderWorkDataArray + ); + } + } + } + + /// + /// コライダーコリジョンEdge + /// + [BurstCompile] + unsafe struct SplitStep_Edge_Job : IJobParallelFor + { + public int workerCount; + public int updateIndex; + public float4 simulationPower; + + // team + [Unity.Collections.ReadOnly] + public NativeList batchSelfTeamList; + [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; + [Unity.Collections.ReadOnly] + public NativeArray edges; + + // particle + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray nextPosArray; + + // collider + [Unity.Collections.ReadOnly] + public NativeArray colliderFlagArray; + [Unity.Collections.ReadOnly] + public NativeArray colliderWorkDataArray; + + // buffer2 + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray tempVectorBufferA; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray tempVectorBufferB; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray tempCountBuffer; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray tempFloatBufferA; + + // バッチ内のローカルチームインデックスごと + // ワーカー分割 + public void Execute(int index) + { + // チームIDとワーカーID + int localIndex = index / workerCount; + int workerIndex = index % workerCount; + + // 各ベースポインタ + TeamManager.TeamData* teamPt = (TeamManager.TeamData*)teamDataArray.GetUnsafeReadOnlyPtr(); + ClothParameters* paramPt = (ClothParameters*)parameterArray.GetUnsafeReadOnlyPtr(); + + int teamId = batchSelfTeamList[localIndex]; + ref var tdata = ref *(teamPt + teamId); + ref var param = ref *(paramPt + teamId); + + if (updateIndex >= tdata.updateCount) + return; + if (tdata.IsProcess == false) + return; + if (tdata.ParticleCount == 0) + return; + + // コライダーコリジョン + if (tdata.UseColliderCount > 0 && param.colliderCollisionConstraint.mode == ColliderCollisionConstraint.Mode.Edge) + { + // 範囲 + var chunk = MathUtility.GetWorkerChunk(tdata.proxyEdgeChunk.dataLength, workerCount, workerIndex); + if (chunk.IsValid == false) + return; + + // Edgeコリジョン + ColliderCollisionConstraint.SolverEdgeConstraint( + //new DataChunk(0, tdata.proxyEdgeChunk.dataLength), + chunk, + // team + ref tdata, + ref param, + // vmesh + ref attributes, + ref depthArray, + ref edges, + // particle + ref nextPosArray, + // collider + ref colliderFlagArray, + ref colliderWorkDataArray, + // buffer2 + ref tempVectorBufferA, + ref tempVectorBufferB, + ref tempCountBuffer, + ref tempFloatBufferA + ); + } + } + } + + /// + /// ■セルフコリジョンあり + /// コライダーコリジョンEdge集計 + /// 距離 + /// モーション + /// + [BurstCompile] + unsafe struct SplitStep_F_Self_Job : IJobParallelFor + { + public int workerCount; + public int updateIndex; + public float4 simulationPower; + + // team + [Unity.Collections.ReadOnly] + public NativeList batchSelfTeamList; + [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 + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray nextPosArray; + [Unity.Collections.ReadOnly] + public NativeArray basePosArray; + [Unity.Collections.ReadOnly] + public NativeArray baseRotArray; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray velocityPosArray; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray frictionArray; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray collisionNormalArray; + + // distance + [Unity.Collections.ReadOnly] + public NativeArray distanceIndexArray; + [Unity.Collections.ReadOnly] + public NativeArray distanceDataArray; + [Unity.Collections.ReadOnly] + public NativeArray distanceDistanceArray; + + // buffer2 + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray tempVectorBufferA; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray tempVectorBufferB; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray tempCountBuffer; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray tempFloatBufferA; + + // バッチ内のローカルチームインデックスごと + // ワーカー分割 + public void Execute(int index) + { + // チームIDとワーカーID + int localIndex = index / workerCount; + int workerIndex = index % workerCount; + + // 各ベースポインタ + TeamManager.TeamData* teamPt = (TeamManager.TeamData*)teamDataArray.GetUnsafeReadOnlyPtr(); + ClothParameters* paramPt = (ClothParameters*)parameterArray.GetUnsafeReadOnlyPtr(); + + int teamId = batchSelfTeamList[localIndex]; + ref var tdata = ref *(teamPt + teamId); + ref var param = ref *(paramPt + teamId); + + if (updateIndex >= tdata.updateCount) + return; + if (tdata.IsProcess == false) + return; + if (tdata.ParticleCount == 0) + return; + + // 範囲 + var chunk = MathUtility.GetWorkerChunk(tdata.particleChunk.dataLength, workerCount, workerIndex); + if (chunk.IsValid == false) + return; + + // コライダーコリジョン + if (tdata.UseColliderCount > 0 && param.colliderCollisionConstraint.mode == ColliderCollisionConstraint.Mode.Edge) + { + // Edgeコリジョン集計 + ColliderCollisionConstraint.SumEdgeConstraint( + //new DataChunk(0, tdata.particleChunk.dataLength), + chunk, + // team + ref tdata, + ref param, + // particle + ref nextPosArray, + ref frictionArray, + ref collisionNormalArray, + // buffer2 + ref tempVectorBufferA, + ref tempVectorBufferB, + ref tempCountBuffer, + ref tempFloatBufferA + ); + } + + // コライダー衝突後はパーティクルが乱れる可能性があるためもう一度距離制約で整える。 + // これは裏返り防止などに効果大。 + DistanceConstraint.SolverConstraint( + //new DataChunk(0, tdata.particleChunk.dataLength), + chunk, + simulationPower, + // team + ref tdata, + ref param, + // vmesh + ref attributes, + ref depthArray, + // particle + ref nextPosArray, + ref basePosArray, + ref velocityPosArray, + ref frictionArray, + // constraint + ref distanceIndexArray, + ref distanceDataArray, + ref distanceDistanceArray + ); + + // モーション制約はコライダーより優先 + MotionConstraint.SolverConstraint( + //new DataChunk(0, tdata.particleChunk.dataLength), + chunk, + // team + ref tdata, + ref param, + // vmesh + ref attributes, + ref depthArray, + // particle + ref basePosArray, + ref baseRotArray, + ref nextPosArray, + ref velocityPosArray, + ref frictionArray, + ref collisionNormalArray + ); + } + } + + /// + /// ■セルフコリジョンあり + /// 座標確定 + /// コライダーの後更新 + /// + [BurstCompile] + unsafe struct SplitStep_G_Self_Job : IJobParallelFor + { + public int workerCount; + public int updateIndex; + public float simulationDeltaTime; + + // team + [Unity.Collections.ReadOnly] + public NativeList batchSelfTeamList; + [Unity.Collections.ReadOnly] + public NativeArray teamDataArray; + [Unity.Collections.ReadOnly] + public NativeArray centerDataArray; + [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; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray oldPosArray; + [Unity.Collections.ReadOnly] + public NativeArray velocityPosArray; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray velocityArray; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray realVelocityArray; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray frictionArray; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray staticFrictionArray; + [Unity.Collections.ReadOnly] + public NativeArray collisionNormalArray; + + // collider + [Unity.Collections.ReadOnly] + public NativeArray colliderNowPositions; + [Unity.Collections.ReadOnly] + public NativeArray colliderNowRotations; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray colliderOldPositions; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray colliderOldRotations; + + // バッチ内のローカルチームインデックスごと + // ワーカー分割 + public void Execute(int index) + { + // チームIDとワーカーID + int localIndex = index / workerCount; + int workerIndex = index % workerCount; + + // 各ベースポインタ + TeamManager.TeamData* teamPt = (TeamManager.TeamData*)teamDataArray.GetUnsafeReadOnlyPtr(); + ClothParameters* paramPt = (ClothParameters*)parameterArray.GetUnsafeReadOnlyPtr(); + InertiaConstraint.CenterData* centerPt = (InertiaConstraint.CenterData*)centerDataArray.GetUnsafeReadOnlyPtr(); + + int teamId = batchSelfTeamList[localIndex]; + ref var tdata = ref *(teamPt + teamId); + ref var cdata = ref *(centerPt + teamId); + ref var param = ref *(paramPt + teamId); + + if (updateIndex >= tdata.updateCount) + return; + if (tdata.IsProcess == false) + return; + if (tdata.ParticleCount == 0) + return; + + // 範囲 + var chunk = MathUtility.GetWorkerChunk(tdata.particleChunk.dataLength, workerCount, workerIndex); + if (chunk.IsValid) + { + // 座標確定 + SimulationStepPostTeam( + chunk, + simulationDeltaTime, + // team + teamId, + ref tdata, + ref cdata, + ref param, + // vmesh + ref attributes, + ref depthArray, + // particle + ref oldPosArray, + ref velocityArray, + ref nextPosArray, + ref velocityPosArray, + ref frictionArray, + ref staticFrictionArray, + ref collisionNormalArray, + ref realVelocityArray + ); + } + + // コライダーの後更新 + var colChunk = MathUtility.GetWorkerChunk(tdata.colliderChunk.dataLength, workerCount, workerIndex); + if (colChunk.IsValid) + { + ColliderManager.SimulationEndStep( + colChunk, + // team + ref tdata, + // collider + ref colliderNowPositions, + ref colliderNowRotations, + ref colliderOldPositions, + ref colliderOldRotations + ); + } + } + } + + /// + /// ■セルフコリジョンなし + /// コライダーコリジョンEdge集計 + /// 距離 + /// モーション + /// 座標確定 + /// コライダーの後更新 + /// + [BurstCompile] + unsafe struct SplitStep_FG_NoSelf_Job : IJobParallelFor + { + public int workerCount; + public int updateIndex; + public float4 simulationPower; + public float simulationDeltaTime; + + // team + [Unity.Collections.ReadOnly] + public NativeList batchSelfTeamList; + [Unity.Collections.ReadOnly] + public NativeArray teamDataArray; + [Unity.Collections.ReadOnly] + public NativeArray centerDataArray; + [Unity.Collections.ReadOnly] + public NativeArray parameterArray; + + // vmesh + [Unity.Collections.ReadOnly] + public NativeArray attributes; + [Unity.Collections.ReadOnly] + public NativeArray depthArray; + + // particle + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray nextPosArray; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray oldPosArray; + [Unity.Collections.ReadOnly] + public NativeArray basePosArray; + [Unity.Collections.ReadOnly] + public NativeArray baseRotArray; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray velocityPosArray; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray velocityArray; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray realVelocityArray; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray frictionArray; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray staticFrictionArray; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray collisionNormalArray; + + // collider + [Unity.Collections.ReadOnly] + public NativeArray colliderNowPositions; + [Unity.Collections.ReadOnly] + public NativeArray colliderNowRotations; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray colliderOldPositions; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray colliderOldRotations; + + // distance + [Unity.Collections.ReadOnly] + public NativeArray distanceIndexArray; + [Unity.Collections.ReadOnly] + public NativeArray distanceDataArray; + [Unity.Collections.ReadOnly] + public NativeArray distanceDistanceArray; + + // buffer2 + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray tempVectorBufferA; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray tempVectorBufferB; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray tempCountBuffer; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray tempFloatBufferA; + + // バッチ内のローカルチームインデックスごと + // ワーカー分割 + public void Execute(int index) + { + // チームIDとワーカーID + int localIndex = index / workerCount; + int workerIndex = index % workerCount; + + // 各ベースポインタ + TeamManager.TeamData* teamPt = (TeamManager.TeamData*)teamDataArray.GetUnsafeReadOnlyPtr(); + ClothParameters* paramPt = (ClothParameters*)parameterArray.GetUnsafeReadOnlyPtr(); + InertiaConstraint.CenterData* centerPt = (InertiaConstraint.CenterData*)centerDataArray.GetUnsafeReadOnlyPtr(); + + int teamId = batchSelfTeamList[localIndex]; + ref var tdata = ref *(teamPt + teamId); + ref var cdata = ref *(centerPt + teamId); + ref var param = ref *(paramPt + teamId); + + if (updateIndex >= tdata.updateCount) + return; + if (tdata.IsProcess == false) + return; + if (tdata.ParticleCount == 0) + return; + + // 範囲 + var chunk = MathUtility.GetWorkerChunk(tdata.particleChunk.dataLength, workerCount, workerIndex); + if (chunk.IsValid) + { + // コライダーコリジョン + if (tdata.UseColliderCount > 0 && param.colliderCollisionConstraint.mode == ColliderCollisionConstraint.Mode.Edge) + { + // Edgeコリジョン集計 + ColliderCollisionConstraint.SumEdgeConstraint( + //new DataChunk(0, tdata.particleChunk.dataLength), + chunk, + // team + ref tdata, + ref param, + // particle + ref nextPosArray, + ref frictionArray, + ref collisionNormalArray, + // buffer2 + ref tempVectorBufferA, + ref tempVectorBufferB, + ref tempCountBuffer, + ref tempFloatBufferA + ); + } + + // コライダー衝突後はパーティクルが乱れる可能性があるためもう一度距離制約で整える。 + // これは裏返り防止などに効果大。 + DistanceConstraint.SolverConstraint( + //new DataChunk(0, tdata.particleChunk.dataLength), + chunk, + simulationPower, + // team + ref tdata, + ref param, + // vmesh + ref attributes, + ref depthArray, + // particle + ref nextPosArray, + ref basePosArray, + ref velocityPosArray, + ref frictionArray, + // constraint + ref distanceIndexArray, + ref distanceDataArray, + ref distanceDistanceArray + ); + + // モーション制約はコライダーより優先 + MotionConstraint.SolverConstraint( + //new DataChunk(0, tdata.particleChunk.dataLength), + chunk, + // team + ref tdata, + ref param, + // vmesh + ref attributes, + ref depthArray, + // particle + ref basePosArray, + ref baseRotArray, + ref nextPosArray, + ref velocityPosArray, + ref frictionArray, + ref collisionNormalArray + ); + + // 座標確定 + SimulationStepPostTeam( + chunk, + simulationDeltaTime, + // team + teamId, + ref tdata, + ref cdata, + ref param, + // vmesh + ref attributes, + ref depthArray, + // particle + ref oldPosArray, + ref velocityArray, + ref nextPosArray, + ref velocityPosArray, + ref frictionArray, + ref staticFrictionArray, + ref collisionNormalArray, + ref realVelocityArray + ); + } + + // コライダーの後更新 + var colChunk = MathUtility.GetWorkerChunk(tdata.colliderChunk.dataLength, workerCount, workerIndex); + if (colChunk.IsValid) + { + ColliderManager.SimulationEndStep( + colChunk, + // team + ref tdata, + // collider + ref colliderNowPositions, + ref colliderNowRotations, + ref colliderOldPositions, + ref colliderOldRotations + ); + } + } + } + + /// + /// 表示位置の計算 + /// + [BurstCompile] + unsafe struct SplitPost_DisplayPos_Job : IJobParallelFor + { + public int workerCount; + public float simulationDeltaTime; + + // team + [Unity.Collections.ReadOnly] + public NativeList batchSelfTeamList; + [Unity.Collections.ReadOnly] + public NativeArray teamDataArray; + + // vmesh + [Unity.Collections.ReadOnly] + public NativeArray attributes; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray positions; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray rotations; + [Unity.Collections.ReadOnly] + public NativeArray vertexRootIndices; + + // particle + [Unity.Collections.ReadOnly] + public NativeArray oldPosArray; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray oldPositionArray; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray oldRotationArray; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray dispPosArray; + [Unity.Collections.ReadOnly] + public NativeArray realVelocityArray; + + // temp + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray tempVectorBufferA; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray tempRotationBufferA; + + // バッチ内のローカルチームインデックスごと + // ワーカー分割 + public void Execute(int index) + { + // チームIDとワーカーID + int localIndex = index / workerCount; + int workerIndex = index % workerCount; + + // 各ベースポインタ + TeamManager.TeamData* teamPt = (TeamManager.TeamData*)teamDataArray.GetUnsafeReadOnlyPtr(); + + int teamId = batchSelfTeamList[localIndex]; + ref var tdata = ref *(teamPt + teamId); + + if (tdata.IsProcess == false) + return; + if (tdata.ParticleCount == 0) + return; + + // ■表示位置の決定 + // 範囲 + var chunk = MathUtility.GetWorkerChunk(tdata.particleChunk.dataLength, workerCount, workerIndex); + //Debug.Log($"localIndex:{localIndex}, workerIndex:{workerIndex}, workerCount:{workerCount}, chun.s:{chunk.startIndex}, chun.l:{chunk.dataLength}"); + if (chunk.IsValid) + { + SimulationCalcDisplayPosition( + chunk, + simulationDeltaTime, + // team + ref tdata, + // particle + ref oldPosArray, + ref realVelocityArray, + ref oldPositionArray, + ref oldRotationArray, + ref dispPosArray, + // vmesh + ref attributes, + ref positions, + ref rotations, + ref vertexRootIndices, + // temp + ref tempVectorBufferA, + ref tempRotationBufferA + ); + } + } + } + + /// + /// クロスシミュレーションの結果をProxyMeshへ反映させる + /// ラインがある場合はベースラインごとに姿勢を整える + /// + [BurstCompile] + unsafe struct SplitPost_CalcProxy_Job : IJobParallelFor + { + public int workerCount; + + // team + [Unity.Collections.ReadOnly] + public NativeList batchSelfTeamList; + [Unity.Collections.ReadOnly] + public NativeArray teamDataArray; + [Unity.Collections.ReadOnly] + public NativeArray parameterArray; + + // vmesh + [Unity.Collections.ReadOnly] + public NativeArray attributes; + [Unity.Collections.ReadOnly] + public NativeArray positions; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray rotations; + [Unity.Collections.ReadOnly] + public NativeArray baseLineStartDataIndices; + [Unity.Collections.ReadOnly] + public NativeArray baseLineDataCounts; + [Unity.Collections.ReadOnly] + public NativeArray baseLineData; + [Unity.Collections.ReadOnly] + public NativeArray vertexLocalPositions; + [Unity.Collections.ReadOnly] + public NativeArray vertexLocalRotations; + [Unity.Collections.ReadOnly] + public NativeArray vertexChildIndexArray; + [Unity.Collections.ReadOnly] + public NativeArray vertexChildDataArray; + [Unity.Collections.ReadOnly] + public NativeArray baseLineFlags; + + // temp + [Unity.Collections.ReadOnly] + public NativeArray tempVectorBufferA; + [Unity.Collections.ReadOnly] + public NativeArray tempRotationBufferB; + + // バッチ内のローカルチームインデックスごと + // ワーカー分割 + public void Execute(int index) + { + // チームIDとワーカーID + int localIndex = index / workerCount; + int workerIndex = index % workerCount; + + // 各ベースポインタ + TeamManager.TeamData* teamPt = (TeamManager.TeamData*)teamDataArray.GetUnsafeReadOnlyPtr(); + ClothParameters* paramPt = (ClothParameters*)parameterArray.GetUnsafeReadOnlyPtr(); + + int teamId = batchSelfTeamList[localIndex]; + ref var tdata = ref *(teamPt + teamId); + ref var param = ref *(paramPt + teamId); + + if (tdata.IsProcess == false) + return; + if (tdata.ParticleCount == 0) + return; + + // ■クロスシミュレーション後の頂点姿勢計算 + // ラインがある場合はベースラインごとに姿勢を整える + // 範囲 + var chunk = MathUtility.GetWorkerChunk(tdata.baseLineChunk.dataLength, workerCount, workerIndex); + if (chunk.IsValid) + { + VirtualMeshManager.SimulationPostProxyMeshUpdateLine( + chunk, + // team + ref tdata, + ref param, + // vmesh + ref attributes, + ref positions, + ref rotations, + ref vertexLocalPositions, + ref vertexLocalRotations, + ref vertexChildIndexArray, + ref vertexChildDataArray, + ref baseLineFlags, + ref baseLineStartDataIndices, + ref baseLineDataCounts, + ref baseLineData, + // temp + ref tempVectorBufferA, + ref tempRotationBufferB + ); + } + } + } + + /// + /// トライアングルの法線接線を求める + /// + [BurstCompile] + unsafe struct SplitPost_CalcProxyTriangle_Job : IJobParallelFor + { + public int workerCount; + + // team + [Unity.Collections.ReadOnly] + public NativeList batchSelfTeamList; + [Unity.Collections.ReadOnly] + public NativeArray teamDataArray; + + // vmesh + [Unity.Collections.ReadOnly] + public NativeArray positions; + [Unity.Collections.ReadOnly] + public NativeArray triangles; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray triangleNormals; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray triangleTangents; + [Unity.Collections.ReadOnly] + public NativeArray uvs; + + // バッチ内のローカルチームインデックスごと + // ワーカー分割 + public void Execute(int index) + { + // チームIDとワーカーID + int localIndex = index / workerCount; + int workerIndex = index % workerCount; + + // 各ベースポインタ + TeamManager.TeamData* teamPt = (TeamManager.TeamData*)teamDataArray.GetUnsafeReadOnlyPtr(); + + int teamId = batchSelfTeamList[localIndex]; + ref var tdata = ref *(teamPt + teamId); + + if (tdata.IsProcess == false) + return; + if (tdata.ParticleCount == 0) + return; + + // ■クロスシミュレーション後の頂点姿勢計算 + // トライアングルの法線接線を求める + // 範囲 + var chunk = MathUtility.GetWorkerChunk(tdata.proxyTriangleChunk.dataLength, workerCount, workerIndex); + if (chunk.IsValid) + { + VirtualMeshManager.SimulationPostProxyMeshUpdateTriangle( + chunk, + // team + ref tdata, + // vmesh + ref positions, + ref triangles, + ref triangleNormals, + ref triangleTangents, + ref uvs + ); + } + } + } + + /// + /// トライアングルの法線接線から頂点の姿勢を求める + /// BoneClothの場合は頂点姿勢から連動するトランスフォームのワールド姿勢を計算する + /// + [BurstCompile] + unsafe struct SplitPost_SumProxyTriangleAndTransform_Job : IJobParallelFor + { + public int workerCount; + + // team + [Unity.Collections.ReadOnly] + public NativeList batchSelfTeamList; + [Unity.Collections.ReadOnly] + public NativeArray teamDataArray; + + // transform + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray transformPositionArray; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray transformRotationArray; + + // vmesh + [Unity.Collections.ReadOnly] + public NativeArray positions; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray rotations; + [Unity.Collections.ReadOnly] + public NativeArray triangleNormals; + [Unity.Collections.ReadOnly] + public NativeArray triangleTangents; + [Unity.Collections.ReadOnly] + public NativeArray> vertexToTriangles; + [Unity.Collections.ReadOnly] + public NativeArray normalAdjustmentRotations; + [Unity.Collections.ReadOnly] + public NativeArray vertexToTransformRotations; + + // バッチ内のローカルチームインデックスごと + // ワーカー分割 + public void Execute(int index) + { + // チームIDとワーカーID + int localIndex = index / workerCount; + int workerIndex = index % workerCount; + + // 各ベースポインタ + TeamManager.TeamData* teamPt = (TeamManager.TeamData*)teamDataArray.GetUnsafeReadOnlyPtr(); + + int teamId = batchSelfTeamList[localIndex]; + ref var tdata = ref *(teamPt + teamId); + + if (tdata.IsProcess == false) + return; + if (tdata.ParticleCount == 0) + return; + + // 範囲 + var chunk = MathUtility.GetWorkerChunk(tdata.proxyCommonChunk.dataLength, workerCount, workerIndex); + if (chunk.IsValid) + { + // ■クロスシミュレーション後の頂点姿勢計算 + // トライアングルの法線接線から頂点の姿勢を求める + VirtualMeshManager.SimulationPostProxyMeshUpdateTriangleSum( + chunk, + // team + ref tdata, + // vmesh + ref rotations, + ref triangleNormals, + ref triangleTangents, + ref vertexToTriangles, + ref normalAdjustmentRotations + ); + // BoneClothの場合は頂点姿勢から連動するトランスフォームのワールド姿勢を計算する + VirtualMeshManager.SimulationPostProxyMeshUpdateWorldTransform( + chunk, + // team + ref tdata, + // vmesh + ref positions, + ref rotations, + ref vertexToTransformRotations, + // transform + ref transformPositionArray, + ref transformRotationArray + ); + } + } + } + + /// + /// チーム更新後処理 + /// BoneClothの場合はTransformのローカル姿勢を計算する + /// コライダー更新後処理 + /// + [BurstCompile] + unsafe struct SplitPost_TeamCollider_Job : IJobParallelFor + { + public float simulationDeltaTime; + + // team + [Unity.Collections.ReadOnly] + public NativeList batchSelfTeamList; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray teamDataArray; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray centerDataArray; + + // collider + [Unity.Collections.ReadOnly] + public NativeArray colliderFramePositions; + [Unity.Collections.ReadOnly] + public NativeArray colliderFrameRotations; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray colliderOldFramePositions; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray colliderOldFrameRotations; + + // transform + [Unity.Collections.ReadOnly] + public NativeArray transformPositionArray; + [Unity.Collections.ReadOnly] + public NativeArray transformRotationArray; + [Unity.Collections.ReadOnly] + public NativeArray transformScaleArray; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray transformLocalPositionArray; + [NativeDisableParallelForRestriction] + [NativeDisableContainerSafetyRestriction] + public NativeArray transformLocalRotationArray; + + // vmesh + [Unity.Collections.ReadOnly] + public NativeArray attributes; + [Unity.Collections.ReadOnly] + public NativeArray vertexParentIndices; + + // バッチ内のローカルチームインデックスごと + public void Execute(int localIndex) + { + // 各ベースポインタ + TeamManager.TeamData* teamPt = (TeamManager.TeamData*)teamDataArray.GetUnsafePtr(); + InertiaConstraint.CenterData* centerPt = (InertiaConstraint.CenterData*)centerDataArray.GetUnsafePtr(); + + int teamId = batchSelfTeamList[localIndex]; + ref var tdata = ref *(teamPt + teamId); + ref var cdata = ref *(centerPt + teamId); + + if (tdata.IsProcess == false) + return; + if (tdata.ParticleCount == 0) + return; + + // BoneClothの場合はTransformのローカル姿勢を計算する + VirtualMeshManager.SimulationPostProxyMeshUpdateLocalTransform( + // team + ref tdata, + // vmesh + ref attributes, + ref vertexParentIndices, + // transform + ref transformPositionArray, + ref transformRotationArray, + ref transformScaleArray, + ref transformLocalPositionArray, + ref transformLocalRotationArray + ); + + // ■コライダー更新後処理 + ColliderManager.SimulationPostUpdate( + // team + ref tdata, + // collider + ref colliderFramePositions, + ref colliderFrameRotations, + ref colliderOldFramePositions, + ref colliderOldFrameRotations + ); + + // ■チーム更新後処理 + TeamManager.SimulationPostTeamUpdate( + // team + ref tdata, + ref cdata + ); + } + } + } +} + diff --git a/Assets/MagicaCloth2/Scripts/Core/Manager/Simulation/SimulationManagerSplit.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Manager/Simulation/SimulationManagerSplit.cs.meta new file mode 100644 index 00000000..be6953bd --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Manager/Simulation/SimulationManagerSplit.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 2dd0faec9645ac1499b7eceb32ba4f10 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Manager/Simulation/SimulationManagerSplit.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Manager/Simulation/TimeManager.cs b/Assets/MagicaCloth2/Scripts/Core/Manager/Simulation/TimeManager.cs new file mode 100644 index 00000000..bcd979e0 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Manager/Simulation/TimeManager.cs @@ -0,0 +1,159 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using System.Text; +using Unity.Mathematics; +using UnityEngine; + +namespace MagicaCloth2 +{ + public class TimeManager : IManager, IValid + { + /// + /// シミュレーションの更新周期 + /// 1ステップで(1.0 / simulationFrequency)時間進みます + /// + internal int simulationFrequency = Define.System.DefaultSimulationFrequency; + + /// + /// 1フレームに実行される最大シミュレーション回数 + /// + internal int maxSimulationCountPerFrame = Define.System.DefaultMaxSimulationCountPerFrame; + + /// + /// マネージャの更新場所 + /// + public enum UpdateLocation + { + AfterLateUpdate = 0, + BeforeLateUpdate = 1, + } + internal UpdateLocation updateLocation = UpdateLocation.AfterLateUpdate; + + //========================================================================================= + bool isValid = false; + + /// + /// フレームのFixedUpdate回数 + /// + internal int FixedUpdateCount { get; private set; } + + /// + /// グローバルタイムスケール(0.0 ~ 1.0) + /// + internal float GlobalTimeScale = 1.0f; + + /// + /// シミュレーション1回の時間 + /// + internal float SimulationDeltaTime { get; private set; } + + /// + /// 1フレームの最大更新時間 + /// + internal float MaxDeltaTime { get; private set; } + + /// + /// 制約解決係数(周波数により変動) + /// + internal float4 SimulationPower { get; private set; } + + //========================================================================================= + public void Dispose() + { + isValid = true; + + GlobalTimeScale = 1.0f; + FixedUpdateCount = 0; + SimulationPower = 1.0f; + + MagicaManager.afterFixedUpdateDelegate -= AfterFixedUpdate; + MagicaManager.afterRenderingDelegate -= AfterRenderring; + } + + public void EnterdEditMode() + { + Dispose(); + } + + public void Initialize() + { + GlobalTimeScale = 1.0f; + FixedUpdateCount = 0; + SimulationPower = 1.0f; + + MagicaManager.afterFixedUpdateDelegate += AfterFixedUpdate; + MagicaManager.afterRenderingDelegate += AfterRenderring; + + isValid = true; + } + + public bool IsValid() + { + return isValid; + } + + //========================================================================================= + void AfterFixedUpdate() + { + //Debug.Log($"AfterFixedUpdate. F:{Time.frameCount}"); + FixedUpdateCount++; + } + + void AfterRenderring() + { + //Debug.Log($"AfterRenderring. F:{Time.frameCount}"); + FixedUpdateCount = 0; + } + + //========================================================================================= + internal void FrameUpdate() + { + simulationFrequency = Mathf.Clamp(simulationFrequency, Define.System.SimulationFrequency_Low, Define.System.SimulationFrequency_Hi); + maxSimulationCountPerFrame = Mathf.Clamp(maxSimulationCountPerFrame, Define.System.MaxSimulationCountPerFrame_Low, Define.System.MaxSimulationCountPerFrame_Hi); + GlobalTimeScale = Mathf.Clamp01(GlobalTimeScale); + + // 1ステップのシミュレーション更新時間 + SimulationDeltaTime = 1.0f / simulationFrequency; + + // 1フレームの最大更新時間 + MaxDeltaTime = SimulationDeltaTime * maxSimulationCountPerFrame; + + // 制約解決係数 + float t = Define.System.DefaultSimulationFrequency / (float)simulationFrequency; + SimulationPower = new float4( + t, // (3.0 ~ 1.0 ~ 0.6) + t > 1.0f ? Mathf.Pow(t, 0.5f) : t, // (1.73 ~ 1.0 ~ 0.6) + t > 1.0f ? Mathf.Pow(t, 0.3f) : t, // (1.39 ~ 1.0 ~ 0.6) + //Mathf.Pow(t, 1.5f) // (5.19 ~ 1.0 ~ 0.46) + Mathf.Pow(t, 1.8f) // (7.22 ~ 1.0 ~ 0.39) + ); + //Debug.Log($"SimulationPower:{SimulationPower}"); + } + + //========================================================================================= + public void InformationLog(StringBuilder allsb) + { + StringBuilder sb = new StringBuilder(); + + sb.AppendLine($"========== Time Manager =========="); + if (IsValid() == false) + { + sb.AppendLine($"Time Manager. Invalid"); + } + else + { + sb.AppendLine($"SimulationFrequency:{simulationFrequency}"); + sb.AppendLine($"MaxSimulationCountPerFrame:{maxSimulationCountPerFrame}"); + sb.AppendLine($"GlobalTimeScale:{GlobalTimeScale}"); + sb.AppendLine($"SimulationDeltaTime:{SimulationDeltaTime}"); + //sb.AppendLine($"MaxDeltaTime:{MaxDeltaTime}"); + sb.AppendLine($"SimulationPower:{SimulationPower}"); + } + sb.AppendLine(); + + Debug.Log(sb.ToString()); + allsb.Append(sb); + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/Manager/Simulation/TimeManager.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Manager/Simulation/TimeManager.cs.meta new file mode 100644 index 00000000..661f85de --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Manager/Simulation/TimeManager.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: e34158b4ab7aaea4b804388730e4f309 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Manager/Simulation/TimeManager.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Manager/Simulation/WindManager.cs b/Assets/MagicaCloth2/Scripts/Core/Manager/Simulation/WindManager.cs new file mode 100644 index 00000000..b7c175e0 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Manager/Simulation/WindManager.cs @@ -0,0 +1,229 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using System.Collections.Generic; +using System.Text; +using Unity.Collections; +using Unity.Mathematics; +using UnityEngine; + +namespace MagicaCloth2 +{ + /// + /// 風ゾーン管理マネージャ + /// + public class WindManager : IManager, IValid + { + public const int Flag_Valid = 0; // データの有効性 + public const int Flag_Enable = 1; // 動作状態 + public const int Flag_Addition = 2; // 加算風 + + /// + /// 風ゾーンの管理データ + /// + public struct WindData + { + public BitField32 flag; + + public MagicaWindZone.Mode mode; + + /// + /// Global:(none) + /// Box :(x, y, z) + /// Sphere:(radius, radius, radius) + /// + public float3 size; + + public float main; + public float turbulence; + public float zoneVolume; + + public float3 worldWindDirection; + + public float3 worldPositin; + public quaternion worldRotation; + public float3 worldScale; + public float4x4 worldToLocalMatrix; + public float4x4 attenuation; + + public bool IsValid() => flag.IsSet(Flag_Valid); + public bool IsEnable() => flag.IsSet(Flag_Enable); + public bool IsAddition() => flag.IsSet(Flag_Addition); + } + public ExNativeArray windDataArray; + + public int WindCount => windDataArray?.Count ?? 0; + + bool isValid; + + /// + /// WindIDとゾーンコンポーネントの関連辞書 + /// + Dictionary windZoneDict = new Dictionary(); + + //========================================================================================= + public void Dispose() + { + isValid = false; + + windDataArray?.Dispose(); + } + + public void EnterdEditMode() + { + Dispose(); + } + + public void Initialize() + { + Dispose(); + + const int capacity = 64; + windDataArray = new ExNativeArray(capacity); + + isValid = true; + } + + public bool IsValid() + { + return isValid; + } + + //========================================================================================= + public int AddWind(MagicaWindZone windZone) + { + if (isValid == false || windZone == null) + return -1; + + var wind = new WindData(); + // ★Enableフラグは立てない + wind.flag.SetBits(Flag_Valid, true); + var c = windDataArray.Add(wind); + + windZoneDict.Add(c.startIndex, windZone); + + return c.startIndex; + } + + public void RemoveWind(int windId) + { + if (isValid == false || windId < 0) + return; + + var c = new DataChunk(windId); + windDataArray.RemoveAndFill(c); + + windZoneDict.Remove(c.startIndex); + } + + public void SetEnable(int windId, bool sw) + { + if (isValid == false || windId < 0) + return; + + var wind = windDataArray[windId]; + wind.flag.SetBits(Flag_Enable, sw); + windDataArray[windId] = wind; + } + + //========================================================================================= + /// + /// 毎フレーム常に実行する更新 + /// + internal void AlwaysWindUpdate() + { + // ジョブでは実行できない風ゾーンの更新 + foreach (var kv in windZoneDict) + { + int windId = kv.Key; + var windZone = kv.Value; + + if (windId < 0 || windZone == null) + continue; + + var t = windZone.transform; + + // コンポーネントデータのコピー + ref var wind = ref windDataArray.GetRef(windId); + wind.mode = windZone.mode; + switch (windZone.mode) + { + case MagicaWindZone.Mode.BoxDirection: + wind.size = windZone.size; + break; + case MagicaWindZone.Mode.SphereDirection: + case MagicaWindZone.Mode.SphereRadial: + wind.size = windZone.radius; + break; + } + wind.main = windZone.main; + wind.turbulence = windZone.turbulence; + + wind.flag.SetBits(Flag_Addition, windZone.IsAddition()); + + wind.worldPositin = t.position; + wind.worldRotation = t.rotation; + wind.worldScale = t.lossyScale; + wind.worldToLocalMatrix = t.worldToLocalMatrix; + + // volume + float volume = 0; + switch (wind.mode) + { + case MagicaWindZone.Mode.GlobalDirection: + volume = float.MaxValue; + break; + case MagicaWindZone.Mode.BoxDirection: + float3 gsize = wind.size * wind.worldScale; + volume = gsize.x * gsize.y * gsize.z; + break; + case MagicaWindZone.Mode.SphereDirection: + case MagicaWindZone.Mode.SphereRadial: + float r = wind.size.x * wind.worldScale.x; + volume = (4.0f / 3.0f) * r * r * r * math.PI; + break; + } + wind.zoneVolume = volume; + + if (windZone.IsDirection()) + { + wind.worldWindDirection = windZone.GetWindDirection(); + //Debug.Log($"wdir:{wind.worldWindDirection}"); + } + else + { + // 減衰カーブ + wind.attenuation = DataUtility.ConvertAnimationCurve(windZone.attenuation); + } + } + } + + //========================================================================================= + public void InformationLog(StringBuilder allsb) + { + StringBuilder sb = new StringBuilder(); + sb.AppendLine($"========== Wind Manager =========="); + if (IsValid() == false) + { + sb.AppendLine($"Wind Manager. Invalid."); + } + else + { + sb.AppendLine($"Wind Manager. Count:{WindCount}"); + + int cnt = WindCount; + for (int i = 0; i < cnt; i++) + { + var wind = windDataArray[i]; + if (wind.flag.IsSet(Flag_Valid) == false) + continue; + + sb.AppendLine($" [{i}] flag:0x{wind.flag.Value:X}, mode:{wind.mode}"); + } + } + sb.AppendLine(); + Debug.Log(sb.ToString()); + allsb.Append(sb); + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/Manager/Simulation/WindManager.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Manager/Simulation/WindManager.cs.meta new file mode 100644 index 00000000..6ebc7b0f --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Manager/Simulation/WindManager.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 410a565210adcf54b96e6427d86b73c1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Manager/Simulation/WindManager.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Manager/Team.meta b/Assets/MagicaCloth2/Scripts/Core/Manager/Team.meta new file mode 100644 index 00000000..3bce14b7 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Manager/Team.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 324a054fc120e7940ab9c3d891b57338 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/MagicaCloth2/Scripts/Core/Manager/Team/TeamManager.cs b/Assets/MagicaCloth2/Scripts/Core/Manager/Team/TeamManager.cs new file mode 100644 index 00000000..b2afc2e3 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Manager/Team/TeamManager.cs @@ -0,0 +1,2926 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +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 Unity.Profiling; +using UnityEngine; + +namespace MagicaCloth2 +{ + public class TeamManager : IManager, IValid + { + /// + /// チームフラグ(64bit) + /// + public const int Flag_Valid = 0; // データの有効性 + public const int Flag_Enable = 1; // 動作状態 + public const int Flag_Reset = 2; // 姿勢リセット + public const int Flag_TimeReset = 3; // 時間リセット + public const int Flag_SyncSuspend = 4; // 同期待ち一時停止 + public const int Flag_Running = 5; // 今回のフレームでシミュレーションが実行されたかどうか + public const int Flag_Synchronization = 6; // 同期中 + public const int Flag_StepRunning = 7; // ステップ実行中 + public const int Flag_Exit = 8; // 存在消滅時 + public const int Flag_KeepTeleport = 9; // 姿勢保持テレポート + public const int Flag_InertiaShift = 10; // 慣性全体シフト + public const int Flag_CameraCullingInvisible = 11; // カメラカリングによる非表示状態 + public const int Flag_CameraCullingKeep = 12; // カメラカリング時に姿勢を保つ + public const int Flag_Spring = 13; // Spring利用 + public const int Flag_SkipWriting = 14; // 書き込み停止(ストップモーション用) + public const int Flag_Anchor = 15; // Inertia anchorを利用中 + public const int Flag_AnchorReset = 16; // Inertia anchorの座標リセット + public const int Flag_NegativeScale = 17; // マイナススケールの有無 + public const int Flag_NegativeScaleTeleport = 18; // マイナススケールによるテレポート + public const int Flag_DistanceCullingInvisible = 19; // 距離カリングによる非表示状態 + public const int Flag_RestoreTransformOnlyOnec = 20; // Transform復元を一度のみ実行する(BoneClothのDisable時) + public const int Flag_Tangent = 21; // 接線を計算する + public const int Flag_ScaleSuspent = 22; // 極小スケールによる機能停止 + public const int Flag_ProxyMeshLine = 23; // プロキシメッシュにLineデータが存在する + + // 以下セルフコリジョン + // !これ以降の順番を変えないこと + public const int Flag_Self_PointPrimitive = 32; // PointPrimitive+Sortを保持し更新する + public const int Flag_Self_EdgePrimitive = 33; // EdgePrimitive+Sortを保持し更新する + public const int Flag_Self_TrianglePrimitive = 34; // TrianglePrimitive+Sortを保持し更新する + + public const int Flag_Self_EdgeEdge = 35; + public const int Flag_Sync_EdgeEdge = 36; + public const int Flag_PSync_EdgeEdge = 37; + + public const int Flag_Self_PointTriangle = 38; + public const int Flag_Sync_PointTriangle = 39; + public const int Flag_PSync_PointTriangle = 40; + + public const int Flag_Self_TrianglePoint = 41; + public const int Flag_Sync_TrianglePoint = 42; + public const int Flag_PSync_TrianglePoint = 43; + + public const int Flag_Self_EdgeTriangleIntersect = 44; + public const int Flag_Sync_EdgeTriangleIntersect = 45; + public const int Flag_PSync_EdgeTriangleIntersect = 46; + public const int Flag_Self_TriangleEdgeIntersect = 47; + public const int Flag_Sync_TriangleEdgeIntersect = 48; + public const int Flag_PSync_TriangleEdgeIntersect = 49; + + /// + /// チーム基本データ + /// + public struct TeamData + { + /// + /// フラグ + /// + public BitField64 flag; + + /// + /// 更新モード(オリジナル) + /// + public ClothUpdateMode originalUpdateMode; + + /// + /// 更新モード(最終結果) + /// + public ClothUpdateMode updateMode; + + /// + /// 1秒間の更新頻度 + /// + //public int frequency; + + /// + /// 現在フレームの更新時間 + /// + public float frameDeltaTime; + + /// + /// 更新計算用時間 + /// + public float time; + + /// + /// 前フレームの更新計算用時間 + /// + public float oldTime; + + /// + /// 現在のシミュレーション更新時間 + /// + public float nowUpdateTime; + + /// + /// 1つ前の最後のシミュレーション更新時間 + /// + public float oldUpdateTime; + + /// + /// 更新がある場合のフレーム時間 + /// + public float frameUpdateTime; + + /// + /// 前回更新のフレーム時間 + /// + public float frameOldTime; + + /// + /// チーム固有のタイムスケール(0.0-1.0) + /// + public float timeScale; + + /// + /// チームの最終計算用タイムスケール(0.0~1.0) + /// グローバルタイムスケールなどを考慮した値 + /// + public float nowTimeScale; + + /// + /// 今回のチーム更新回数(0ならばこのフレームは更新なし) + /// + public int updateCount; + + /// + /// 今回のチーム更新スキップ回数(1以上ならばシミュレーションスキップが発生) + /// + public int skipCount; + + /// + /// ステップごとのフレームに対するnowUpdateTime割合 + /// これは(frameStartTime ~ time)間でのnowUpdateTimeの割合 + /// + public float frameInterpolation; + + /// + /// 重力の影響力(0.0 ~ 1.0) + /// 1.0は重力が100%影響する + /// + public float gravityRatio; + + public float gravityDot; + + /// + /// センタートランスフォーム(ダイレクト値) + /// + public int centerTransformIndex; + + /// + /// 現在の中心ワールド座標(この値はCenterData.nowWorldPositionのコピー) + /// + //public float3 centerWorldPosition; + + /// + /// アンカーとして設定されているTransformのインスタンスID(0=なし) + /// + //public int anchorTransformId; + + /// + /// 距離カリングの測定オブジェクトID(0=メインカメラ) + /// + public int distanceReferenceObjectId; + + /// + /// コンポーネント用のTransformインデックス + /// + public int componentTransformIndex; + + /// + /// チームスケール + /// + public float3 initScale; // データ生成時のセンタートランスフォームスケール + public float scaleRatio; // 現在のスケール倍率 + + /// + /// マイナススケール + /// + public float negativeScaleSign; // マイナススケールの有無(1:正スケール, -1:マイナススケール) + public float3 negativeScaleDirection; // スケール方向(xyz):(1:正スケール, -1:マイナススケール) + public float3 negativeScaleChange; // 今回のフレームで変化したスケール(xyz):(1:変化なし, -1:反転した) + public float2 negativeScaleTriangleSign; // トライアングル法線接線フリップフラグ + public float4 negativeScaleQuaternionValue; // クォータニオン反転用 + + /// + /// MagicaClothコンポーネントのインスタンスID + /// + //public int componentId; + public MagicaObjectId componentId; + + /// + /// 同期チームID(0=なし) + /// + public int syncTeamId; + + /// + /// 自身を同期している親チームID(0=なし):最大7つ + /// + public FixedList32Bytes syncParentTeamId; + + /// + /// 同期先チームのセンタートランスフォームインデックス(ダイレクト値) + /// + public int syncCenterTransformIndex; + + /// + /// 連動するAnimatorのインスタンスID(0=なし) + /// + //public int interlockingAnimatorId; + public MagicaObjectId interlockingAnimatorId; + + /// + /// 初期姿勢とアニメーション姿勢のブレンド率(制約で利用) + /// + public float animationPoseRatio; + + /// + /// 速度安定時間(StablizationTime)による速度適用割合(0.0 ~ 1.0) + /// + public float velocityWeight; + + /// + /// 距離カリングによるブレンド割合(0.0 ~ 1.0) + /// + public float distanceWeight; + + /// + /// 最終シミュレーション結果ブレンド割合(0.0 ~ 1.0) + /// + public float blendWeight; + + /// + /// 外力モード + /// + public ClothForceMode forceMode; + + /// + /// 外力 + /// + public float3 impactForce; + + //----------------------------------------------------------------- + /// + /// ProxyMeshのタイプ + /// + public VirtualMesh.MeshType proxyMeshType; + + /// + /// ProxyMeshのTransformデータ + /// + public DataChunk proxyTransformChunk; + + /// + /// ProxyMeshの共通部分 + /// -attributes + /// -vertexToTriangles + /// -vertexToVertexIndexArray + /// -vertexDepths + /// -vertexLocalPositions + /// -vertexLocalRotations + /// -vertexRootIndices + /// -vertexParentIndices + /// -vertexChildIndexArray + /// -vertexAngleCalcLocalRotations + /// -uv + /// -positions + /// -rotations + /// -vertexBindPosePositions + /// -vertexBindPoseRotations + /// -normalAdjustmentRotations + /// + public DataChunk proxyCommonChunk; + + /// + /// ProxyMeshの頂点接続頂点データ + /// -vertexToVertexDataArray (-vertexToVertexIndexArrayと対) + /// + //public DataChunk proxyVertexToVertexDataChunk; + + /// + /// ProxyMeshの子頂点データ + /// -vertexChildDataArray (-vertexChildIndexArrayと対) + /// + public DataChunk proxyVertexChildDataChunk; + + /// + /// ProxyMeshのTriangle部分 + /// -triangles + /// -triangleTeamIdArray + /// -triangleNormals + /// -triangleTangents + /// + public DataChunk proxyTriangleChunk; + + /// + /// ProxyMeshのEdge部分 + /// -edges + /// -edgeTeamIdArray + /// + public DataChunk proxyEdgeChunk; + + /// + /// ProxyMeshのBoneCloth/MeshCloth共通部分 + /// -localPositions + /// -localNormals + /// -localTangents + /// -boneWeights + /// + public DataChunk proxyMeshChunk; + + /// + /// ProxyMeshのBoneCloth固有部分 + /// -vertexToTransformRotations + /// + public DataChunk proxyBoneChunk; + + /// + /// ProxyMeshのMeshClothのスキニングボーン部分 + /// -skinBoneTransformIndices + /// -skinBoneBindPoses + /// + public DataChunk proxySkinBoneChunk; + + /// + /// ProxyMeshのベースライン部分 + /// -baseLineFlags + /// -baseLineStartDataIndices + /// -baseLineDataCounts + /// + public DataChunk baseLineChunk; + + /// + /// ProxyMeshのベースラインデータ配列 + /// -baseLineData + /// + public DataChunk baseLineDataChunk; + + /// + /// 固定点リスト + /// + public DataChunk fixedDataChunk; + + //----------------------------------------------------------------- + /// + /// 接続しているマッピングメッシュへデータへのインデックスセット(最大15まで) + /// + //public FixedList32Bytes mappingDataIndexSet; + + //----------------------------------------------------------------- + /// + /// パーティクルデータ + /// + public DataChunk particleChunk; + + /// + /// コライダーデータ + /// コライダーが有効の場合は未使用であっても最大数まで確保される + /// + public DataChunk colliderChunk; + + /// + /// コライダートランスフォーム + /// コライダーが有効の場合は未使用であっても最大数まで確保される + /// + public DataChunk colliderTransformChunk; + + /// + /// 現在有効なコライダー数 + /// + public int colliderCount; + + //----------------------------------------------------------------- + /// + /// 距離制約 + /// + public DataChunk distanceStartChunk; + public DataChunk distanceDataChunk; + + /// + /// 曲げ制約 + /// + public DataChunk bendingPairChunk; + + /// + /// セルフコリジョン制約 + /// + public DataChunk selfPointChunk; + public DataChunk selfEdgeChunk; + public DataChunk selfTriangleChunk; + public float selfGridSize; + public int selfPointGridCount; + public int selfEdgeGridCount; + public int selfTriangleGridCount; + public float selfMaxPrimitiveSize; + + //----------------------------------------------------------------- + /// + /// UnityPhysicsでの更新の必要性 + /// + public bool IsFixedUpdate => updateMode == ClothUpdateMode.UnityPhysics; + + /// + /// タイムスケールを無視 + /// + public bool IsUnscaled => updateMode == ClothUpdateMode.Unscaled; + + /// + /// 1回の更新間隔 + /// + //public float SimulationDeltaTime => 1.0f / frequency; + + /// + /// データの有効性 + /// + public bool IsValid => flag.IsSet(Flag_Valid); + + /// + /// 有効状態 + /// + public bool IsEnable => flag.IsSet(Flag_Enable); + + /// + /// 処理状態 + /// + public bool IsProcess => IsEnable && flag.IsSet(Flag_SyncSuspend) == false && IsCullingInvisible == false && IsScaleSuspend == false; + + /// + /// 姿勢リセット有無 + /// + public bool IsReset => flag.IsSet(Flag_Reset); + + /// + /// 姿勢維持テレポートの有無 + /// + public bool IsKeepReset => flag.IsSet(Flag_KeepTeleport); + + /// + /// 慣性全体シフトの有無 + /// + public bool IsInertiaShift => flag.IsSet(Flag_InertiaShift); + + /// + /// 今回のフレームでシミュレーションが実行されたかどうか(1回以上実行された場合) + /// + public bool IsRunning => flag.IsSet(Flag_Running); + + /// + /// ステップ実行中かどうか + /// + public bool IsStepRunning => flag.IsSet(Flag_StepRunning); + + public bool IsCameraCullingInvisible => flag.IsSet(Flag_CameraCullingInvisible); + public bool IsCameraCullingKeep => flag.IsSet(Flag_CameraCullingKeep); + public bool IsDistanceCullingInvisible => flag.IsSet(Flag_DistanceCullingInvisible); + public bool IsCullingInvisible => IsCameraCullingInvisible || IsDistanceCullingInvisible; + public bool IsSpring => flag.IsSet(Flag_Spring); + public bool IsNegativeScale => flag.IsSet(Flag_NegativeScale); + public bool IsNegativeScaleTeleport => flag.IsSet(Flag_NegativeScaleTeleport); + public bool IsTangent => flag.IsSet(Flag_Tangent); + public bool IsScaleSuspend => flag.IsSet(Flag_ScaleSuspent); + public int ParticleCount => particleChunk.dataLength; + + /// + /// 現在有効なコライダー数 + /// + public int UseColliderCount => colliderCount; + public int BaseLineCount => baseLineChunk.dataLength; + public int TriangleCount => proxyTriangleChunk.dataLength; + public int EdgeCount => proxyEdgeChunk.dataLength; + + //public int MappingCount => mappingDataIndexSet.Length; + + /// + /// 初期スケール(x軸のみで判定、一様スケールしか認めていない) + /// + public float InitScale => initScale.x; + } + public ExNativeArray teamDataArray; + + /// + /// チームごとの風の影響情報 + /// + public ExNativeArray teamWindArray; + + /// + /// マッピングメッシュデータフラグ + /// + public const int MappingDataFlag_ChangePositionNormal = 0; + public const int MappingDataFlag_ChangeTangent = 1; + public const int MappingDataFlag_ChangeBoneWeight = 2; + public const int MappingDataFlag_ModifyBoneWeight = 3; + + /// + /// マッピングメッシュデータ + /// + public struct MappingData : IValid + { + public int teamId; + + /// + /// 状態フラグ + /// + public BitField32 flag; + + /// + /// Mappingメッシュのセンタートランスフォーム(ダイレクト値) + /// + public int centerTransformIndex; + + /// + /// Mappingメッシュの基本 + /// -attributes + /// -localPositions + /// -localNormlas + /// -localTangents + /// -boneWeights + /// -positions + /// -rotations + /// + public DataChunk mappingCommonChunk; + + /// + /// 初期状態でのプロキシメッシュへの変換マトリックスと変換回転 + /// この姿勢は初期化時に固定される + /// + public float4x4 toProxyMatrix; + public quaternion toProxyRotation; + + /// + /// プロキシメッシュとマッピングメッシュの座標空間が同じかどうか + /// + public bool sameSpace; + + /// + /// プロキシメッシュからマッピングメッシュへの座標空間変換用 + /// ▲ワールド対応:ここはワールド空間からマッピングメッシュへの座標変換となる + /// + public float4x4 toMappingMatrix; + public quaternion toMappingRotation; + + /// + /// Mappingメッシュ用のスケーリング比率 + /// + public float scaleRatio; + + /// + /// 紐づけられているRenderDataWorkバッファへのインデックス + /// + public int renderDataWorkIndex; + + public bool IsValid() + { + return teamId > 0; + } + + public int VertexCount => mappingCommonChunk.dataLength; + } + public ExNativeArray mappingDataArray; + + /// + /// チームごとのマッピングメッシュIDリスト(チームごとに最大31まで) + /// + public ExNativeArray> teamMappingIndexArray; + + /// + /// チーム全体の集計データ + /// x:最大更新回数 + /// y:分割ジョブチームのPointコリジョンの数 + /// z:分割ジョブチームのEdgeコリジョンの数 + /// w:分割ジョブチームのSelfコリジョンの数 + /// + public NativeReference teamStatus; + + /// + /// パラメータ(teamDataArrayとインデックス連動) + /// + public ExNativeArray parameterArray; + + /// + /// センタートランスフォームデータ + /// + public ExNativeArray centerDataArray; + + /// + /// 登録されているマッピングメッシュ数 + /// + public int MappingCount => mappingDataArray?.Count ?? 0; + + /// + /// チームの有効状態を別途記録 + /// NativeArrayはジョブ実行中にアクセスできないため。 + /// + HashSet enableTeamSet = new HashSet(); + + /// + /// チームIDとClothProcessクラスの関連辞書 + /// + Dictionary clothProcessDict = new Dictionary(); + + //========================================================================================= + /// + /// 登録されているチーム数(グローバルチームを含む。そのため0にはならない) + /// + public int TeamCount => teamDataArray?.Count ?? 0; + + /// + /// 登録されている有効なチーム数(グローバルチームを含まない) + /// + public int TrueTeamCount => clothProcessDict.Count; + + /// + /// 実行状態にあるチーム数 + /// + public int ActiveTeamCount => enableTeamSet.Count; + + /// + /// 今回フレームでのチーム全体の最大更新回数 + /// + public int TeamMaxUpdateCount => teamStatus.Value.x; + + //========================================================================================= + // ■作業データ + bool isValid; + + /// + /// エッジコライダーコリジョンのエッジ数合計 + /// + internal int edgeColliderCollisionCount; + + internal NativeReference edgeColliderCollisionCountBuff; + internal NativeParallelHashMap comp2SuspendCounterMap; + internal NativeParallelHashMap comp2TeamIdMap; + internal NativeParallelHashMap comp2SyncPartnerCompMap; + internal NativeParallelHashMap comp2SyncTopCompMap; + + internal NativeList batchNormalClothTeamList; + internal NativeList batchSplitClothTeamList; + + internal List parameterDirtyList; + internal List skipWritingDirtyList; + internal NativeList cullingDirtyList; + internal NativeParallelHashSet selfCollisionUpdateSet; + internal NativeParallelHashMap animatorUpdateModeMap; + + internal ExSimpleNativeArray teamAnchorTransformIndexArray; + internal ExSimpleNativeArray teamDistanceTransformIndexArray; + internal NativeParallelHashMap transformPositionMap; + internal NativeParallelHashMap transformRotationMap; + + internal HashSet cameraCullingClothSet = new HashSet(256); + + //========================================================================================= + public void Dispose() + { + // 破棄監視リストの強制処理 + MonitoringProcess(true); + + isValid = false; + + teamDataArray?.Dispose(); + teamWindArray?.Dispose(); + mappingDataArray?.Dispose(); + teamMappingIndexArray?.Dispose(); + parameterArray?.Dispose(); + centerDataArray?.Dispose(); + + teamDataArray = null; + teamWindArray = null; + mappingDataArray = null; + teamMappingIndexArray = null; + parameterArray = null; + centerDataArray = null; + + if (teamStatus.IsCreated) + teamStatus.Dispose(); + + enableTeamSet.Clear(); + clothProcessDict.Clear(); + + if (edgeColliderCollisionCountBuff.IsCreated) + edgeColliderCollisionCountBuff.Dispose(); + comp2SuspendCounterMap.MC2DisposeSafe(); + comp2TeamIdMap.MC2DisposeSafe(); + comp2SyncPartnerCompMap.MC2DisposeSafe(); + comp2SyncTopCompMap.MC2DisposeSafe(); + + if (batchNormalClothTeamList.IsCreated) + batchNormalClothTeamList.Dispose(); + if (batchSplitClothTeamList.IsCreated) + batchSplitClothTeamList.Dispose(); + + parameterDirtyList?.Clear(); + skipWritingDirtyList?.Clear(); + if (cullingDirtyList.IsCreated) + cullingDirtyList.Dispose(); + if (selfCollisionUpdateSet.IsCreated) + selfCollisionUpdateSet.Dispose(); + animatorUpdateModeMap.MC2DisposeSafe(); + + teamAnchorTransformIndexArray?.Dispose(); + teamDistanceTransformIndexArray?.Dispose(); + transformPositionMap.MC2DisposeSafe(); + transformRotationMap.MC2DisposeSafe(); + + cameraCullingClothSet.Clear(); + + //globalTimeScale = 1.0f; + //fixedUpdateCount = 0; + + // 破棄監視更新処理 + MagicaManager.afterUpdateDelegate -= MonitoringProcessUpdate; + } + + public void EnterdEditMode() + { + Dispose(); + } + + public void Initialize() + { + Dispose(); + + const int capacity = 32; + teamDataArray = new ExNativeArray(capacity); + teamWindArray = new ExNativeArray(capacity); + mappingDataArray = new ExNativeArray(capacity); + teamMappingIndexArray = new ExNativeArray>(capacity); + parameterArray = new ExNativeArray(capacity); + centerDataArray = new ExNativeArray(capacity); + + // グローバルチーム[0]を追加する + var gteam = new TeamData(); + teamDataArray.Add(gteam); + teamWindArray.Add(new TeamWindData()); + teamMappingIndexArray.Add(new FixedList64Bytes()); + parameterArray.Add(new ClothParameters()); + centerDataArray.Add(new InertiaConstraint.CenterData()); + + teamStatus = new NativeReference(Allocator.Persistent); + + //globalTimeScale = 1.0f; + //fixedUpdateCount = 0; + + // 作業用 + edgeColliderCollisionCountBuff = new NativeReference(Allocator.Persistent); + comp2SuspendCounterMap = new NativeParallelHashMap(256, Allocator.Persistent); + comp2TeamIdMap = new NativeParallelHashMap(256, Allocator.Persistent); + comp2SyncPartnerCompMap = new NativeParallelHashMap(256, Allocator.Persistent); + comp2SyncTopCompMap = new NativeParallelHashMap(256, Allocator.Persistent); + + batchNormalClothTeamList = new NativeList(Allocator.Persistent); + batchSplitClothTeamList = new NativeList(Allocator.Persistent); + + parameterDirtyList = new List(128); + skipWritingDirtyList = new List(128); + cullingDirtyList = new NativeList(128, Allocator.Persistent); + selfCollisionUpdateSet = new NativeParallelHashSet(256, Allocator.Persistent); + animatorUpdateModeMap = new NativeParallelHashMap(128, Allocator.Persistent); + + teamAnchorTransformIndexArray = new ExSimpleNativeArray(256, true); + teamDistanceTransformIndexArray = new ExSimpleNativeArray(256, true); + transformPositionMap = new NativeParallelHashMap(32, Allocator.Persistent); + transformRotationMap = new NativeParallelHashMap(32, Allocator.Persistent); + + // 破棄監視更新処理 + MagicaManager.afterUpdateDelegate += MonitoringProcessUpdate; + + isValid = true; + } + + public bool IsValid() + { + return isValid; + } + + //========================================================================================= + /// + /// チームを登録する + /// + /// + /// + /// + internal int AddTeam(ClothProcess cprocess, ClothParameters clothParams) + { + if (isValid == false) + return 0; + + // この段階でProxyMeshは完成している + + var team = new TeamData(); + team.componentId = cprocess.cloth.GetMagicaId(); + // ★Enableフラグは立てない + team.flag.SetBits(Flag_Valid, true); + team.flag.SetBits(Flag_Reset, true); + team.flag.SetBits(Flag_TimeReset, true); + team.originalUpdateMode = cprocess.cloth.SerializeData.updateMode; + team.updateMode = cprocess.cloth.SerializeData.updateMode; + //team.frequency = clothParams.solverFrequency; + team.timeScale = 1.0f; + team.initScale = cprocess.clothTransformRecord.scale; // 初期スケール + team.scaleRatio = 1.0f; + team.negativeScaleSign = 1; + team.negativeScaleDirection = 1; + team.negativeScaleChange = 1; + team.negativeScaleQuaternionValue = 1; + team.negativeScaleTriangleSign = 1; + //team.centerWorldPosition = cprocess.clothTransformRecord.position; + team.animationPoseRatio = cprocess.cloth.SerializeData.animationPoseRatio; + team.distanceWeight = 1; + team.componentTransformIndex = MagicaManager.Bone.AddComponentTransform(cprocess.cloth.transform); // コンポーネントTransform + //cprocess.componentTransformIndex = team.componentTransformIndex; // cprocessにもコピー + var c = teamDataArray.Add(team); + int teamId = c.startIndex; + + // 最大チーム数チェック + if (teamId >= Define.System.MaximumTeamCount) + { + Develop.LogError($"Cannot create more than {Define.System.MaximumTeamCount} teams."); + teamDataArray.Remove(c); + return 0; + } + + var wind = new TeamWindData(); + wind.movingWind.time = -Define.System.WindMaxTime; + teamWindArray.Add(wind); + + // マッピングメッシュ + teamMappingIndexArray.Add(new FixedList64Bytes()); + + // パラメータ + parameterArray.Add(clothParams); + + // 慣性制約 + // 初期化時のセンターローカル位置を初期化 + var cdata = new InertiaConstraint.CenterData(); + cdata.frameLocalPosition = cprocess.ProxyMeshContainer.shareVirtualMesh.localCenterPosition.Value; + centerDataArray.Add(cdata); + + clothProcessDict.Add(teamId, cprocess); + + return teamId; + } + + /// + /// チームを解除する + /// + /// + internal void RemoveTeam(int teamId) + { + if (isValid == false || teamId == 0) + return; + + // セルフコリジョン同期解除 + ref var tdata = ref GetTeamDataRef(teamId); + if (tdata.syncTeamId > 0 && ContainsTeamData(tdata.syncTeamId)) + { + ref var stdata = ref GetTeamDataRef(tdata.syncTeamId); + RemoveSyncParent(ref stdata, teamId); + } + + // 制約データなど解除 + MagicaManager.Bone.RemoveComponentTransform(tdata.componentTransformIndex); + + // チームデータを破棄する + var c = new DataChunk(teamId); + teamDataArray.RemoveAndFill(c); + teamWindArray.RemoveAndFill(c); + teamMappingIndexArray.RemoveAndFill(c, new FixedList64Bytes()); + parameterArray.Remove(c); + centerDataArray.Remove(c); + + // チーム作業バッファをクリア + teamAnchorTransformIndexArray[teamId] = MagicaObjectId.Invalid; + teamDistanceTransformIndexArray[teamId] = MagicaObjectId.Invalid; + + clothProcessDict.Remove(teamId); + } + + /// + /// チームの有効化設定 + /// + /// + /// + public void SetEnable(ClothProcess cprocess, int teamId, bool sw) + { + //Debug.Log($"Set Enable:{sw} F:{Time.frameCount}"); + if (isValid == false || teamId == 0) + return; + ref var team = ref teamDataArray.GetRef(teamId); + + // シミュレーションリセットの有無 + // (同期先を参照) + ClothProcess syncProcess = cprocess.SyncTopCloth ? cprocess.SyncTopCloth.Process : cprocess; + bool isReset = syncProcess.cloth.SerializeData.disableMode == ClothDisableMode.Reset; + + team.flag.SetBits(Flag_Enable, sw); + if (isReset) + team.flag.SetBits(Flag_Reset, sw); + + //Debug.Log($"Set Enable:{sw}, isReset:{isReset} F:{Time.frameCount}"); + + if (sw) + enableTeamSet.Add(teamId); + else + enableTeamSet.Remove(teamId); + + // 非表示(リセット)の挙動 + if (sw == false && isReset) + { + // 無効時には一度のみTransform復元フラグを立てる + team.flag.SetBits(Flag_RestoreTransformOnlyOnec, true); + // Disable時は非表示設定にする + team.flag.SetBits(Flag_CameraCullingInvisible, true); + cprocess.SetState(ClothProcess.State_CameraCullingInvisible, true); + cprocess.cameraCullingOldInvisible = true; + } + + // コライダーの有効状態(内部でコライダートランスフォームの有効状態も設定) + MagicaManager.Collider.EnableTeamCollider(teamId); + + // センタートランスフォーム + MagicaManager.Bone.EnableTransform(team.centerTransformIndex, sw); + + // プロキシメッシュ + MagicaManager.Bone.EnableTransform(team.proxyTransformChunk, sw); + } + + public bool IsEnable(int teamId) + { + return enableTeamSet.Contains(teamId); + } + + internal void SetSkipWriting(int teamId, bool sw) + { + if (isValid == false || teamId == 0) + return; + ref var team = ref teamDataArray.GetRef(teamId); + team.flag.SetBits(Flag_SkipWriting, sw); + } + + public bool ContainsTeamData(int teamId) + { + return teamId >= 0 && clothProcessDict.ContainsKey(teamId); + } + + public ref TeamData GetTeamDataRef(int teamId) + { + return ref teamDataArray.GetRef(teamId); + } + + public ref FixedList64Bytes GetTeamMappingRef(int teamId) + { + return ref teamMappingIndexArray.GetRef(teamId); + } + + public ref ClothParameters GetParametersRef(int teamId) + { + return ref parameterArray.GetRef(teamId); + } + + internal ref InertiaConstraint.CenterData GetCenterDataRef(int teamId) + { + return ref centerDataArray.GetRef(teamId); + } + + internal ref MappingData GetMappingDataRef(int mindex) + { + return ref mappingDataArray.GetRef(mindex); + } + + public ClothProcess GetClothProcess(int teamId) + { + if (clothProcessDict.ContainsKey(teamId)) + return clothProcessDict[teamId]; + else + return null; + } + + //========================================================================================= + static readonly ProfilerMarker teamCameraCullingPreProfiler = new ProfilerMarker("CameraCullingPre"); + static readonly ProfilerMarker teamCameraCullingProfiler = new ProfilerMarker("CameraCullingPost"); + + /// + /// カメラカリング状態更新(前処理) + /// 次のフレームの開始時に行うレンダラー判定用のデータを収集する + /// + internal void CameraCullingPreProcess() + { + teamCameraCullingPreProfiler.Begin(); + + var cm = MagicaManager.Cloth; + + // ここはシミュレーション処理中なのでtdataなどにアクセスできないので注意! + cameraCullingClothSet.Clear(); + foreach (var cprocess in cm.clothSet) + { + if (cprocess.IsEnable == false) + continue; + if (cprocess.IsRunning() == false) + continue; + + + // 判定クロス。同期時は同期先を見る + MagicaCloth jugeCloth = cprocess.SyncTopCloth != null ? cprocess.SyncTopCloth : cprocess.cloth; + CullingSettings jugeSettings = jugeCloth.SerializeData.cullingSettings; + ClothProcess jugeProcess = jugeCloth.Process; + + // 最終的なカリングモード + var cullingMode = jugeSettings.cameraCullingMode; + if (cullingMode == CullingSettings.CameraCullingMode.AnimatorLinkage) + { + if (jugeProcess.interlockingAnimator) + { + switch (jugeProcess.interlockingAnimator.cullingMode) + { + case AnimatorCullingMode.AlwaysAnimate: + cullingMode = CullingSettings.CameraCullingMode.Off; + break; + case AnimatorCullingMode.CullCompletely: + cullingMode = CullingSettings.CameraCullingMode.Keep; + break; + case AnimatorCullingMode.CullUpdateTransforms: + cullingMode = CullingSettings.CameraCullingMode.Reset; + break; + } + } + else + cullingMode = CullingSettings.CameraCullingMode.Off; + } + + // カリング判定 + if (jugeCloth == null || cullingMode == CullingSettings.CameraCullingMode.Off) + { + // カリングは行わない + cprocess.cameraCullingAnimator = null; + cprocess.cameraCullingRenderers = null; + } + else + { + // 参照すべきレンダラー確定 + Animator jugeAnimator = null; + List jugeRenderers = jugeSettings.cameraCullingRenderers; + if (jugeSettings.cameraCullingMethod == CullingSettings.CameraCullingMethod.AutomaticRenderer) + { + jugeAnimator = jugeCloth.Process.interlockingAnimator; + jugeRenderers = jugeCloth.Process.interlockingAnimatorRenderers; + } + cprocess.cameraCullingAnimator = jugeAnimator; + cprocess.cameraCullingRenderers = jugeRenderers; + } + cprocess.cameraCullingMode = cullingMode; + + cameraCullingClothSet.Add(cprocess.cloth); + } + + teamCameraCullingPreProfiler.End(); + } + + /// + /// カメラカリング状態更新(後処理) + /// カメラカリングは該当するRendereのisVisibleフラグから判定される + /// このフラグは前フレームのレンダリング時に設定される + /// そのため現在フレームの位置は反映されないので注意する(1フレーム遅れる) + /// + internal void CameraCullingPostProcess() + { + teamCameraCullingProfiler.Begin(); + + var cm = MagicaManager.Cloth; + cm.ClearVisibleDict(); + + foreach (var cloth in cameraCullingClothSet) + { + if (cloth == null) + continue; + + var cprocess = cloth.Process; + + // 現在の状態 + bool oldInvisible = cprocess.cameraCullingOldInvisible; + bool invisible; + + if (cprocess.cameraCullingAnimator == null && cprocess.cameraCullingRenderers == null) + { + // カリングなし + invisible = false; + } + else + { + // レンダラー判定 + invisible = !cm.CheckVisible(cprocess.cameraCullingAnimator, cprocess.cameraCullingRenderers); + } + + // 状態変更 + if (oldInvisible != invisible) + { + //Debug.Log($"Camera culling change. oldInvisible:{oldInvisible} -> invisible:{invisible} F:{Time.frameCount}"); + int teamId = cprocess.TeamId; + ref var tdata = ref GetTeamDataRef(teamId); + + tdata.flag.SetBits(Flag_CameraCullingInvisible, invisible); + tdata.flag.SetBits(Flag_CameraCullingKeep, false); + + // cprocessクラスにもコピーする + cprocess.SetState(ClothProcess.State_CameraCullingInvisible, invisible); + cprocess.SetState(ClothProcess.State_CameraCullingKeep, false); + cprocess.cameraCullingOldInvisible = invisible; + + if (invisible) + { + // (表示->非表示)時の振る舞い + switch (cprocess.cameraCullingMode) + { + case CullingSettings.CameraCullingMode.Reset: + case CullingSettings.CameraCullingMode.Off: + tdata.flag.SetBits(Flag_Reset, true); + //Debug.Log($"Camera culling invisible. Reset On"); + break; + case CullingSettings.CameraCullingMode.Keep: + tdata.flag.SetBits(Flag_CameraCullingKeep, true); + cprocess.SetState(ClothProcess.State_CameraCullingKeep, true); + //Debug.Log($"Camera culling invisible. Keep On"); + break; + } + } + + // 対応するレンダーデータに更新を指示する + cprocess.UpdateRendererUse(); + } + } + cameraCullingClothSet.Clear(); + + teamCameraCullingProfiler.End(); + } + + //========================================================================================= + static readonly ProfilerMarker startClothUpdateComponentProfiler = new ProfilerMarker("StartClothUpdate.Component"); + + /// + /// 毎フレーム常に実行するチーム更新 + /// - パラメータ反映 + /// - 更新モード反映 + /// - アンカー/距離カリングの参照オブジェクト反映 + /// - 時間の更新と実行回数の算出 + /// + internal void AlwaysTeamUpdate() + { + var cm = MagicaManager.Cloth; + var tm = MagicaManager.Time; + var rm = MagicaManager.Render; + var bm = MagicaManager.Bone; + var sm = MagicaManager.Simulation; + + // 作業バッファクリア + edgeColliderCollisionCount = 0; + edgeColliderCollisionCountBuff.Value = 0; + cm.ClearVisibleDict(); // レンダラーの表示判定辞書をクリア + selfCollisionUpdateSet.Clear(); + teamAnchorTransformIndexArray.SetLength(TeamCount); + teamDistanceTransformIndexArray.SetLength(TeamCount); + transformPositionMap.Clear(); + transformRotationMap.Clear(); + cullingDirtyList.Clear(); + batchNormalClothTeamList.Clear(); + batchSplitClothTeamList.Clear(); + + // (1)パラメータ反映 + for (int i = 0; i < parameterDirtyList.Count;) + { + var cprocess = parameterDirtyList[i]; + if (cprocess == null) + { + parameterDirtyList.RemoveAt(i); + continue; + } + if (cprocess.IsEnable == false) + { + i++; + continue; + } + + //Develop.DebugLog($"Update Parameters {teamId}"); + // コライダー更新(内部でteamData更新) + MagicaManager.Collider.UpdateColliders(cprocess); + + // カリング用アニメーターとレンダラー更新 + cprocess.UpdateCullingAnimatorAndRenderers(); + + int teamId = cprocess.TeamId; + ref var tdata = ref GetTeamDataRef(teamId); + var cloth = cprocess.cloth; + + // 連動アニメーターのインスタンスID + tdata.interlockingAnimatorId = cprocess.interlockingAnimator != null ? cprocess.interlockingAnimator.GetMagicaId() : MagicaObjectId.Invalid; + + // パラメータ変更 + cprocess.SyncParameters(); + parameterArray[teamId] = cprocess.parameters; + tdata.originalUpdateMode = cloth.SerializeData.updateMode; + tdata.updateMode = cloth.SerializeData.updateMode; + tdata.animationPoseRatio = cloth.SerializeData.animationPoseRatio; + tdata.flag.SetBits(Flag_Spring, cprocess.clothType == ClothProcess.ClothType.BoneSpring && cprocess.parameters.springConstraint.springPower > 0.0f); // Spring利用フラグ + + // セルフコリジョン更新 + selfCollisionUpdateSet.Add(teamId); + + // 接線モード + tdata.flag.SetBits(Flag_Tangent, cloth.SerializeData.meshWriteMode == ClothMeshWriteMode.PositionAndNormalTangent); + cprocess.SetState(ClothProcess.State_UpdateTangent, tdata.flag.IsSet(Flag_Tangent)); + + parameterDirtyList.RemoveAt(i); + } + + // (2)書き込み停止反映 + for (int i = 0; i < skipWritingDirtyList.Count;) + { + var cprocess = skipWritingDirtyList[i]; + if (cprocess == null) + { + skipWritingDirtyList.RemoveAt(i); + continue; + } + if (cprocess.IsEnable == false) + { + i++; + continue; + } + + bool skipWriting = cprocess.IsState(ClothProcess.State_SkipWriting); + + int teamId = cprocess.TeamId; + ref var tdata = ref GetTeamDataRef(teamId); + + // チームへ反映 + tdata.flag.SetBits(Flag_SkipWriting, skipWriting); + + // RenderDataへ反映 + foreach (var rinfo in cprocess.renderMeshInfoList) + { + var renderData = rm.GetRendererData(rinfo.renderHandle); + renderData.UpdateSkipWriting(); + } + + skipWritingDirtyList.RemoveAt(i); + } + +#if true + // (3A)チーム前処理ジョブ + // このジョブは相互参照があるので並列化できない + var job1 = new AlwaysTeamUpdatePreJob() + { + teamDataArray = teamDataArray.GetNativeArray(), + parameterArray = parameterArray.GetNativeArray(), + + comp2SuspendCounterMap = comp2SuspendCounterMap, + comp2TeamIdMap = comp2TeamIdMap, + comp2SyncPartnerCompMap = comp2SyncPartnerCompMap, + comp2SyncTopCompMap = comp2SyncTopCompMap, + selfCollisionUpdateSet = selfCollisionUpdateSet, + edgeColliderCollisionCountBuff = edgeColliderCollisionCountBuff, + }; + var jobHandle1 = job1.Schedule(); + + // (3B)コンポーネント座標読み込みジョブ + // 3Aと並列実行 + var jobHandle2 = bm.ReadComponentTransform(default); + + JobHandle.ScheduleBatchedJobs(); // 即時開始 +#endif + + // (4)他のコンポーネントを参照する必要がある処理 + startClothUpdateComponentProfiler.Begin(); + animatorUpdateModeMap.Clear(); + foreach (var cprocess in cm.clothSet) + { + if (cprocess.TeamId == 0) + continue; + + // 連動アニメーターの更新モード取得 + if (cprocess.interlockingAnimator) + { + MagicaObjectId animatorId = cprocess.interlockingAnimator.GetMagicaId(); + if (animatorUpdateModeMap.ContainsKey(animatorId) == false) + { + animatorUpdateModeMap.Add(animatorId, (int)cprocess.interlockingAnimator.updateMode); + } + } + + // 同期時は同期先を見る + var refCloth = cprocess.SyncTopCloth != null ? cprocess.SyncTopCloth : cprocess.cloth; + var sdata = refCloth.SerializeData; + +#if true + // アンカー参照オブジェクト + var anchorTransform = sdata.inertiaConstraint.anchor; + MagicaObjectId anchorTransformId = anchorTransform != null ? anchorTransform.GetMagicaId() : MagicaObjectId.Invalid; + if (anchorTransformId.IsValid() && transformPositionMap.ContainsKey(anchorTransformId) == false) + { + // 参照オブジェクトの座標取得 + transformPositionMap.Add(anchorTransformId, anchorTransform.position); + transformRotationMap.Add(anchorTransformId, anchorTransform.rotation); + } + if (cprocess.anchorTransformId != anchorTransformId) + { + // 変更あり + cprocess.anchorTransformId = anchorTransformId; + teamAnchorTransformIndexArray[cprocess.TeamId] = anchorTransformId; + } + + // 距離カリング参照オブジェクト + MagicaObjectId distanceObjectId = sdata.cullingSettings.distanceCullingReferenceObject != null ? sdata.cullingSettings.distanceCullingReferenceObject.GetMagicaId() : MagicaObjectId.Invalid; + if (distanceObjectId.IsValid() && transformPositionMap.ContainsKey(distanceObjectId) == false) + { + // 参照オブジェクトの座標取得 + transformPositionMap.Add(distanceObjectId, sdata.cullingSettings.distanceCullingReferenceObject.transform.position); + } + if (cprocess.distanceReferenceObjectId != distanceObjectId) + { + // 変更あり + cprocess.distanceReferenceObjectId = distanceObjectId; + teamDistanceTransformIndexArray[cprocess.TeamId] = distanceObjectId; + } +#endif + } + + // メインカメラ座標 + bool hasMainCamera = Camera.main != null; + float3 mainCameraPosition = Camera.main ? Camera.main.transform.position : 0; + //transformPositionMap.Add(0, mainCameraPosition); + transformPositionMap.Add(MagicaObjectId.Invalid, mainCameraPosition); + startClothUpdateComponentProfiler.End(); + + // チーム前処理ジョブ待ち + jobHandle1.Complete(); + jobHandle2.Complete(); + edgeColliderCollisionCount = edgeColliderCollisionCountBuff.Value; + + // (5)セルフコリジョンのフラグやバッファ更新 + if (selfCollisionUpdateSet.Count() > 0) + { + foreach (var teamId in selfCollisionUpdateSet) + { + sm.selfCollisionConstraint.UpdateTeam(teamId); + } + selfCollisionUpdateSet.Clear(); + } + + // (6)チーム後処理ジョブ +#if true + if (ActiveTeamCount > 0) + { + // フレーム更新時間 + float deltaTime = Time.deltaTime; + float fixedDeltaTime = tm.FixedUpdateCount * Time.fixedDeltaTime; + float unscaledDeltaTime = Time.unscaledDeltaTime; + + //Debug.Log($"DeltaTime:{deltaTime}, FixedDeltaTime:{fixedDeltaTime}, simulationDeltaTime:{MagicaManager.Time.SimulationDeltaTime}, maxDeltaTime:{MagicaManager.Time.MaxDeltaTime}"); + //Debug.Log($"DeltaTime:{deltaTime}, FixedDeltaTime:{fixedDeltaTime}, simulationDeltaTime:{MagicaManager.Time.SimulationDeltaTime}"); + + // このJobは即時実行させる + var postJob = new AlwaysTeamUpdatePostJob() + { + teamCount = TeamCount, + unityFrameDeltaTime = deltaTime, + unityFrameFixedDeltaTime = fixedDeltaTime, + unityFrameUnscaledDeltaTime = unscaledDeltaTime, + globalTimeScale = tm.GlobalTimeScale, + simulationDeltaTime = tm.SimulationDeltaTime, + //maxDeltaTime = MagicaManager.Time.MaxDeltaTime, + maxSimmulationCountPerFrame = tm.maxSimulationCountPerFrame, + splitProxyMeshVertexCount = sm.splitProxyMeshVertexCount, + + //maxUpdateCount = maxUpdateCount, + teamStatus = teamStatus, + teamDataArray = teamDataArray.GetNativeArray(), + parameterArray = parameterArray.GetNativeArray(), + centerDataArray = centerDataArray.GetNativeArray(), + + componentPositionArray = bm.componentPositionArray.GetNativeArray(), + componentMinScaleArray = bm.componentMinScaleArray.GetNativeArray(), + hasMainCamera = hasMainCamera, + + comp2TeamIdMap = comp2TeamIdMap, + comp2SyncTopCompMap = comp2SyncTopCompMap, + animatorUpdateModeMap = animatorUpdateModeMap, + teamAnchorTransformIndexArray = teamAnchorTransformIndexArray.GetNativeArray(), + teamDistanceTransformIndexArray = teamDistanceTransformIndexArray.GetNativeArray(), + transformPositionMap = transformPositionMap, + transformRotationMap = transformRotationMap, + cullingDirtyList = cullingDirtyList, + + batchNormalClothTeamList = batchNormalClothTeamList, + batchSplitClothTeamList = batchSplitClothTeamList, + }; + postJob.Run(); + + // 距離カリング反映 + if (cullingDirtyList.Length > 0) + { + foreach (int teamId in cullingDirtyList) + { + ref var tdata = ref GetTeamDataRef(teamId); + var cprocess = GetClothProcess(teamId); + + bool invisible = tdata.IsDistanceCullingInvisible; + + // cprocessクラスにもコピーする + // 距離カリングでは表示/非表示切替時に常にリセットする + // またカメラカリングのKeepは強制解除する + cprocess.SetState(ClothProcess.State_DistanceCullingInvisible, invisible); + cprocess.SetState(ClothProcess.State_CameraCullingKeep, false); + + // 対応するレンダーデータに更新を指示する + cprocess.UpdateRendererUse(); + } + } + } +#endif + } + + [BurstCompile] + unsafe struct AlwaysTeamUpdatePreJob : IJob + { + public NativeArray teamDataArray; + public NativeArray parameterArray; + + // work + public NativeParallelHashMap comp2SuspendCounterMap; + public NativeParallelHashMap comp2TeamIdMap; + public NativeParallelHashMap comp2SyncPartnerCompMap; + public NativeParallelHashMap comp2SyncTopCompMap; + public NativeParallelHashSet selfCollisionUpdateSet; + public NativeReference edgeColliderCollisionCountBuff; + + public void Execute() + { + int edgeColliderCollisionCount = 0; + TeamData* tt = (TeamData*)teamDataArray.GetUnsafePtr(); + + foreach (var kv in comp2TeamIdMap) + { + int teamId = kv.Value; + if (teamId == 0) + continue; + + MagicaObjectId compId = kv.Key; + ref var tdata = ref *(tt + teamId); + + // 作業フラグをクリア ------------------------------------- + tdata.flag.SetBits(Flag_RestoreTransformOnlyOnec, false); + + // 動作判定 ---------------------------------------------------- + if (tdata.flag.IsSet(Flag_Enable) == false) + continue; + + // 同期まち判定 ------------------------------------------------- + bool syncSuspend = true; + if (comp2SuspendCounterMap.ContainsKey(compId) == false || comp2SuspendCounterMap[compId] == 0) + syncSuspend = false; + + // 同期相手の有効状態 + if (comp2SyncPartnerCompMap.ContainsKey(compId)) + { + MagicaObjectId syncCompId = comp2SyncPartnerCompMap[compId]; + if (comp2TeamIdMap.ContainsKey(syncCompId)) + { + int syncTeamId = comp2TeamIdMap[syncCompId]; + if (syncTeamId > 0) + { + ref var syncTeamData = ref *(tt + syncTeamId); + int syncSuspendCounter = comp2SuspendCounterMap.ContainsKey(syncCompId) ? comp2SuspendCounterMap[syncCompId] : 0; + if (syncTeamData.IsEnable && syncSuspendCounter == 0) + syncSuspend = false; // 相手も処理可能状態 + } + } + } + tdata.flag.SetBits(Flag_SyncSuspend, syncSuspend); + + // 同期待ちなら実行できない + if (tdata.flag.IsSet(Flag_SyncSuspend)) + continue; + + // チーム同期 -------------------------------------------------- + int oldSyncTeamId = tdata.syncTeamId; + tdata.syncTeamId = 0; + if (comp2SyncPartnerCompMap.ContainsKey(compId)) + { + MagicaObjectId syncCompId = comp2SyncPartnerCompMap[compId]; + if (comp2TeamIdMap.ContainsKey(syncCompId)) + { + int syncTeamId = comp2TeamIdMap[syncCompId]; + tdata.syncTeamId = syncTeamId; + } + } + tdata.flag.SetBits(Flag_Synchronization, tdata.syncTeamId != 0); + tdata.syncCenterTransformIndex = 0; + if (oldSyncTeamId != tdata.syncTeamId) + { + // 変更あり! + // 同期解除 + if (oldSyncTeamId > 0) + { + //Debug.Log($"Desynchronization! (1) {teamId}"); + ref var syncTeamData = ref *(tt + oldSyncTeamId); + syncTeamData.syncParentTeamId.MC2RemoveItemAtSwapBack(teamId); + } + + // 同期変更 + if (tdata.syncTeamId != 0) + { + ref var syncTeamData = ref *(tt + tdata.syncTeamId); + + // 相手に自身を登録 + // 最大7まで + if (syncTeamData.syncParentTeamId.Length == syncTeamData.syncParentTeamId.Capacity) + { + //Debug.LogWarning($"Synchronous team number limit!"); + } + else + syncTeamData.syncParentTeamId.Add(teamId); + + // 時間リセットフラグクリア + tdata.flag.SetBits(Flag_TimeReset, false); + + //Debug.Log($"Synchronization! {teamId}->{tdata.syncTeamId}"); + } + else + { + // 同期解除 + //cloth.SerializeData.selfCollisionConstraint.syncPartner = null; + //Debug.Log($"Desynchronization! (2) {teamId}"); + } + + // セルフコリジョン更新セットに追加 + selfCollisionUpdateSet.Add(teamId); + } + + // 時間とパラメータの同期 + var clothParam = parameterArray[teamId]; + + // トップ階層の同期クロスを見る + int syncTopTeamId = 0; + if (comp2SyncTopCompMap.ContainsKey(compId)) + { + MagicaObjectId syncTopCompId = comp2SyncTopCompMap[compId]; + if (comp2TeamIdMap.ContainsKey(syncTopCompId)) + { + syncTopTeamId = comp2TeamIdMap[syncTopCompId]; + ref var syncTeamData = ref *(tt + syncTopTeamId); + + // 時間同期 + if (syncTeamData.IsValid) + { + tdata.originalUpdateMode = syncTeamData.originalUpdateMode; + tdata.updateMode = syncTeamData.updateMode; + //tdata.frequency = syncTeamData.frequency; + tdata.time = syncTeamData.time; + tdata.oldTime = syncTeamData.oldTime; + tdata.nowUpdateTime = syncTeamData.nowUpdateTime; + tdata.oldUpdateTime = syncTeamData.oldUpdateTime; + tdata.frameUpdateTime = syncTeamData.frameUpdateTime; + tdata.frameOldTime = syncTeamData.frameOldTime; + tdata.timeScale = syncTeamData.timeScale; + tdata.updateCount = syncTeamData.updateCount; + tdata.frameInterpolation = syncTeamData.frameInterpolation; + tdata.skipCount = syncTeamData.skipCount; + //Develop.DebugLog($"Team time sync:{teamId}->{syncCloth.Process.TeamId}"); + } + + // パラメータ同期 + // 同期中は一部のパラメータを連動させる + var syncClothParam = parameterArray[syncTopTeamId]; + clothParam.inertiaConstraint.anchorInertia = syncClothParam.inertiaConstraint.anchorInertia; + clothParam.inertiaConstraint.worldInertia = syncClothParam.inertiaConstraint.worldInertia; + clothParam.inertiaConstraint.movementInertiaSmoothing = syncClothParam.inertiaConstraint.movementInertiaSmoothing; + clothParam.inertiaConstraint.movementSpeedLimit = syncClothParam.inertiaConstraint.movementSpeedLimit; + clothParam.inertiaConstraint.rotationSpeedLimit = syncClothParam.inertiaConstraint.rotationSpeedLimit; + clothParam.inertiaConstraint.teleportMode = syncClothParam.inertiaConstraint.teleportMode; + clothParam.inertiaConstraint.teleportDistance = syncClothParam.inertiaConstraint.teleportDistance; + clothParam.inertiaConstraint.teleportRotation = syncClothParam.inertiaConstraint.teleportRotation; + parameterArray[teamId] = clothParam; + + // 同期先のセンタートランスフォームインデックスを記録 + tdata.syncCenterTransformIndex = syncTeamData.centerTransformIndex; + } + } + + // 集計まわり + if (clothParam.colliderCollisionConstraint.mode == ColliderCollisionConstraint.Mode.Edge) + edgeColliderCollisionCount += tdata.EdgeCount; + } + + edgeColliderCollisionCountBuff.Value = edgeColliderCollisionCount; + } + } + + [BurstCompile] + struct AlwaysTeamUpdatePostJob : IJob + { + public int teamCount; + public float unityFrameDeltaTime; + public float unityFrameFixedDeltaTime; + public float unityFrameUnscaledDeltaTime; + public float globalTimeScale; + public float simulationDeltaTime; + public int maxSimmulationCountPerFrame; + public int splitProxyMeshVertexCount; + + public NativeReference teamStatus; + public NativeArray teamDataArray; + [Unity.Collections.ReadOnly] + public NativeArray parameterArray; + public NativeArray centerDataArray; + + public NativeArray componentPositionArray; + public NativeArray componentMinScaleArray; + public bool hasMainCamera; + + // work + public NativeParallelHashMap comp2TeamIdMap; + public NativeParallelHashMap comp2SyncTopCompMap; + public NativeParallelHashMap animatorUpdateModeMap; + public NativeArray teamAnchorTransformIndexArray; + public NativeArray teamDistanceTransformIndexArray; + public NativeParallelHashMap transformPositionMap; + public NativeParallelHashMap transformRotationMap; + public NativeList cullingDirtyList; + + public NativeList batchNormalClothTeamList; + public NativeList batchSplitClothTeamList; + + public void Execute() + { + int maxCount = 0; + int splitPointCollisionCount = 0; + int splitEdgeCollisionCount = 0; + int splitSelfCollisionCount = 0; + + for (int teamId = 1; teamId < teamCount; teamId++) + { + var tdata = teamDataArray[teamId]; + MagicaObjectId compId = tdata.componentId; + if (tdata.IsEnable == false) + continue; + if (tdata.flag.IsSet(Flag_SyncSuspend)) + continue; + + var param = parameterArray[teamId]; + + // 動作検証 + // 極小スケールによる機能停止 + tdata.flag.SetBits(Flag_ScaleSuspent, componentMinScaleArray[tdata.componentTransformIndex] < 1e-06f); + if (tdata.flag.IsSet(Flag_ScaleSuspent)) + { + teamDataArray[teamId] = tdata; + continue; + } + + // アンカー + MagicaObjectId anchorTransformIndex = teamAnchorTransformIndexArray[teamId]; + bool oldAnchor = tdata.flag.IsSet(Flag_Anchor); + bool newAnchor = anchorTransformIndex.IsValid(); + tdata.flag.SetBits(Flag_Anchor, newAnchor); + tdata.flag.SetBits(Flag_AnchorReset, oldAnchor != newAnchor); + var cdata = centerDataArray[teamId]; + cdata.anchorPosition = anchorTransformIndex.IsValid() ? transformPositionMap[anchorTransformIndex] : float3.zero; + cdata.anchorRotation = anchorTransformIndex.IsValid() ? transformRotationMap[anchorTransformIndex] : quaternion.identity; + centerDataArray[teamId] = cdata; + + // 距離カリング判定 + DistanceCullingUpdate(teamId, ref tdata, ref param); + + if (tdata.IsCullingInvisible) + { + teamDataArray[teamId] = tdata; + continue; + } + + // 更新モード + int syncTopTeamId = 0; + if (comp2SyncTopCompMap.ContainsKey(compId)) + { + MagicaObjectId syncTopCompId = comp2SyncTopCompMap[compId]; + if (comp2TeamIdMap.ContainsKey(syncTopCompId)) + { + syncTopTeamId = comp2TeamIdMap[syncTopCompId]; + } + } + if (tdata.originalUpdateMode == ClothUpdateMode.AnimatorLinkage || syncTopTeamId > 0) + { + var originalUpdateMode = tdata.originalUpdateMode; + MagicaObjectId animatorId = tdata.interlockingAnimatorId; + if (syncTopTeamId > 0) + { + var syncTeamData = teamDataArray[syncTopTeamId]; + originalUpdateMode = syncTeamData.originalUpdateMode; + animatorId = syncTeamData.interlockingAnimatorId; + } + + switch (originalUpdateMode) + { + case ClothUpdateMode.Normal: + case ClothUpdateMode.UnityPhysics: + case ClothUpdateMode.Unscaled: + tdata.updateMode = originalUpdateMode; + break; + case ClothUpdateMode.AnimatorLinkage: + if (animatorUpdateModeMap.ContainsKey(animatorId)) + { + AnimatorUpdateMode aniUpdateMode = (AnimatorUpdateMode)animatorUpdateModeMap[animatorId]; + switch (aniUpdateMode) + { + case AnimatorUpdateMode.Normal: + tdata.updateMode = ClothUpdateMode.Normal; + break; +#if UNITY_2023_1_OR_NEWER + case AnimatorUpdateMode.Fixed: + tdata.updateMode = ClothUpdateMode.UnityPhysics; + break; +#else + case AnimatorUpdateMode.AnimatePhysics: + tdata.updateMode = ClothUpdateMode.UnityPhysics; + break; +#endif + case AnimatorUpdateMode.UnscaledTime: + tdata.updateMode = ClothUpdateMode.Unscaled; + break; + default: + //Develop.DebugLogWarning($"[{cloth.name}] Unknown Animator UpdateMode:{interlockingAnimator.updateMode}"); + tdata.updateMode = ClothUpdateMode.Normal; + break; + } + } + else + tdata.updateMode = ClothUpdateMode.Normal; + break; + default: + //Develop.LogError($"[{cloth.name}] Unknown Cloth Update Mode:{cloth.SerializeData.updateMode}"); + tdata.updateMode = ClothUpdateMode.Normal; + break; + } + } + + // 時間リセット + if (tdata.flag.IsSet(Flag_TimeReset)) + { + tdata.time = 0; + tdata.oldTime = 0; + tdata.nowUpdateTime = 0; + tdata.oldUpdateTime = 0; + tdata.frameUpdateTime = 0; + tdata.frameOldTime = 0; + } + + // 更新時間 + //Debug.Log($"Team [{teamId}] updateMode:{(int)tdata.updateMode}"); + float frameDeltaTime = tdata.IsFixedUpdate ? unityFrameFixedDeltaTime : (tdata.IsUnscaled ? unityFrameUnscaledDeltaTime : unityFrameDeltaTime); + tdata.frameDeltaTime = frameDeltaTime; + float deltaTime = frameDeltaTime; + + // タイムスケール + float timeScale = tdata.timeScale * (tdata.IsUnscaled ? 1.0f : globalTimeScale); + timeScale = tdata.flag.IsSet(Flag_SyncSuspend) ? 0.0f : timeScale; + tdata.nowTimeScale = timeScale; // 最終計算用タイムスケール + + // 加算時間 + float addTime = deltaTime * timeScale; // 今回の加算時間 + + // 時間を加算 + float time = tdata.time + addTime; + //Debug.Log($"[{i}] time:{time}, addTime:{addTime}, timeScale:{timeScale}, suspend:{tdata.flag.IsSet(Flag_Suspend)}"); + float interval = time - tdata.nowUpdateTime; + + // 今回の予定更新回数 + int updateCount = (int)(interval / simulationDeltaTime); + + // 今回の更新回数(最大更新回数まで) + tdata.updateCount = math.min(updateCount, maxSimmulationCountPerFrame); + + // 今回のスキップ回数(最大更新回数超過分) + tdata.skipCount = updateCount - tdata.updateCount; + if (tdata.skipCount > 0) + { + // スキップ発生時はスキップ時間を無かったものとする + time = time - simulationDeltaTime * tdata.skipCount; + } + + if (tdata.updateCount > 0 && addTime == 0.0f) + { + // SimulationDeltaTime加算の誤差が発生! + // ステップ毎のnowUpdateTime += tdata.SimulationDeltaTimeが誤差を蓄積 + // その結果addTime=0でもintervalが一回分となり処理がまわってしまう + // こうなると時間補間関連で0除算が発生して数値が壊れる + // 誤差を修正する + tdata.updateCount = 0; + tdata.skipCount = 0; + tdata.nowUpdateTime = time - simulationDeltaTime + 0.0001f; + } + + // 時間まわり更新 + if (tdata.updateCount > 0) + { + // 更新時のフレーム開始時間 + tdata.frameOldTime = tdata.frameUpdateTime; + tdata.frameUpdateTime = time; + + // 前回の更新時間 + tdata.oldUpdateTime = tdata.nowUpdateTime; + + //Debug.Log($"TeamUpdate!:{i}"); + } + tdata.oldTime = tdata.time; + tdata.time = time; + + // シミュレーション実行フラグ + tdata.flag.SetBits(Flag_Running, tdata.updateCount > 0); + + teamDataArray[teamId] = tdata; + + // 全体の最大実行回数 + maxCount = math.max(maxCount, tdata.updateCount); + + //Debug.Log($"[{teamId}] updateCount:{tdata.updateCount}, skipCount:{tdata.skipCount}, addtime:{addTime}, t.time:{tdata.time}, t.oldtime:{tdata.oldTime}, timeScale:{tdata.timeScale}"); + + // ジョブ情報の作成 + bool isSplitTeam = false; + bool isSelfCollisionJob = tdata.flag.IsSet(Flag_Self_PointPrimitive) + || tdata.flag.IsSet(Flag_Self_EdgePrimitive) + || tdata.flag.IsSet(Flag_Self_TrianglePrimitive); + if (isSelfCollisionJob) + { + // セルフコリジョン + // Splitジョブ + batchSplitClothTeamList.Add(teamId); + isSplitTeam = true; + splitSelfCollisionCount++; + } + else + { + // セルフコリジョンなしではプロキシメッシュの頂点数が一定以上なら分割する + if (tdata.ParticleCount >= splitProxyMeshVertexCount) + { + // Splitジョブ + batchSplitClothTeamList.Add(teamId); + isSplitTeam = true; + } + else + { + // Normalジョブ + batchNormalClothTeamList.Add(teamId); + } + } + + // SplitチームのPoint/Edgeコリジョンの有無 + if (isSplitTeam && tdata.UseColliderCount > 0) + { + if (param.colliderCollisionConstraint.mode == ColliderCollisionConstraint.Mode.Point) + splitPointCollisionCount++; + if (param.colliderCollisionConstraint.mode == ColliderCollisionConstraint.Mode.Edge) + splitEdgeCollisionCount++; + } + } + + teamStatus.Value = new int4(maxCount, splitPointCollisionCount, splitEdgeCollisionCount, splitSelfCollisionCount); + } + + void DistanceCullingUpdate(int teamId, ref TeamData tdata, ref ClothParameters param) + { + // 現在の状態 + bool oldInvisible = tdata.IsDistanceCullingInvisible; + bool invisible; + + // 距離カリングの有無 + if (param.culling.useDistanceCulling) + { + // 距離カリング有効 + // 距離判定 + MagicaObjectId transformId = teamDistanceTransformIndexArray[teamId]; + if (transformPositionMap.ContainsKey(transformId)) + { + // 現在コンポーネント位置(pos)は同期を取っていない + // これは2つのコンポーネントが同じ階層と同じ位置であることを想定しているためである + // そのため2つのコンポーネントの位置がずれていると予期せぬ動作不良を起こす危険性がある + float3 pos = componentPositionArray[tdata.componentTransformIndex]; + + // 参照オブジェクト位置(spos)は同期されている + float3 spos = transformPositionMap[transformId]; + + //Debug.Log($"[{teamId}] pos:{pos}, spos:{spos}"); + //Debug.Log($"[{teamId}] componentTransformIndex:{tdata.componentTransformIndex}, objTransformId:{transformId}"); + + float dist = math.distance(pos, spos); + float cullingDist = param.culling.distanceCullingLength; + if (hasMainCamera == false && tdata.componentTransformIndex == 0) + cullingDist = 1000000.0f; // メインカメラnull時の安全対策 + invisible = dist >= cullingDist; + + // フェードウエイト + float fadeDist = math.saturate(param.culling.distanceCullingFadeRatio) * cullingDist; + tdata.distanceWeight = 1.0f - math.saturate(math.unlerp(cullingDist - fadeDist, cullingDist, dist)); + } + else + { + // 距離カリング無効 + invisible = false; + tdata.distanceWeight = 1.0f; + } + } + else + { + // 距離カリング無効 + invisible = false; + tdata.distanceWeight = 1.0f; + } + + // 状態変更 + if (oldInvisible != invisible) + { + tdata.flag.SetBits(Flag_DistanceCullingInvisible, invisible); + //Debug.Log($"Change distance culling invisible:({oldInvisible}) -> ({invisible})"); + + // 距離カリングでは表示/非表示切替時に常にリセットする + // またカメラカリングのKeepは強制解除する + tdata.flag.SetBits(Flag_Reset, true); + tdata.flag.SetBits(Flag_CameraCullingKeep, false); + + // メインスレッド処理用のリストに追加する + cullingDirtyList.Add(teamId); + } + } + } + + internal void RemoveSyncParent(ref TeamData tdata, int parentTeamId) + { + tdata.syncParentTeamId.MC2RemoveItemAtSwapBack(parentTeamId); + } + + //========================================================================================= + /// + /// ここに登録されるのはClothコンポーネントがDisable時に初期化されたプロセス + /// これらのプロセスはマネージャ側で消滅が監視される + /// + HashSet monitoringProcessSet = new HashSet(); + List disposeProcessList = new List(); + + internal void AddMonitoringProcess(ClothProcess cprocess) + { + Develop.Assert(cprocess != null); + monitoringProcessSet.Add(cprocess); + } + + internal void RemoveMonitoringProcess(ClothProcess cprocess) + { + Develop.Assert(cprocess != null); + if (monitoringProcessSet.Contains(cprocess)) + monitoringProcessSet.Remove(cprocess); + } + + /// + /// コンポーネントDisable時に初期化されたClothProcessを監視し消滅していたらマネージャ側からメモリを開放する + /// + /// + void MonitoringProcess(bool force) + { + disposeProcessList.Clear(); + foreach (var cprocess in monitoringProcessSet) + { + if (cprocess.cloth == null || force) + { + // 消滅を検出 + Develop.DebugLog($"Detection MagicaCloth destroy!"); + disposeProcessList.Add(cprocess); + } + } + + // 消滅したClothを破棄する + if (disposeProcessList.Count > 0) + { + disposeProcessList.ForEach(cprocess => cprocess.Dispose()); + disposeProcessList.Clear(); + } + if (force) + { + monitoringProcessSet.Clear(); + } + } + + void MonitoringProcessUpdate() => MonitoringProcess(false); + + //========================================================================================= + // Simulation + //========================================================================================= + /// + /// チームごとのセンター姿勢の決定と慣性用の移動量計算 + /// および風の影響を計算 + /// + internal static void SimulationCalcCenterAndInertiaAndWind( + float simulationDeltaTime, + + // team + int teamId, + ref TeamData tdata, + ref InertiaConstraint.CenterData cdata, + ref TeamWindData windData, + ref ClothParameters param, + + // vmesh + in NativeArray positions, + in NativeArray rotations, + in NativeArray vertexBindPoseRotations, + + // inertia + in NativeArray fixedArray, + + // transform + in NativeArray transformPositionArray, + in NativeArray transformRotationArray, + in NativeArray transformScaleArray, + + // wind + int windZoneCount, + in NativeArray windDataArray + ) + { + // ■コンポーネントトランスフォーム同期 + // 同期中は同期先のコンポーネントトランスフォームからワールド慣性を計算する + int centerTransformIndex = (tdata.syncTeamId != 0 && tdata.flag.IsSet(Flag_Synchronization)) ? tdata.syncCenterTransformIndex : cdata.centerTransformIndex; + + // ■コンポーネント姿勢 + float3 componentWorldPos = transformPositionArray[centerTransformIndex]; + quaternion componentWorldRot = transformRotationArray[centerTransformIndex]; + float3 componentWorldScl = transformScaleArray[cdata.centerTransformIndex]; // ただしスケールは同期させない!(v2.11.1) + cdata.componentWorldPosition = componentWorldPos; + cdata.componentWorldRotation = componentWorldRot; + cdata.componentWorldScale = componentWorldScl; + //Debug.Log($"componentWorldPos:{componentWorldPos}, componentWorldRot:{componentWorldRot.value}"); + + // コンポーネントスケール倍率 + float componentScaleRatio = math.length(componentWorldScl) / math.length(tdata.initScale); + + // ■マイナススケール + // マイナススケールの場合は計算に必要なデータを予め作成しておく + float3 oldInverseScaleDirection = tdata.negativeScaleDirection; + tdata.negativeScaleDirection = math.sign(componentWorldScl); // 各スケールの方向(1/-1) + tdata.negativeScaleChange = oldInverseScaleDirection * tdata.negativeScaleDirection; // 今回スケール反転された方向(1:変化なし, -1:反転あり) + //Debug.Log($"inverseScaleChange:{tdata.inverseScaleChange}"); + if (componentWorldScl.x < 0 || componentWorldScl.y < 0 || componentWorldScl.z < 0) + { + tdata.negativeScaleSign = -1; // マイナススケール時は(-1) + tdata.negativeScaleQuaternionValue = new float4(-math.sign(componentWorldScl), 1); // 回転反転用 + tdata.negativeScaleTriangleSign.x = (componentWorldScl.x < 0 || componentWorldScl.z < 0) ? -1 : 1; // TriangleBendingの法線フリップフラグ + tdata.negativeScaleTriangleSign.y = componentWorldScl.x < 0 ? -1 : 1; // TriangleBendingの接線フリップフラグ + tdata.flag.SetBits(Flag_NegativeScale, true); + } + else + { + tdata.negativeScaleSign = 1; + tdata.negativeScaleQuaternionValue = 1; + tdata.negativeScaleTriangleSign = 1; + tdata.flag.SetBits(Flag_NegativeScale, false); + } + // 以前とスケール方向が変わっていたいたら軸反転テレポートを行う + if (oldInverseScaleDirection.Equals(tdata.negativeScaleDirection) == false) + { + // 軸反転テレポート + // 本体がスケール反転するためシミュレーションに影響が出ないように必要な座標系を同様に反転させる + // 一旦クロスローカル空間に戻し軸反転してからワールドに書き戻す + tdata.flag.SetBits(Flag_NegativeScaleTeleport, true); + //Debug.LogWarning($"Negative Scale detection!"); + + // コンポーネント反転用マトリックス + float4x4 nowComponentLW = float4x4.TRS(componentWorldPos, componentWorldRot, componentWorldScl); + float4x4 oldComponentLW = float4x4.TRS(cdata.oldComponentWorldPosition, cdata.oldComponentWorldRotation, cdata.oldComponentWorldScale); + float4x4 componentNegativeM = math.mul(nowComponentLW, math.inverse(oldComponentLW)); + + // コンポーネント空間のものを反転させる + // Transformに関するものは回転を反転させる必要はない + cdata.oldComponentWorldPosition = MathUtility.TransformPoint(cdata.oldComponentWorldPosition, componentNegativeM); + cdata.oldComponentWorldScale = componentWorldScl; // スケールはリセット + cdata.oldAnchorPosition = MathUtility.TransformPoint(cdata.oldAnchorPosition, componentNegativeM); + cdata.smoothingVelocity = MathUtility.TransformVector(cdata.smoothingVelocity, componentNegativeM); + } + + float3 oldComponentWorldPosition = cdata.oldComponentWorldPosition; + quaternion oldComponentWorldRotation = cdata.oldComponentWorldRotation; + float3 oldComponentWorldScale = cdata.oldComponentWorldScale; + + // ■クロスセンター位置 + var centerWorldPos = componentWorldPos; + var centerWorldRot = componentWorldRot; + + // 固定点リストがある場合は固定点の姿勢から算出する、ない場合はクロストランスフォームを使用する + if (tdata.fixedDataChunk.IsValid) + { + float3 cen = 0; + float3 nor = 0; + float3 tan = 0; + + int v_start = tdata.proxyCommonChunk.startIndex; + + int fcnt = tdata.fixedDataChunk.dataLength; + int fstart = tdata.fixedDataChunk.startIndex; + for (int i = 0; i < fcnt; i++) + { + var l_findex = fixedArray[fstart + i]; + int vindex = l_findex + v_start; + + cen += positions[vindex]; + + var rot = rotations[vindex]; + + // マイナススケール + if (tdata.negativeScaleSign < 0) + { + MathUtility.ToNormalTangent(rot, out float3 n, out float3 t); + rot = MathUtility.ToRotation(-n, -t); + } + + // 頂点バインドポーズを乗算して初期姿勢の一定方向に合わせる + rot = math.mul(rot, vertexBindPoseRotations[vindex]); + + nor += MathUtility.ToNormal(rot); + tan += MathUtility.ToTangent(rot); + } + + // マイナススケール + nor *= (tdata.negativeScaleDirection.x < 0 || tdata.negativeScaleDirection.z < 0) ? -1 : 1; + tan *= (tdata.negativeScaleDirection.x < 0 || tdata.negativeScaleDirection.y < 0) ? -1 : 1; + +#if MC2_DEBUG + Develop.Assert(math.length(nor) > 0.0f); + Develop.Assert(math.length(tan) > 0.0f); +#endif + centerWorldPos = cen / fcnt; + centerWorldRot = MathUtility.ToRotation(math.normalize(nor), math.normalize(tan)); // 単位化必須 + } + var wtol = MathUtility.WorldToLocalMatrix(centerWorldPos, centerWorldRot, componentWorldScl); + //Debug.Log($"centerWorldPos:{centerWorldPos}, centerWorldRot:{centerWorldRot.value}"); + //Debug.Log($"centerWorldRot nor:{math.mul(centerWorldRot, math.up())}, tan:{math.mul(centerWorldRot, math.forward())}, bin:{math.mul(centerWorldRot, math.right())}"); + + // ■マイナススケール + if (tdata.IsNegativeScaleTeleport) + { + // センター反転用変換マトリックスを計算(2) + float4x4 nowLW = float4x4.TRS(centerWorldPos, centerWorldRot, componentWorldScl); + float4x4 oldLW = float4x4.TRS(cdata.oldFrameWorldPosition, cdata.oldFrameWorldRotation, cdata.oldFrameWorldScale); + float4x4 negativeM = math.mul(nowLW, math.inverse(oldLW)); + cdata.negativeScaleMatrix = negativeM; + } + + // ■アンカー + float3 anchorDeltaVector = 0; + quaternion anchorDeltaRotation = quaternion.identity; + if (tdata.flag.IsSet(Flag_AnchorReset) || tdata.IsReset) + { + cdata.oldAnchorPosition = cdata.anchorPosition; + cdata.oldAnchorRotation = cdata.anchorRotation; + cdata.anchorComponentLocalPosition = MathUtility.InverseTransformPoint(componentWorldPos, cdata.anchorPosition, cdata.anchorRotation, 1); + } + if (tdata.flag.IsSet(Flag_Anchor)) + { + // アンカーの移動回転影響 + float3 anchorCenterPosition = MathUtility.TransformPoint(cdata.anchorComponentLocalPosition, cdata.anchorPosition, cdata.anchorRotation, 1); + anchorDeltaVector = anchorCenterPosition - oldComponentWorldPosition; + anchorDeltaRotation = MathUtility.FromToRotation(cdata.oldAnchorRotation, cdata.anchorRotation); + + // アンカーの影響割合 + float anchorRatio = 1.0f - param.inertiaConstraint.anchorInertia; + anchorDeltaVector = math.lerp(float3.zero, anchorDeltaVector, anchorRatio); + anchorDeltaRotation = math.slerp(quaternion.identity, anchorDeltaRotation, anchorRatio); + + // 打ち消す + oldComponentWorldPosition += anchorDeltaVector; + oldComponentWorldRotation = math.mul(anchorDeltaRotation, oldComponentWorldRotation); + + tdata.flag.SetBits(Flag_InertiaShift, true); + } + + // フレーム移動量と速度 + float3 frameDeltaVector = componentWorldPos - oldComponentWorldPosition; + float frameDeltaAngle = MathUtility.Angle(oldComponentWorldRotation, componentWorldRot); + //Debug.Log($"frameDeltaVector:{frameDeltaVector}, frameDeltaAngle:{frameDeltaAngle}"); + + // ■テレポート判定(コンポーネント姿勢から判定する) + // 同期時は同期先のテレポートモードとパラメータが入っている + if (param.inertiaConstraint.teleportMode != InertiaConstraint.TeleportMode.None && tdata.IsReset == false) + { + // 移動と回転どちらか一方がしきい値を超えたらテレポートと判定 + bool isTeleport = false; + isTeleport = math.length(frameDeltaVector) >= param.inertiaConstraint.teleportDistance * componentScaleRatio ? true : isTeleport; + isTeleport = math.degrees(frameDeltaAngle) >= param.inertiaConstraint.teleportRotation ? true : isTeleport; + + if (isTeleport) + { + //Debug.Log($"[{teamId}] Auto Teleport!"); + switch (param.inertiaConstraint.teleportMode) + { + case InertiaConstraint.TeleportMode.Reset: + tdata.flag.SetBits(Flag_Reset, true); + break; + case InertiaConstraint.TeleportMode.Keep: + tdata.flag.SetBits(Flag_KeepTeleport, true); + break; + } + } + } + + // ■スムージング + // ワールド慣性の急激な変化および小刻みな変化によりクロスが乱れる問題を解消するために慣性をスムージングする + // ・慣性の急激な変化(急発進・急停止)によるクロスの乱れの緩和 + // ・慣性の小刻みな変化によるクロスの振動の緩和 + float3 smoothDeltaVector = 0; +#if true + if (param.inertiaConstraint.movementInertiaSmoothing >= 1e-06f && !(tdata.IsKeepReset || tdata.IsReset)) + { + // 慣性速度をスムージングする + // 測定はシミュレーションが実行される場合のみ行う(そうしないと振動が発生する) + if (tdata.IsRunning) + { + float3 frameDeltaVelocity = tdata.frameDeltaTime > 0.0f ? frameDeltaVector / tdata.frameDeltaTime : 0; // 速度ベクトル(m/s) + float movementSpeedLimit = param.inertiaConstraint.movementSpeedLimit * componentScaleRatio; // 同期時は同期先の値が入っている + if (movementSpeedLimit >= 0.0f) + { + // 最大速度制限 + frameDeltaVelocity = MathUtility.ClampVector(frameDeltaVelocity, movementSpeedLimit); + } + float averageRatio = math.saturate(math.pow(1.0f - param.inertiaConstraint.movementInertiaSmoothing, 3.0f) * 0.99f + 0.01f); + cdata.smoothingVelocity = math.lerp(cdata.smoothingVelocity, frameDeltaVelocity, averageRatio); // 比重により平滑化 + } + //Debug.Log($"smoothingVelocity:{cdata.smoothingVelocity}"); + + // スムージングした慣性速度に基づいて1つ前のコンポーネント位置を補正する + // 処理的にはアンカーと同じ考え + float3 smoothPos = componentWorldPos - cdata.smoothingVelocity * tdata.frameDeltaTime; + smoothDeltaVector = smoothPos - oldComponentWorldPosition; + oldComponentWorldPosition = smoothPos; + tdata.flag.SetBits(Flag_InertiaShift, true); + } +#endif + + // リセットおよび最新のセンター座標として格納 + cdata.frameWorldPosition = centerWorldPos; + cdata.frameWorldRotation = centerWorldRot; + cdata.frameWorldScale = componentWorldScl; + if (tdata.IsReset) + { + //Debug.LogWarning($"Team Reset!"); + cdata.oldComponentWorldPosition = componentWorldPos; + cdata.oldComponentWorldRotation = componentWorldRot; + cdata.oldComponentWorldScale = componentWorldScl; + oldComponentWorldPosition = componentWorldPos; + oldComponentWorldRotation = componentWorldRot; + oldComponentWorldScale = componentWorldScl; + + cdata.oldFrameWorldPosition = centerWorldPos; + cdata.oldFrameWorldRotation = centerWorldRot; + cdata.oldFrameWorldScale = componentWorldScl; + cdata.nowWorldPosition = centerWorldPos; + cdata.nowWorldRotation = centerWorldRot; + //cdata.nowWorldScale = centerWorldScl; + cdata.oldWorldPosition = centerWorldPos; + cdata.oldWorldRotation = centerWorldRot; + //tdata.centerWorldPosition = centerWorldPos; + } + else if (tdata.IsNegativeScaleTeleport) + { + // マイナススケール + // センター空間に関するものはリセットする + //Debug.LogWarning($"Team NegativeScale Reset!"); + cdata.oldFrameWorldPosition = centerWorldPos; + cdata.oldFrameWorldRotation = centerWorldRot; + cdata.oldFrameWorldScale = componentWorldScl; + cdata.nowWorldPosition = centerWorldPos; + cdata.nowWorldRotation = centerWorldRot; + //cdata.nowWorldScale = centerWorldScl; + cdata.oldWorldPosition = centerWorldPos; + cdata.oldWorldRotation = centerWorldRot; + //tdata.centerWorldPosition = centerWorldPos; + } + + // ■ワールド慣性シフト + float3 workOldComponentPosition = oldComponentWorldPosition; + quaternion workOldComponentRotation = oldComponentWorldRotation; + if (tdata.IsReset) + { + // リセット(なし) + cdata.frameComponentShiftVector = 0; + cdata.frameComponentShiftRotation = quaternion.identity; + + // スムージングリセット + cdata.smoothingVelocity = 0; + smoothDeltaVector = 0; + } + else + { + cdata.frameComponentShiftVector = componentWorldPos - oldComponentWorldPosition; + cdata.frameComponentShiftRotation = MathUtility.FromToRotation(oldComponentWorldRotation, componentWorldRot); + //Debug.Log($"frameComponentShiftVector:{cdata.frameComponentShiftVector}, frameComponentShiftRotation:{cdata.frameComponentShiftRotation.value}"); + float moveShiftRatio = 0.0f; + float rotationShiftRatio = 0.0f; + + // ■全体慣性シフト + float movementShift = 1.0f - param.inertiaConstraint.worldInertia; // 同期時は同期先の値が入っている + float rotationShift = 1.0f - param.inertiaConstraint.worldInertia; // 同期時は同期先の値が入っている + + // KeepテレポートもしくはCulling時はシフト量100%で実装 + //bool keep = tdata.IsKeepReset || tdata.IsCameraCullingInvisible; + bool keep = tdata.IsKeepReset || tdata.IsCullingInvisible; + movementShift = keep ? 1.0f : movementShift; + rotationShift = keep ? 1.0f : rotationShift; + + if (movementShift > Define.System.Epsilon || rotationShift > Define.System.Epsilon) + { + // 全体シフトあり + tdata.flag.SetBits(Flag_InertiaShift, true); + moveShiftRatio = movementShift; + rotationShiftRatio = rotationShift; + + workOldComponentPosition = math.lerp(workOldComponentPosition, componentWorldPos, movementShift); + workOldComponentRotation = math.slerp(workOldComponentRotation, componentWorldRot, rotationShift); + } + + // ■最大移動速度制限(全体シフトの結果から計算する) + float movementSpeedLimit = param.inertiaConstraint.movementSpeedLimit * componentScaleRatio; // 同期時は同期先の値が入っている + float rotationSpeedLimit = param.inertiaConstraint.rotationSpeedLimit; // 同期時は同期先の値が入っている + float3 deltaVector = componentWorldPos - workOldComponentPosition; + float deltaAngle = MathUtility.Angle(workOldComponentRotation, componentWorldRot); + float frameSpeed = tdata.frameDeltaTime > 0.0f ? math.length(deltaVector) / tdata.frameDeltaTime : 0.0f; + float frameRotationSpeed = tdata.frameDeltaTime > 0.0f ? math.degrees(deltaAngle) / tdata.frameDeltaTime : 0.0f; + if (frameSpeed > movementSpeedLimit && movementSpeedLimit >= 0.0f) + { + tdata.flag.SetBits(Flag_InertiaShift, true); + float moveLimitRatio = math.saturate(math.max(frameSpeed - movementSpeedLimit, 0.0f) / frameSpeed); + moveShiftRatio = math.lerp(moveShiftRatio, 1.0f, moveLimitRatio); + workOldComponentPosition = math.lerp(workOldComponentPosition, componentWorldPos, moveLimitRatio); + } + if (frameRotationSpeed > rotationSpeedLimit && rotationSpeedLimit >= 0.0f) + { + tdata.flag.SetBits(Flag_InertiaShift, true); + float rotationLimitRatio = math.saturate(math.max(frameRotationSpeed - rotationSpeedLimit, 0.0f) / frameRotationSpeed); + rotationShiftRatio = math.lerp(rotationShiftRatio, 1.0f, rotationLimitRatio); + workOldComponentRotation = math.slerp(workOldComponentRotation, componentWorldRot, rotationLimitRatio); + } + + // その他の影響 + float otherShiftRatio = 0.0f; + + // 更新スキップによるシフト + // 更新スキップ時はスキップ時間分ワールド慣性シフトを行う + if (tdata.skipCount > 0) + { + otherShiftRatio = math.lerp(otherShiftRatio, 1.0f, math.saturate((tdata.skipCount * simulationDeltaTime) / (tdata.frameDeltaTime * tdata.nowTimeScale))); + } + + // 安定化時間中は慣性を抑える + if (tdata.velocityWeight < 1.0f) + { + otherShiftRatio = math.lerp(otherShiftRatio, 1.0f, 1.0f - tdata.velocityWeight); + } + + // タイムスケール + // タイムスケールの影響分ワールド慣性シフトを行う + if (tdata.nowTimeScale < 1.0f) + { + otherShiftRatio = math.lerp(otherShiftRatio, 1.0f, 1.0f - tdata.nowTimeScale); + } + + if (otherShiftRatio > 0.0f) + { + tdata.flag.SetBits(Flag_InertiaShift, true); + moveShiftRatio = math.lerp(moveShiftRatio, 1.0f, otherShiftRatio); + workOldComponentPosition = math.lerp(workOldComponentPosition, componentWorldPos, otherShiftRatio); + rotationShiftRatio = math.lerp(rotationShiftRatio, 1.0f, otherShiftRatio); + workOldComponentRotation = math.slerp(workOldComponentRotation, componentWorldRot, otherShiftRatio); + } + + // ■慣性シフト最終設定 + if (tdata.IsInertiaShift) + { + //Debug.Log($"moveShiftRatio:{moveShiftRatio}, rotationShiftRatio:{rotationShiftRatio}"); + + cdata.frameComponentShiftVector *= moveShiftRatio; + cdata.frameComponentShiftRotation = math.slerp(quaternion.identity, cdata.frameComponentShiftRotation, rotationShiftRatio); + + // アンカーによる打ち消し + cdata.frameComponentShiftVector += anchorDeltaVector; + cdata.frameComponentShiftRotation = math.mul(anchorDeltaRotation, cdata.frameComponentShiftRotation); + + // スムージング影響打ち消し + cdata.frameComponentShiftVector += smoothDeltaVector; + + cdata.oldFrameWorldPosition = MathUtility.ShiftPosition(cdata.oldFrameWorldPosition, cdata.oldComponentWorldPosition, cdata.frameComponentShiftVector, cdata.frameComponentShiftRotation); + cdata.oldFrameWorldRotation = math.mul(cdata.frameComponentShiftRotation, cdata.oldFrameWorldRotation); + + cdata.nowWorldPosition = MathUtility.ShiftPosition(cdata.nowWorldPosition, cdata.oldComponentWorldPosition, cdata.frameComponentShiftVector, cdata.frameComponentShiftRotation); + cdata.nowWorldRotation = math.mul(cdata.frameComponentShiftRotation, cdata.nowWorldRotation); + } + } + //Debug.Log($"team:[{teamId}] frameComponentShiftVector:{cdata.frameComponentShiftVector}, frameComponentShiftRotation:{cdata.frameComponentShiftRotation}"); + //Debug.Log($"team:[{teamId}] centerTransformIndex:{centerTransformIndex}"); + //Debug.Log($"team:[{teamId}] worldInertia:{param.inertiaConstraint.worldInertia}"); + //Debug.Log($"team:[{teamId}] movementSpeedLimit:{param.inertiaConstraint.movementSpeedLimit}"); + //Debug.Log($"team:[{teamId}] rotationSpeedLimit:{param.inertiaConstraint.rotationSpeedLimit}"); + + // ■ワールド移動方向と速度割り出し(慣性シフト後の移動量で計算) + float3 movingVector = componentWorldPos - workOldComponentPosition; + float movingLength = math.length(movingVector); + cdata.frameMovingSpeed = tdata.frameDeltaTime > 0.0f ? movingLength / tdata.frameDeltaTime : 0.0f; + cdata.frameMovingSpeed *= tdata.nowTimeScale > 1e-06f ? 1.0f / tdata.nowTimeScale : 0.0f; // タイムスケール考慮 + cdata.frameMovingDirection = movingLength > 1e-06f ? movingVector / movingLength : 0; + + //Debug.Log($"frameWorldPosition:{cdata.frameWorldPosition}, framwWorldRotation:{cdata.frameWorldRotation.value}"); + //Debug.Log($"oldFrameWorldPosition:{cdata.oldFrameWorldPosition}, oldFrameWorldRotation:{cdata.oldFrameWorldRotation.value}"); + //Debug.Log($"nowWorldPosition:{cdata.nowWorldPosition}, nowWorldRotation:{cdata.nowWorldRotation.value}"); + //Debug.Log($"oldWorldPosition:{cdata.oldWorldPosition}, oldWorldRotation:{cdata.oldWorldRotation.value}"); + + // センターローカル座標 + float3 localCenterPos = MathUtility.InverseTransformPoint(centerWorldPos, wtol); + cdata.frameLocalPosition = localCenterPos; + + // 速度安定化処理 + if (tdata.flag.IsSet(Flag_Reset) || tdata.flag.IsSet(Flag_TimeReset)) + { + tdata.velocityWeight = param.stablizationTimeAfterReset > 1e-06f ? 0.0f : 1.0f; + tdata.blendWeight = tdata.velocityWeight; + } + + // 風の影響を計算 ======================================================== + //var oldTeamWindData = teamWindArray[teamId]; + var newTeamWindData = new TeamWindData(); + if (windZoneCount > 0 && param.wind.IsValid()) + { + float minVolume = float.MaxValue; + int addWindCount = 0; + int latestWindId = -1; + + for (int windId = 0; windId < windZoneCount; windId++) + { + var wdata = windDataArray[windId]; + if (wdata.IsValid() == false || wdata.IsEnable() == false) + continue; + + // チームが風エリアに入っているか判定する + // 加算風は最大3つまで + bool isAdditin = wdata.IsAddition(); + if (isAdditin && addWindCount >= 3) + continue; + + // 風ゾーンのローカル位置 + float3 lpos = math.transform(wdata.worldToLocalMatrix, centerWorldPos); + float llen = math.length(lpos); + + // エリア判定 + switch (wdata.mode) + { + case MagicaWindZone.Mode.BoxDirection: + var lv = math.abs(lpos) * 2; + if (lv.x > wdata.size.x || lv.y > wdata.size.y || lv.z > wdata.size.z) + continue; + break; + case MagicaWindZone.Mode.SphereDirection: + case MagicaWindZone.Mode.SphereRadial: + if (llen > wdata.size.x) + continue; + break; + } + + // エリア風の場合はボリューム判定(体積が小さいものが優先) + if (isAdditin == false && wdata.zoneVolume > minVolume) + continue; + + // 風の方向(world) + float3 mainDirection = wdata.worldWindDirection; + switch (wdata.mode) + { + case MagicaWindZone.Mode.SphereRadial: + if (llen <= 1e-06f) + continue; + var v = centerWorldPos - wdata.worldPositin; + mainDirection = math.normalize(v); + break; + } + //Debug.Log($"wdir:{mainDirection}"); + + // 風力 + float windMain = wdata.main; + switch (wdata.mode) + { + case MagicaWindZone.Mode.SphereRadial: + // 減衰 + if (llen <= 1e-06f) + continue; + float depth = math.saturate(llen / wdata.size.x); + float attenuation = wdata.attenuation.MC2EvaluateCurveClamp01(depth); + windMain *= attenuation; + break; + } + + // 計算する風として登録する + var windInfo = new TeamWindInfo() + { + windId = windId, + time = -Define.System.WindMaxTime, // マイナス値からスタート + main = windMain, + direction = mainDirection + }; + if (isAdditin) + { + newTeamWindData.AddOrReplaceWindZone(windInfo, windData); + addWindCount++; + } + else + { + newTeamWindData.RemoveWindZone(latestWindId); + newTeamWindData.AddOrReplaceWindZone(windInfo, windData); + minVolume = wdata.zoneVolume; + latestWindId = windId; + } + } + } + + // 移動風移植 + newTeamWindData.movingWind = windData.movingWind; + windData.CopyFrom(newTeamWindData); + } + + /// + /// ステップごとの前処理(ステップの開始に実行される) + /// + internal static void SimulationStepTeamUpdate( + int updateIndex, + float simulationDeltaTime, + // team + int teamId, + ref TeamData tdata, + ref ClothParameters param, + ref InertiaConstraint.CenterData cdata, + ref TeamWindData wdata + ) + { + // ■ステップ実行時のみ処理する + bool runStep = updateIndex < tdata.updateCount; + tdata.flag.SetBits(Flag_StepRunning, runStep); + + //Debug.Log($"team[{teamId}] ({updateIndex}/{tdata.updateCount})"); + + // ■時間更新 --------------------------------------------------- + // nowUpdateTime更新 + tdata.nowUpdateTime += simulationDeltaTime; + + // 今回のフレーム割合を計算する + // frameStartTimeからtime区間でのnowUpdateTimeの割合 + //tdata.frameInterpolation = (tdata.nowUpdateTime - tdata.frameOldTime) / (tdata.time - tdata.frameOldTime); + // 念の為、0除算チェックと0-1クランプを入れる + float b = tdata.time - tdata.frameOldTime; + tdata.frameInterpolation = b > 0 ? math.saturate((tdata.nowUpdateTime - tdata.frameOldTime) / b) : 1.0f; + + //Debug.Log($"Team[{teamId}] time.{tdata.time}, oldTime:{tdata.oldTime}, frameTime:{tdata.frameUpdateTime}, frameOldTime:{tdata.frameOldTime}, nowUpdateTime:{tdata.nowUpdateTime}, frameInterp:{tdata.frameInterpolation}"); + + // ■センター --------------------------------------------------- + // 現在ステップでのセンタートランスフォーム姿勢を求める + cdata.oldWorldPosition = cdata.nowWorldPosition; + cdata.oldWorldRotation = cdata.nowWorldRotation; + cdata.nowWorldPosition = math.lerp(cdata.oldFrameWorldPosition, cdata.frameWorldPosition, tdata.frameInterpolation); + cdata.nowWorldRotation = math.slerp(cdata.oldFrameWorldRotation, cdata.frameWorldRotation, tdata.frameInterpolation); + cdata.nowWorldRotation = math.normalize(cdata.nowWorldRotation); // 必要 + float3 wscl = math.lerp(cdata.oldFrameWorldScale, cdata.frameWorldScale, tdata.frameInterpolation); + //cdata.nowWorldScale = wscl; + + // ステップごとの移動量 + cdata.stepVector = cdata.nowWorldPosition - cdata.oldWorldPosition; + cdata.stepRotation = MathUtility.FromToRotation(cdata.oldWorldRotation, cdata.nowWorldRotation); + float stepAngle = MathUtility.Angle(cdata.oldWorldRotation, cdata.nowWorldRotation); + //Debug.Log($"Team[{teamId}] stepVector:{cdata.stepVector}, stepRotation:{cdata.stepRotation}, stepAngle:{stepAngle}"); + //Debug.Log($"Team[{teamId}] stepVector:{math.length(cdata.stepVector)}, frameInterpolation:{tdata.frameInterpolation}"); + + // ローカル慣性 + float localMovementInertia = 1.0f - param.inertiaConstraint.localInertia; + float localRotationInertia = 1.0f - param.inertiaConstraint.localInertia; +#if true + float3 localVector = cdata.stepVector * (1.0f - localMovementInertia); + float localMovementSpeed = math.length(localVector) / simulationDeltaTime; // ローカル移動速度(m/s) + if (localMovementSpeed > param.inertiaConstraint.localMovementSpeedLimit && param.inertiaConstraint.localMovementSpeedLimit >= 0.0f) + { + float t = param.inertiaConstraint.localMovementSpeedLimit / localMovementSpeed; + localMovementInertia = math.lerp(1.0f, localMovementInertia, t); + } + float localAngle = stepAngle * (1.0f - localRotationInertia); + float localAngleSpeed = math.degrees(localAngle / simulationDeltaTime); // ローカル回転速度(deg/s) + if (localAngleSpeed > param.inertiaConstraint.localRotationSpeedLimit && param.inertiaConstraint.localRotationSpeedLimit >= 0.0f) + { + float t = param.inertiaConstraint.localRotationSpeedLimit / localAngleSpeed; + localRotationInertia = math.lerp(1.0f, localRotationInertia, t); + } +#endif + cdata.stepMoveInertiaRatio = localMovementInertia; + cdata.stepRotationInertiaRatio = localRotationInertia; + + // 最終慣性 + cdata.inertiaVector = math.lerp(float3.zero, cdata.stepVector, localMovementInertia); + cdata.inertiaRotation = math.slerp(quaternion.identity, cdata.stepRotation, localRotationInertia); + //Debug.Log($"Team[{teamId}] localMovementInertia:{localMovementInertia}, localRotationInertia:{localRotationInertia}, inertiaVector:{cdata.inertiaVector}, inertiaRotation:{cdata.inertiaRotation}"); + + // ■遠心力用パラメータ算出 + // 今回ステップでの回転速度と回転軸 + cdata.angularVelocity = stepAngle / simulationDeltaTime; // 回転速度(rad/s) + if (cdata.angularVelocity > Define.System.Epsilon) + MathUtility.ToAngleAxis(cdata.stepRotation, out _, out cdata.rotationAxis); + else + cdata.rotationAxis = 0; + //Debug.Log($"Team[{teamId}] angularVelocity:{math.degrees(cdata.angularVelocity)}, axis:{cdata.rotationAxis}, q:{cdata.stepRotation.value}"); + //Debug.Log($"Team[{teamId}] angularVelocity:{math.degrees(cdata.angularVelocity)}, now:{cdata.nowWorldRotation.value}, old:{cdata.oldWorldRotation.value}"); + + // チームスケール倍率 + tdata.scaleRatio = math.max(math.length(wscl) / math.length(tdata.initScale), 1e-06f); + //Debug.Log($"[{teamId}] scaleRatio:{tdata.scaleRatio}"); + + // ■重力方向割合 --------------------------------------------------- + float gravityDot = 1.0f; + if (math.lengthsq(param.worldGravityDirection) > Define.System.Epsilon) + { + // マイナススケール + float3 initLocalGravityDirection = cdata.initLocalGravityDirection; + initLocalGravityDirection.y *= tdata.negativeScaleDirection.y; // Yマイナススケール時のみY軸を反転 + + var worldFalloffDir = math.mul(cdata.nowWorldRotation, initLocalGravityDirection); + gravityDot = math.dot(worldFalloffDir, param.worldGravityDirection); + gravityDot = math.saturate(gravityDot * 0.5f + 0.5f); + } + tdata.gravityDot = gravityDot; + //Develop.DebugLog($"gdot:{gravityDot}"); + + // ■重力減衰 --------------------------------------------------- + float gravityRatio = 1.0f; + if (param.gravity > 1e-06f && param.gravityFalloff > 1e-06f) + { + gravityRatio = math.lerp(math.saturate(1.0f - param.gravityFalloff), 1.0f, math.saturate(1.0f - gravityDot)); + } + tdata.gravityRatio = gravityRatio; + + // 速度安定化時間の速度割合を更新 + if (tdata.velocityWeight < 1.0f) + { + float addw = param.stablizationTimeAfterReset > 1e-06f ? simulationDeltaTime / param.stablizationTimeAfterReset : 1.0f; + tdata.velocityWeight = math.saturate(tdata.velocityWeight + addw); + } + //Debug.Log($"{tdata.velocityWeight}"); + + // シミュレーション結果のブレンド割合 + tdata.blendWeight = math.saturate(tdata.velocityWeight * param.blendWeight * tdata.distanceWeight); + //Debug.Log($"{tdata.blendWeight}"); + + // 風の時間更新 + UpdateWind(simulationDeltaTime, teamId, tdata, param.wind, cdata, ref wdata); + + //Debug.Log($"[{updateIndex}/{updateCount}] frameRatio:{data.frameInterpolation}, inertiaPosition:{idata.inertiaPosition}"); + } + + // 各風ゾーンの時間更新 + static void UpdateWind( + float simulationDeltaTime, + int teamId, + in TeamData tdata, + in WindParams windParams, + in InertiaConstraint.CenterData cdata, + ref TeamWindData teamWindData + ) + { + if (windParams.IsValid() == false) + return; + + // ゾーン風 + int cnt = teamWindData.ZoneCount; + for (int i = 0; i < cnt; i++) + { + var windInfo = teamWindData.windZoneList[i]; + UpdateWindTime(ref windInfo, windParams.frequency, simulationDeltaTime); + teamWindData.windZoneList[i] = windInfo; + } + + // 移動風 + var movingWindInfo = teamWindData.movingWind; + movingWindInfo.main = 0; + if (windParams.movingWind > 0.01f) + { + movingWindInfo.main = (cdata.frameMovingSpeed * windParams.movingWind) / tdata.scaleRatio; + movingWindInfo.direction = -cdata.frameMovingDirection; + UpdateWindTime(ref movingWindInfo, windParams.frequency, simulationDeltaTime); + } + teamWindData.movingWind = movingWindInfo; + } + + static void UpdateWindTime(ref TeamWindInfo windInfo, float frequency, float simulationDeltaTime) + { + // 風速係数 + float mainRatio = windInfo.main / Define.System.WindBaseSpeed; // 0.0 ~ + + // 基本周期 + float freq = 0.2f + mainRatio * 0.5f; + freq *= frequency; // 0.0 ~ 2.0f; + freq = math.min(freq, 1.5f); // max 1.5 + freq *= simulationDeltaTime; + + // 時間加算 + windInfo.time = windInfo.time + freq; + + // timeオーバーフロー対策 + if (windInfo.time > Define.System.WindMaxTime) // 約6時間 + windInfo.time -= Define.System.WindMaxTime * 2; // マイナス側から再スタート + } + + /// + /// クロスシミュレーション更新後処理 + /// + internal static void SimulationPostTeamUpdate( + // team + ref TeamData tdata, + ref InertiaConstraint.CenterData cdata + ) + { + // コンポーネント位置 + cdata.oldComponentWorldPosition = cdata.componentWorldPosition; + cdata.oldComponentWorldRotation = cdata.componentWorldRotation; + cdata.oldComponentWorldScale = cdata.componentWorldScale; + + if (tdata.IsRunning) + { + // センターを更新 + cdata.oldFrameWorldPosition = cdata.frameWorldPosition; + cdata.oldFrameWorldRotation = cdata.frameWorldRotation; + cdata.oldFrameWorldScale = cdata.frameWorldScale; + + // 外力クリア + tdata.forceMode = ClothForceMode.None; + tdata.impactForce = 0; + + // スキップ + tdata.skipCount = 0; + } + + // アンカー + cdata.oldAnchorPosition = cdata.anchorPosition; + cdata.oldAnchorRotation = cdata.anchorRotation; + cdata.anchorComponentLocalPosition = MathUtility.InverseTransformPoint(cdata.componentWorldPosition, cdata.anchorPosition, cdata.anchorRotation, 1); + + // フラグリセット + tdata.flag.SetBits(Flag_Reset, false); + tdata.flag.SetBits(Flag_TimeReset, false); + tdata.flag.SetBits(Flag_Running, false); + tdata.flag.SetBits(Flag_StepRunning, false); + tdata.flag.SetBits(Flag_KeepTeleport, false); + tdata.flag.SetBits(Flag_InertiaShift, false); + tdata.flag.SetBits(Flag_NegativeScaleTeleport, false); + + // 時間調整(floatの精度問題への対処) + const float limitTime = 3600.0f; // 60min + if (tdata.time > limitTime * 2) + { + tdata.time -= limitTime; + tdata.oldTime -= limitTime; + tdata.nowUpdateTime -= limitTime; + tdata.oldUpdateTime -= limitTime; + tdata.frameUpdateTime -= limitTime; + tdata.frameOldTime -= limitTime; + } + } + + //========================================================================================= + public void InformationLog(StringBuilder allsb) + { + StringBuilder sb = new StringBuilder(); + + sb.AppendLine($"========== Team Manager =========="); + if (IsValid() == false) + { + sb.AppendLine($"Team Manager. Invalid."); + sb.AppendLine(); + Debug.Log(sb.ToString()); + allsb.Append(sb); + } + else + { + sb.AppendLine($"Team Manager. Team:{TeamCount}, Mapping:{MappingCount}, Monitoring:{monitoringProcessSet.Count}"); + sb.AppendLine($" -teamDataArray:{teamDataArray.ToSummary()}"); + sb.AppendLine($" -teamWindArray:{teamWindArray.ToSummary()}"); + sb.AppendLine($" -mappingDataArray:{mappingDataArray.ToSummary()}"); + sb.AppendLine($" -parameterArray:{parameterArray.ToSummary()}"); + sb.AppendLine($" -centerDataArray:{centerDataArray.ToSummary()}"); + Debug.Log(sb.ToString()); + allsb.Append(sb); + + for (int i = 1; i < TeamCount; i++) + { + var tdata = teamDataArray[i]; + if (tdata.IsValid == false) + continue; + + sb.Clear(); + + var mappingList = teamMappingIndexArray[i]; + + var cprocess = GetClothProcess(i); + if (cprocess == null) + { + sb.AppendLine($"ID:{i} cprocess is null!"); + Debug.LogWarning(sb.ToString()); + allsb.Append(sb); + continue; + } + var cloth = cprocess.cloth; + if (cloth == null) + { + sb.AppendLine($"ID:{i} cloth is null!"); + Debug.LogWarning(sb.ToString()); + allsb.Append(sb); + continue; + } + + sb.AppendLine($"ID:{i} [{cprocess.Name}] state:0x{cprocess.GetStateFlag().Value:X}, Flag:0x{tdata.flag.Value:X}, Particle:{tdata.ParticleCount}, Collider:{cprocess.colliderDict.Count} Proxy:{tdata.proxyMeshType}, Mapping:{mappingList.Length}"); + sb.AppendLine($" -centerTransformIndex {tdata.centerTransformIndex}"); + sb.AppendLine($" -initScale {tdata.initScale}"); + sb.AppendLine($" -scaleRatio {tdata.scaleRatio}"); + sb.AppendLine($" -animationPoseRatio {tdata.animationPoseRatio}"); + sb.AppendLine($" -blendWeight {tdata.blendWeight}"); + + // 同期 + sb.AppendLine($" Sync:{cloth.SyncPartnerCloth}, SyncParentCount:{tdata.syncParentTeamId.Length}"); + + // chunk情報 + sb.AppendLine($" -ProxyTransformChunk {tdata.proxyTransformChunk}"); + sb.AppendLine($" -ProxyCommonChunk {tdata.proxyCommonChunk}"); + sb.AppendLine($" -ProxyMeshChunk {tdata.proxyMeshChunk}"); + sb.AppendLine($" -ProxyBoneChunk {tdata.proxyBoneChunk}"); + sb.AppendLine($" -ProxySkinBoneChunk {tdata.proxySkinBoneChunk}"); + sb.AppendLine($" -ProxyTriangleChunk {tdata.proxyTriangleChunk}"); + sb.AppendLine($" -ProxyEdgeChunk {tdata.proxyEdgeChunk}"); + sb.AppendLine($" -BaseLineChunk {tdata.baseLineChunk}"); + sb.AppendLine($" -BaseLineDataChunk {tdata.baseLineDataChunk}"); + sb.AppendLine($" -ParticleChunk {tdata.particleChunk}"); + sb.AppendLine($" -ColliderChunk {tdata.colliderChunk}"); + sb.AppendLine($" -ColliderTrnasformChunk {tdata.colliderTransformChunk}"); + sb.AppendLine($" -colliderCount {tdata.colliderCount}"); + + // mapping情報 + sb.AppendLine($" *Mapping Count {mappingList.Length}"); + if (mappingList.Length > 0) + { + for (int j = 0; j < mappingList.Length; j++) + { + int mid = mappingList[j]; + var mdata = mappingDataArray[mid]; + sb.AppendLine($" *Mapping Mid:{mid}, Vertex:{mdata.VertexCount}"); + sb.AppendLine($" -teamId:{mdata.teamId}"); + sb.AppendLine($" -centerTransformIndex:{mdata.centerTransformIndex}"); + sb.AppendLine($" -mappingCommonChunk:{mdata.mappingCommonChunk}"); + sb.AppendLine($" -toProxyMatrix:{mdata.toProxyMatrix}"); + sb.AppendLine($" -toProxyRotation:{mdata.toProxyRotation}"); + sb.AppendLine($" -sameSpace:{mdata.sameSpace}"); + sb.AppendLine($" -toMappingMatrix:{mdata.toMappingMatrix}"); + sb.AppendLine($" -scaleRatio:{mdata.scaleRatio}"); + sb.AppendLine($" -renderDataWorkIndex:{mdata.renderDataWorkIndex}"); + } + } + + // constraint + sb.AppendLine($" +DistanceStartChunk {tdata.distanceStartChunk}"); + sb.AppendLine($" +DistanceDataChunk {tdata.distanceDataChunk}"); + sb.AppendLine($" +BendingPairChunk {tdata.bendingPairChunk}"); + sb.AppendLine($" +selfPointChunk {tdata.selfPointChunk}"); + sb.AppendLine($" +selfEdgeChunk {tdata.selfEdgeChunk}"); + sb.AppendLine($" +selfTriangleChunk {tdata.selfTriangleChunk}"); + + // wind + var wdata = teamWindArray[i]; + sb.AppendLine($" #Wind ZoneCount:{wdata.ZoneCount}"); + for (int j = 0; j < wdata.ZoneCount; j++) + { + sb.AppendLine($" [{j}] {wdata.windZoneList[j].ToString()}"); + } + sb.AppendLine($" [Move] {wdata.movingWind.ToString()}"); + + + Debug.Log(sb.ToString()); + allsb.Append(sb); + } + allsb.AppendLine(); + + // MappingData + sb.Clear(); + int mappingCount = mappingDataArray.Count; + sb.AppendLine($"#MappingData Count:{mappingCount}"); + for (int i = 0; i < mappingCount; i++) + { + var mdata = mappingDataArray[i]; + if (mdata.IsValid() == false) + continue; + + sb.AppendLine($"[{i}] teamId:{mdata.teamId}, renderDataWorkIndex:{mdata.renderDataWorkIndex}"); + } + Debug.Log(sb.ToString()); + allsb.Append(sb); + } + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/Manager/Team/TeamManager.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Manager/Team/TeamManager.cs.meta new file mode 100644 index 00000000..9f8ff85a --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Manager/Team/TeamManager.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 3a759ca7f68f34f49b63e9bb8551c699 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Manager/Team/TeamManager.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Manager/Team/TeamWindData.cs b/Assets/MagicaCloth2/Scripts/Core/Manager/Team/TeamWindData.cs new file mode 100644 index 00000000..48697c0f --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Manager/Team/TeamWindData.cs @@ -0,0 +1,110 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp + +using Unity.Collections; +using Unity.Mathematics; +using UnityEngine; + +namespace MagicaCloth2 +{ + /// + /// 風ゾーン1つの情報 + /// + public struct TeamWindInfo : IValid + { + public int windId; + public float time; + public float main; + public float3 direction; + + public bool IsValid() + { + return main > 1e-06f; + } + + public override string ToString() + { + return $"windId:{windId}, time:{time}, main:{main}, direction:{direction}"; + } + + public void DebugLog() + { + Debug.Log(ToString()); + } + } + + /// + /// チームに影響する風ゾーンと移動風の情報 + /// + public struct TeamWindData + { + public FixedList128Bytes windZoneList; + public TeamWindInfo movingWind; + + + public int ZoneCount => windZoneList.Length; + + public int IndexOf(int windId) + { + int cnt = windZoneList.Length; + for (int i = 0; i < cnt; i++) + { + if (windZoneList[i].windId == windId) + return i; + } + return -1; + } + + public void ClearZoneList() + { + windZoneList.Clear(); + } + + public void AddOrReplaceWindZone(TeamWindInfo windInfo, in TeamWindData oldWindData) + { + if (windInfo.IsValid() == false) + return; + + int i = oldWindData.IndexOf(windInfo.windId); + if (i >= 0) + { + // 旧データに存在する場合はtimeを引き継ぐ + var oldWindInfo = oldWindData.windZoneList[i]; + windInfo.time = oldWindInfo.time; + } + + windZoneList.AddNoResize(windInfo); + } + + public void RemoveWindZone(int windId) + { + int i = IndexOf(windId); + if (i >= 0) + { + windZoneList.RemoveAtSwapBack(i); + } + } + + public void CopyFrom(in TeamWindData wdata) + { + windZoneList = wdata.windZoneList; + movingWind = wdata.movingWind; + } + + //public void DebugLog(int teamId) + //{ + // Debug.Log($"TeamWindData:{teamId}, zoneCnt:{ZoneCount}"); + // for (int i = 0; i < ZoneCount; i++) + // { + // windZoneList[i].DebugLog(); + // } + + // if (movingWind.IsValid()) + // { + // Debug.Log("Moving"); + // movingWind.DebugLog(); + // } + //} + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/Manager/Team/TeamWindData.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Manager/Team/TeamWindData.cs.meta new file mode 100644 index 00000000..30095ea4 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Manager/Team/TeamWindData.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: a3aa95cb25a154343ba918a4fa7f4e26 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Manager/Team/TeamWindData.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Manager/TransformManager.meta b/Assets/MagicaCloth2/Scripts/Core/Manager/TransformManager.meta new file mode 100644 index 00000000..70b15536 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Manager/TransformManager.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: f7a265c09484f0d4d88e3798b515b83f +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/MagicaCloth2/Scripts/Core/Manager/TransformManager/TransformData.cs b/Assets/MagicaCloth2/Scripts/Core/Manager/TransformManager/TransformData.cs new file mode 100644 index 00000000..75bd6ed4 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Manager/TransformManager/TransformData.cs @@ -0,0 +1,967 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using System; +using System.Collections.Generic; +using System.Text; +using Unity.Burst; +using Unity.Collections; +using Unity.Jobs; +using Unity.Mathematics; +using UnityEngine; +using UnityEngine.Jobs; + +namespace MagicaCloth2 +{ + /// + /// TransformAccessArrayを中心とした一連のTransform管理クラス + /// スレッドで利用できるように様々な工夫を行っている + /// + public partial class TransformData : IDisposable + { + internal List transformList; + + /// + /// フラグ(フラグはTransformManagerクラスで定義) + /// + internal ExSimpleNativeArray flagArray; + + /// + /// 初期localPosition + /// + internal ExSimpleNativeArray initLocalPositionArray; + + /// + /// 初期localRotation + /// + internal ExSimpleNativeArray initLocalRotationArray; + + /// + /// ワールド座標 + /// + internal ExSimpleNativeArray positionArray; + + /// + /// ワールド回転 + /// + internal ExSimpleNativeArray rotationArray; + + /// + /// ワールド逆回転 + /// + internal ExSimpleNativeArray inverseRotationArray; + + /// + /// ワールドスケール + /// Transform.lossyScaleと等価 + /// + internal ExSimpleNativeArray scaleArray; + + /// + /// ローカル座標 + /// + internal ExSimpleNativeArray localPositionArray; + + /// + /// ローカル回転 + /// + internal ExSimpleNativeArray localRotationArray; + + /// + /// トランスフォームのインスタンスID + /// + internal ExSimpleNativeArray idArray; + + /// + /// 親トランスフォームのインスタンスID(0=なし) + /// + internal ExSimpleNativeArray parentIdArray; + + /// + /// BoneClothのルートトランスフォームIDリスト + /// + internal List rootIdList; + + /// + /// Transformリストに変更があったかどうか + /// + bool isDirty = false; + + //========================================================================================= + /// + /// Job作業用トランスフォームアクセス配列 + /// データ構築時には利用しない + /// + internal TransformAccessArray transformAccessArray; + + + //========================================================================================= + /// + /// 利用可能な空インデックス + /// + Queue emptyStack; + + //========================================================================================= + public TransformData() { } + + public TransformData(int capacity) + { + // 領域のみ確保する + Init(capacity); + } + + public void Init(int capacity) + { + // 領域のみ確保する + transformList = new List(capacity); + idArray = new ExSimpleNativeArray(capacity, true); + parentIdArray = new ExSimpleNativeArray(capacity, true); + flagArray = new ExSimpleNativeArray(capacity, true); + initLocalPositionArray = new ExSimpleNativeArray(capacity, true); + initLocalRotationArray = new ExSimpleNativeArray(capacity, true); + positionArray = new ExSimpleNativeArray(capacity, true); + rotationArray = new ExSimpleNativeArray(capacity, true); + scaleArray = new ExSimpleNativeArray(capacity, true); + localPositionArray = new ExSimpleNativeArray(capacity, true); + localRotationArray = new ExSimpleNativeArray(capacity, true); + inverseRotationArray = new ExSimpleNativeArray(capacity, true); + emptyStack = new Queue(capacity); + isDirty = true; + } + + public void Dispose() + { + transformList?.Clear(); + idArray?.Dispose(); + parentIdArray?.Dispose(); + flagArray?.Dispose(); + initLocalPositionArray?.Dispose(); + initLocalRotationArray?.Dispose(); + positionArray?.Dispose(); + rotationArray?.Dispose(); + scaleArray?.Dispose(); + localPositionArray?.Dispose(); + localRotationArray?.Dispose(); + inverseRotationArray?.Dispose(); + emptyStack?.Clear(); + + // transformAccessArrayはメインスレッドのみ + if (transformAccessArray.isCreated) + { + transformAccessArray.Dispose(); + } + } + + public int Count => transformList.Count; + public int RootCount => rootIdList?.Count ?? 0; + public bool IsDirty => isDirty; + public bool IsEmpty => transformList == null; + + //========================================================================================= + /// + /// Transform単体を追加する(tidを指定するならスレッド可) + /// すでに登録済みの同じトランスフォームがある場合はそのインデックスを返す + /// + /// + /// Invalidの場合はTransformからGetInstanceId()を即時設定する + /// 不要ならInvalid + /// + /// + //public int AddTransform(Transform t, int tid = 0, int pid = 0, byte flag = TransformManager.Flag_Read, bool checkDuplicate = true) + public int AddTransform(Transform t, MagicaObjectId tid, MagicaObjectId pid, byte flag = TransformManager.Flag_Read, bool checkDuplicate = true) + { + int index; + + // 重複チェック + if (checkDuplicate) + { + index = ReferenceIndexOf(transformList, t); + if (index >= 0) + return index; // 発見 + } + + // 新規追加 + if (emptyStack.Count > 0) + { + index = emptyStack.Dequeue(); + transformList[index] = t; + if (tid.IsValid() == false) + { + // Transformからデータを取得(メインスレッドのみ) + idArray[index] = t.GetMagicaId(); + parentIdArray[index] = t.parent ? t.parent.GetMagicaId() : MagicaObjectId.Invalid; + initLocalPositionArray[index] = t.localPosition; + initLocalRotationArray[index] = t.localRotation; + positionArray[index] = t.position; + rotationArray[index] = t.rotation; + scaleArray[index] = t.lossyScale; + localPositionArray[index] = t.localPosition; + localRotationArray[index] = t.localRotation; + inverseRotationArray[index] = Quaternion.Inverse(t.rotation); + flagArray[index] = new ExBitFlag8(flag); + } + else + { + // 最低限の情報上書き + idArray[index] = tid; + parentIdArray[index] = pid; + initLocalPositionArray[index] = 0; + initLocalRotationArray[index] = quaternion.identity; + positionArray[index] = 0; + rotationArray[index] = quaternion.identity; + scaleArray[index] = 1; + localPositionArray[index] = 0; + localRotationArray[index] = quaternion.identity; + inverseRotationArray[index] = quaternion.identity; + flagArray[index] = new ExBitFlag8(flag); + } + } + else + { + index = Count; + transformList.Add(t); + if (tid.IsValid() == false) + { + // Transformからデータを取得(メインスレッドのみ) + idArray.Add(t.GetMagicaId()); + parentIdArray.Add(t.parent ? t.parent.GetMagicaId() : MagicaObjectId.Invalid); + initLocalPositionArray.Add(t.localPosition); + initLocalRotationArray.Add(t.localRotation); + positionArray.Add(t.position); + rotationArray.Add(t.rotation); + scaleArray.Add(t.lossyScale); + localPositionArray.Add(t.localPosition); + localRotationArray.Add(t.localRotation); + inverseRotationArray.Add(Quaternion.Inverse(t.rotation)); + flagArray.Add(new ExBitFlag8(flag)); + } + else + { + // 領域のみ確保 + idArray.Add(tid); + parentIdArray.Add(pid); + initLocalPositionArray.Add(0); + initLocalRotationArray.Add(quaternion.identity); + positionArray.Add(0); + rotationArray.Add(quaternion.identity); + scaleArray.Add(1); + localPositionArray.Add(0); + localRotationArray.Add(quaternion.identity); + inverseRotationArray.Add(quaternion.identity); + flagArray.Add(new ExBitFlag8(flag)); + } + } + + isDirty = true; + + return index; + } + + /// + /// レコード情報からTransformを登録する(スレッド可) + /// すでに登録済みの同じトランスフォームがある場合はそのインデックスを返す + /// + /// トランスフォーム記録クラス + /// 親のインスタンスID。なければInvalid + /// + /// 重複チェックの有無 + /// + //public int AddTransform(TransformRecord record, int pid = 0, byte flag = TransformManager.Flag_Read, bool checkDuplicate = true) + public int AddTransform(TransformRecord record, MagicaObjectId pid, byte flag = TransformManager.Flag_Read, bool checkDuplicate = true) + { + int index; + + // 重複チェック + if (checkDuplicate) + { + index = ReferenceIndexOf(transformList, record.transform); + if (index >= 0) + return index; // 発見 + } + + // 新規追加 + if (emptyStack.Count > 0) + { + index = emptyStack.Dequeue(); + transformList[index] = record.transform; + idArray[index] = record.id; + parentIdArray[index] = pid; + initLocalPositionArray[index] = record.localPosition; + initLocalRotationArray[index] = record.localRotation; + positionArray[index] = record.position; + rotationArray[index] = record.rotation; + scaleArray[index] = record.scale; + localPositionArray[index] = record.localPosition; + localRotationArray[index] = record.localRotation; + inverseRotationArray[index] = Quaternion.Inverse(record.rotation); + flagArray[index] = new ExBitFlag8(flag); + } + else + { + index = Count; + transformList.Add(record.transform); + idArray.Add(record.id); + parentIdArray.Add(pid); + initLocalPositionArray.Add(record.localPosition); + initLocalRotationArray.Add(record.localRotation); + positionArray.Add(record.position); + rotationArray.Add(record.rotation); + scaleArray.Add(record.scale); + localPositionArray.Add(record.localPosition); + localRotationArray.Add(record.localRotation); + inverseRotationArray.Add(Quaternion.Inverse(record.rotation)); + flagArray.Add(new ExBitFlag8(flag)); + } + + isDirty = true; + return index; + } + + /// + /// 他のTransformDataから追加する + /// + /// + /// + /// 重複チェックの有無 + /// + public int AddTransform(TransformData srcData, int srcIndex, bool checkDuplicate = true) + { + int index; + + // 重複チェック + Transform t = srcData.transformList[srcIndex]; + if (checkDuplicate) + { + index = ReferenceIndexOf(transformList, t); + if (index >= 0) + return index; // 発見 + } + + // 新規追加 + MagicaObjectId id = srcData.idArray[srcIndex]; + MagicaObjectId pid = srcData.parentIdArray[srcIndex]; + var initPos = srcData.initLocalPositionArray[srcIndex]; + var initRot = srcData.initLocalRotationArray[srcIndex]; + var pos = srcData.positionArray[srcIndex]; + var rot = srcData.rotationArray[srcIndex]; + var scl = srcData.scaleArray[srcIndex]; + var lpos = srcData.localPositionArray[srcIndex]; + var lrot = srcData.localRotationArray[srcIndex]; + var irot = srcData.inverseRotationArray[srcIndex]; + var flag = srcData.flagArray[srcIndex]; + if (emptyStack.Count > 0) + { + index = emptyStack.Dequeue(); + transformList[index] = t; + idArray[index] = id; + parentIdArray[index] = pid; + initLocalPositionArray[index] = initPos; + initLocalRotationArray[index] = initRot; + positionArray[index] = pos; + rotationArray[index] = rot; + scaleArray[index] = scl; + localPositionArray[index] = lpos; + localRotationArray[index] = lrot; + inverseRotationArray[index] = irot; + flagArray[index] = flag; + } + else + { + index = Count; + transformList.Add(t); + idArray.Add(id); + parentIdArray.Add(pid); + initLocalPositionArray.Add(initPos); + initLocalRotationArray.Add(initRot); + positionArray.Add(pos); + rotationArray.Add(rot); + scaleArray.Add(scl); + localPositionArray.Add(lpos); + localRotationArray.Add(lrot); + inverseRotationArray.Add(irot); + flagArray.Add(flag); + } + + isDirty = true; + return index; + } + + /// + /// トランスフォーム配列を追加し追加されたインデックスを返す(スレッド可) + /// transform.GetInstanceID()のリストが必要 + /// + /// + /// + public int[] AddTransformRange(List tlist, List idList, List pidList, int copyCount = 0) + { + //int tcnt = tlist.Count; + int tcnt = copyCount > 0 ? copyCount : tlist.Count; + Debug.Assert(tcnt > 0 && tcnt < tlist.Count); + + int startIndex = Count; + int[] indices = new int[tcnt]; + + for (int i = 0; i < tcnt; i++) + { + transformList.Add(tlist[i]); + idArray.Add(idList[i]); + parentIdArray.Add(pidList[i]); + indices[i] = startIndex + i; + } + + // データは領域のみ追加 + flagArray.AddRange(tcnt, new ExBitFlag8(TransformManager.Flag_Read)); // フラグは読み込みとして初期化 + initLocalPositionArray.AddRange(tcnt); + initLocalRotationArray.AddRange(tcnt); + positionArray.AddRange(tcnt); + rotationArray.AddRange(tcnt); + scaleArray.AddRange(tcnt); + localPositionArray.AddRange(tcnt); + localRotationArray.AddRange(tcnt); + inverseRotationArray.AddRange(tcnt); + + // 変更フラグ + isDirty = true; + + return indices; + } + + /// + /// トランスフォームデータから指定したカウントのトランスフォームをコピーする(スレッド可) + /// + /// + /// + /// + public int[] AddTransformRange(TransformData stdata, int copyCount = 0) + { + Debug.Assert(stdata != null); + return AddTransformRange( + stdata.transformList, + new List(stdata.idArray.ToArray()), + new List(stdata.parentIdArray.ToArray()), + copyCount + ); + } + + /// + /// トランスフォーム配列と一部データを追加しインデックスを返す(スレッド可) + /// 残りのデータは即時計算される + /// ※ImportWorkからの作成用 + /// + /// + /// + /// + /// + /// + /// + public int[] AddTransformRange( + List tlist, + List idList, + List pidList, + List rootIds, + NativeArray localPositions, + NativeArray localRotations, + NativeArray positions, + NativeArray rotations, + NativeArray scales, + NativeArray inverseRotations + ) + { + int tcnt = tlist.Count; + Debug.Assert(tcnt > 0); + + int startIndex = Count; + int[] indices = new int[tcnt]; + + transformList.AddRange(tlist); + for (int i = 0; i < tcnt; i++) + { + idArray.Add(idList[i]); + parentIdArray.Add(pidList[i]); + indices[i] = startIndex + i; + } + + // root id + if (rootIds != null && rootIds.Count > 0) + { + if (rootIdList == null) + rootIdList = new List(rootIds); + else + rootIdList.AddRange(rootIds); + } + + // データコピー + flagArray.AddRange(tcnt, new ExBitFlag8(TransformManager.Flag_Read)); // フラグは読み込みとして初期化 + initLocalPositionArray.AddRange(localPositions); + initLocalRotationArray.AddRange(localRotations); + positionArray.AddRange(positions); + rotationArray.AddRange(rotations); + scaleArray.AddRange(scales); + localPositionArray.AddRange(localPositions); + localRotationArray.AddRange(localRotations); + inverseRotationArray.AddRange(inverseRotations); + + // 変更フラグ + isDirty = true; + + return indices; + } + + /// + /// 単体トランスフォームを削除する(スレッド可) + /// 削除は配列インデックスで指定する + /// 削除されたインデックスはキューに追加され再利用される + /// + /// + public void RemoveTransformIndex(int index) + { + // 削除 + transformList[index] = null; + flagArray[index] = new ExBitFlag8(); // フラグのみクリア + emptyStack.Enqueue(index); + } + + /// + /// Transform単体を追加する(tidを指定するならスレッド可) + /// + /// + /// Invalidの場合はTransformからGetInstanceId()を即時設定する + /// 不要ならInvalid + /// + /// + //public int ReplaceTransform(int index, Transform t, int tid = 0, int pid = 0, byte flag = TransformManager.Flag_Read) + public int ReplaceTransform(int index, Transform t, MagicaObjectId tid, MagicaObjectId pid, byte flag = TransformManager.Flag_Read) + { + Debug.Assert(index < Count); + + transformList[index] = t; + flagArray[index] = new ExBitFlag8(flag); + if (tid.IsValid() == false) + { + // Transformからデータを取得(メインスレッドのみ) + idArray[index] = t.GetMagicaId(); + parentIdArray[index] = t.parent ? t.parent.GetMagicaId() : MagicaObjectId.Invalid; + initLocalPositionArray[index] = t.localPosition; + initLocalRotationArray[index] = t.localRotation; + positionArray[index] = t.position; + rotationArray[index] = t.rotation; + scaleArray[index] = t.lossyScale; + localPositionArray[index] = t.localPosition; + localRotationArray[index] = t.localRotation; + } + else + { + // 領域のみ初期化 + idArray[index] = tid; + parentIdArray[index] = pid; + initLocalPositionArray[index] = 0; + initLocalRotationArray[index] = quaternion.identity; + positionArray[index] = 0; + rotationArray[index] = quaternion.identity; + scaleArray[index] = 1; + localPositionArray[index] = 0; + localRotationArray[index] = quaternion.identity; + } + + isDirty = true; + + return index; + } + + /// + /// 純粋なクラスポインタのみのIndexOf()実装 + /// List.IndexOf()はスレッドでは利用できない。 + /// Unity.objectの(==)比較は様々な処理が入りGetInstanceId()を利用してしまうため。 + /// + /// + /// + /// + /// + int ReferenceIndexOf(List list, T item) where T : class + { + if (list == null) + return -1; + for (int i = 0; i < list.Count; i++) + { + if (ReferenceEquals(list[i], item)) + return i; + } + return -1; + } + + //========================================================================================= + /// + /// 作業用バッファの更新(メインスレッドのみ) + /// + public void UpdateWorkData() + { + // 変更がある場合にはtransformAccessArrayを作り直す + if (isDirty) + { + if (transformAccessArray.isCreated) + transformAccessArray.Dispose(); + + transformAccessArray = new TransformAccessArray(transformList.ToArray()); + + isDirty = false; + } + } + + //========================================================================================= + /// + /// Transformを初期姿勢で復元させるジョブを発行する(メインスレッドのみ) + /// + /// + /// + /// + public JobHandle RestoreTransform(int count, JobHandle jobHandle = default(JobHandle)) + { + UpdateWorkData(); + + var job = new RestoreTransformJob() + { + count = count, + flagList = flagArray.GetNativeArray(), + localPositionArray = initLocalPositionArray.GetNativeArray(), + localRotationArray = initLocalRotationArray.GetNativeArray(), + }; + jobHandle = job.Schedule(transformAccessArray, jobHandle); + + return jobHandle; + } + + [BurstCompile] + struct RestoreTransformJob : IJobParallelForTransform + { + public int count; + [Unity.Collections.ReadOnly] + public NativeArray flagList; + + [Unity.Collections.ReadOnly] + public NativeArray localPositionArray; + [Unity.Collections.ReadOnly] + public NativeArray localRotationArray; + + public void Execute(int index, TransformAccess transform) + { + if (index >= count) + return; + if (transform.isValid == false) + return; + + //byte flag = flagList[index]; + //if ((flag & Flag_Write) != 0) + { + transform.SetLocalPositionAndRotation(localPositionArray[index], localRotationArray[index]); + } + } + } + + + //========================================================================================= + /// + /// トランスフォームを読み込むジョブを発行する(メインスレッドのみ) + /// + /// + /// + public JobHandle ReadTransform(JobHandle jobHandle = default(JobHandle)) + { + UpdateWorkData(); + + // todo:未来予測などがあると色々複雑化するところ + + var job = new ReadTransformJob() + { + flagList = flagArray.GetNativeArray(), + positionArray = positionArray.GetNativeArray(), + rotationArray = rotationArray.GetNativeArray(), + scaleList = scaleArray.GetNativeArray(), + localPositionArray = localPositionArray.GetNativeArray(), + localRotationArray = localRotationArray.GetNativeArray(), + inverseRotationArray = inverseRotationArray.GetNativeArray(), + }; + jobHandle = job.ScheduleReadOnly(transformAccessArray, 16, jobHandle); + + return jobHandle; + } + + public void ReadTransformRun() + { + UpdateWorkData(); + var job = new ReadTransformJob() + { + flagList = flagArray.GetNativeArray(), + positionArray = positionArray.GetNativeArray(), + rotationArray = rotationArray.GetNativeArray(), + scaleList = scaleArray.GetNativeArray(), + localPositionArray = localPositionArray.GetNativeArray(), + localRotationArray = localRotationArray.GetNativeArray(), + inverseRotationArray = inverseRotationArray.GetNativeArray(), + }; + job.RunReadOnly(transformAccessArray); + } + + [BurstCompile] + struct ReadTransformJob : IJobParallelForTransform + { + [Unity.Collections.ReadOnly] + public NativeArray flagList; + + [Unity.Collections.WriteOnly] + public NativeArray positionArray; + [Unity.Collections.WriteOnly] + public NativeArray rotationArray; + [Unity.Collections.WriteOnly] + public NativeArray scaleList; + [Unity.Collections.WriteOnly] + public NativeArray localPositionArray; + [Unity.Collections.WriteOnly] + public NativeArray localRotationArray; + [Unity.Collections.WriteOnly] + public NativeArray inverseRotationArray; + + public void Execute(int index, TransformAccess transform) + { + if (transform.isValid == false) + return; + + //byte flag = flagList[index]; + //if ((flag & Flag_Read) != 0) + { + transform.GetPositionAndRotation(out var pos, out var rot); + float4x4 LtoW = transform.localToWorldMatrix; + + positionArray[index] = pos; + rotationArray[index] = rot; + localPositionArray[index] = transform.localPosition; + localRotationArray[index] = transform.localRotation; + + // lossyScale取得(現在はUnity2019.2.14以上のみ) + // マトリックスから正確なスケール値を算出する(これはTransform.lossyScaleと等価) + var irot = math.inverse(rot); + var m2 = math.mul(new float4x4(irot, float3.zero), LtoW); + var scl = new float3(m2.c0.x, m2.c1.y, m2.c2.z); + scaleList[index] = scl; + + // ワールド->ローカル変換用の逆クォータニオン + inverseRotationArray[index] = math.inverse(rot); + } + } + } + + //========================================================================================= +#if false + /// + /// Transformを書き込むジョブを発行する(メインスレッドのみ) + /// + /// + /// + /// + public JobHandle WriteTransform(int count, JobHandle jobHandle = default(JobHandle)) + { + var job = new WriteTransformJob() + { + count = count, + flagList = flagArray.GetNativeArray(), + worldPositions = positionArray.GetNativeArray(), + worldRotations = rotationArray.GetNativeArray(), + localPositions = localPositionArray.GetNativeArray(), + localRotations = localRotationArray.GetNativeArray(), + }; + jobHandle = job.Schedule(transformAccessArray, jobHandle); + + return jobHandle; + } + + [BurstCompile] + struct WriteTransformJob : IJobParallelForTransform + { + public int count; + [Unity.Collections.ReadOnly] + public NativeArray flagList; + + [Unity.Collections.ReadOnly] + public NativeArray worldPositions; + [Unity.Collections.ReadOnly] + public NativeArray worldRotations; + [Unity.Collections.ReadOnly] + public NativeArray localPositions; + [Unity.Collections.ReadOnly] + public NativeArray localRotations; + + public void Execute(int index, TransformAccess transform) + { + if (index >= count) + return; + if (transform.isValid == false) + return; + + var flag = flagList[index]; + if (flag.IsSet(TransformManager.Flag_WorldRotWrite)) + { + // ワールド回転のみ書き込む + //transform.position = worldPositions[index]; + transform.rotation = worldRotations[index]; + } + else if (flag.IsSet(TransformManager.Flag_LocalPosRotWrite)) + { + // ローカル座標・回転を書き込む + transform.localPosition = localPositions[index]; + transform.localRotation = localRotations[index]; + } + } + } +#endif + + //========================================================================================= + /// + /// リダクション結果に基づいてTransformの情報を再編成する(スレッド可) + /// + /// + /// + public void OrganizeReductionTransform(VirtualMesh vmesh, ReductionWorkData workData) + { + // 新しいTransformに対して参照する古いインデックスのリストを作成する + int newSkinBoneCount = workData.newSkinBoneCount.Value; + var oldToNewIndexList = new List(newSkinBoneCount + 2); + + // 最初にスキニング用ボーンを追加する + foreach (var kv in workData.useSkinBoneMap) + { + // スキンボーンの実際のトランスフォームインデックスはskinBoneTransformIndicesに格納されている + oldToNewIndexList.Add(vmesh.skinBoneTransformIndices[kv.Key]); + } + + // skin rootを追加する + int newSkinRootIndex = oldToNewIndexList.Count; + oldToNewIndexList.Add(vmesh.skinRootIndex); + + // center transformを追加する + int newCenterTransformIndex = oldToNewIndexList.Count; + oldToNewIndexList.Add(vmesh.centerTransformIndex); + + // 新しいトランスフォームの数 + int newTransformCount = oldToNewIndexList.Count; + + // 新しい領域 + var newTransformList = new List(newTransformCount); + var newTransformIdArray = new ExSimpleNativeArray(newTransformCount); + var newParentIdArray = new ExSimpleNativeArray(newTransformCount); + var newFlagArray = new ExSimpleNativeArray(newTransformCount); + var newInitLocalPositionArray = new ExSimpleNativeArray(newTransformCount); + var newInitLocalRotationArray = new ExSimpleNativeArray(newTransformCount); + var newPositionArray = new ExSimpleNativeArray(newTransformCount); + var newRotationArray = new ExSimpleNativeArray(newTransformCount); + var newScaleArray = new ExSimpleNativeArray(newTransformCount); + + // データコピー + for (int i = 0; i < newTransformCount; i++) + { + int oldIndex = oldToNewIndexList[i]; + newTransformList.Add(transformList[oldIndex]); + + newTransformIdArray[i] = idArray[oldIndex]; + newParentIdArray[i] = parentIdArray[oldIndex]; + newFlagArray[i] = flagArray[oldIndex]; + newInitLocalPositionArray[i] = initLocalPositionArray[oldIndex]; + newInitLocalRotationArray[i] = initLocalRotationArray[oldIndex]; + newPositionArray[i] = positionArray[oldIndex]; + newRotationArray[i] = rotationArray[oldIndex]; + newScaleArray[i] = scaleArray[oldIndex]; + } + + // 以前の要素を破棄する + transformList.Clear(); + idArray.Dispose(); + parentIdArray.Dispose(); + flagArray.Dispose(); + initLocalPositionArray.Dispose(); + initLocalRotationArray.Dispose(); + positionArray.Dispose(); + rotationArray.Dispose(); + scaleArray.Dispose(); + + // 新しい要素に組み換え + transformList = newTransformList; + idArray = newTransformIdArray; + parentIdArray = newParentIdArray; + flagArray = newFlagArray; + initLocalPositionArray = newInitLocalPositionArray; + initLocalRotationArray = newInitLocalRotationArray; + positionArray = newPositionArray; + rotationArray = newRotationArray; + scaleArray = newScaleArray; + + // 管理情報更新 + emptyStack.Clear(); + + // Virtual Mesh修正 + vmesh.centerTransformIndex = newCenterTransformIndex; + vmesh.skinRootIndex = newSkinRootIndex; + + // Dirty + isDirty = true; + } + + //========================================================================================= + public Transform GetTransformFromIndex(int index) + { + return transformList[index]; + } + + /// + /// IDのトランスフォームインデックスを返す + /// 順次検索なのでコストに注意! + /// + /// + /// -1=見つからない + public int GetTransformIndexFormId(MagicaObjectId id) + { + var array = idArray.GetNativeArray(); + int cnt = Count; + for (int i = 0; i < cnt; i++) + { + if (array[i] == id) + return i; + } + return -1; + } + + public MagicaObjectId GetTransformIdFromIndex(int index) + { + return idArray[index]; + } + + public MagicaObjectId GetParentIdFromIndex(int index) + { + return parentIdArray[index]; + } + + public float4x4 GetLocalToWorldMatrix(int index) + { + var pos = positionArray[index]; + var rot = rotationArray[index]; + var scl = scaleArray[index]; + return Matrix4x4.TRS(pos, rot, scl); + } + + public float4x4 GetWorldToLocalMatrix(int index) + { + return math.inverse(GetLocalToWorldMatrix(index)); + } + + //========================================================================================= + public override string ToString() + { + int transformListCount = transformList?.Count ?? 0; + + StringBuilder sb = new StringBuilder(); + sb.AppendLine("==== TransformData ===="); + sb.AppendLine($"isDirty:{isDirty}"); + sb.AppendLine($"transformList:{transformListCount}"); + sb.AppendLine($"flagArray:{flagArray.Length}"); + + return sb.ToString(); + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/Manager/TransformManager/TransformData.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Manager/TransformManager/TransformData.cs.meta new file mode 100644 index 00000000..3d87f51e --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Manager/TransformManager/TransformData.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 4b71aff9fe4f3ef4bb756f57709e11a0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Manager/TransformManager/TransformData.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Manager/TransformManager/TransformDataSerialization.cs b/Assets/MagicaCloth2/Scripts/Core/Manager/TransformManager/TransformDataSerialization.cs new file mode 100644 index 00000000..8b5b47eb --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Manager/TransformManager/TransformDataSerialization.cs @@ -0,0 +1,117 @@ +// Magica Cloth 2. +// Copyright (c) 2024 MagicaSoft. +// https://magicasoft.jp +using System; +using System.Collections.Generic; +using Unity.Mathematics; +using UnityEngine; + +namespace MagicaCloth2 +{ + public partial class TransformData + { + /// + /// PreBuildの共有部分保存データ + /// + [System.Serializable] + public class ShareSerializationData + { + public ExSimpleNativeArray.SerializationData flagArray; + public ExSimpleNativeArray.SerializationData initLocalPositionArray; + public ExSimpleNativeArray.SerializationData initLocalRotationArray; + } + + public ShareSerializationData ShareSerialize() + { + var sdata = new ShareSerializationData(); + try + { + sdata.flagArray = flagArray.Serialize(); + sdata.initLocalPositionArray = initLocalPositionArray.Serialize(); + sdata.initLocalRotationArray = initLocalRotationArray.Serialize(); + } + catch (Exception exception) + { + Debug.LogException(exception); + } + + return sdata; + } + + public static TransformData ShareDeserialize(ShareSerializationData sdata) + { + if (sdata == null) + return null; + + var tdata = new TransformData(); + try + { + tdata.flagArray = new ExSimpleNativeArray(sdata.flagArray); + tdata.initLocalPositionArray = new ExSimpleNativeArray(sdata.initLocalPositionArray); + tdata.initLocalRotationArray = new ExSimpleNativeArray(sdata.initLocalRotationArray); + } + catch (Exception exception) + { + Debug.LogException(exception); + } + + return tdata; + } + + //========================================================================================= + /// + /// PreBuild固有部分の保存データ + /// + [System.Serializable] + public class UniqueSerializationData : ITransform + { + public Transform[] transformArray; + + 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) + { + for (int i = 0; i < transformArray.Length; i++) + { + var t = transformArray[i]; + if (t) + { + MagicaObjectId id = t.GetMagicaId(); + if (id.IsValid() && replaceDict.ContainsKey(id)) + { + transformArray[i] = replaceDict[id]; + } + } + } + } + } + } + + public UniqueSerializationData UniqueSerialize() + { + var sdata = new UniqueSerializationData(); + try + { + sdata.transformArray = transformList.ToArray(); + } + catch (Exception exception) + { + Debug.LogException(exception); + } + + return sdata; + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/Manager/TransformManager/TransformDataSerialization.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Manager/TransformManager/TransformDataSerialization.cs.meta new file mode 100644 index 00000000..50fc856c --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Manager/TransformManager/TransformDataSerialization.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 7ae8000d77bdbae4b86315fcc83b2518 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Manager/TransformManager/TransformDataSerialization.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Manager/TransformManager/TransformManager.cs b/Assets/MagicaCloth2/Scripts/Core/Manager/TransformManager/TransformManager.cs new file mode 100644 index 00000000..d04164a3 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Manager/TransformManager/TransformManager.cs @@ -0,0 +1,1105 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using System.Text; +using Unity.Burst; +using Unity.Collections; +using Unity.Jobs; +using Unity.Mathematics; +using UnityEngine; +using UnityEngine.Jobs; + +namespace MagicaCloth2 +{ + public class TransformManager : IManager, IValid + { + // フラグ + internal const byte Flag_Read = 0x01; + internal const byte Flag_WorldRotWrite = 0x02; // ワールド回転のみ書き込み + internal const byte Flag_LocalPosRotWrite = 0x04; // ローカル座標・回転書き込み + internal const byte Flag_Restore = 0x08; // 復元する + internal const byte Flag_Enable = 0x10; // 有効状態 + internal ExNativeArray flagArray; + + /// + /// 初期localPosition + /// + internal ExNativeArray initLocalPositionArray; + + /// + /// 初期localRotation + /// + internal ExNativeArray initLocalRotationArray; + + /// + /// シミュレーションの基準となるlocalPosition + /// + internal ExNativeArray baseLocalPositionArray; + + /// + /// シミュレーションの基準となるlocalRotation + /// + internal ExNativeArray baseLocalRotationArray; + + /// + /// ワールド座標 + /// + internal ExNativeArray positionArray; + + /// + /// ワールド回転 + /// + internal ExNativeArray rotationArray; + + /// + /// ワールド逆回転 + /// + //internal ExNativeArray inverseRotationArray; + + /// + /// ワールドスケール + /// Transform.lossyScaleと等価 + /// + internal ExNativeArray scaleArray; + + /// + /// ローカル座標 + /// + internal ExNativeArray localPositionArray; + + /// + /// ローカル回転 + /// + internal ExNativeArray localRotationArray; + + /// + /// ローカルスケール + /// + internal ExNativeArray localScaleArray; + + /// + /// ワールド変換マトリックス + /// + internal ExNativeArray localToWorldMatrixArray; + + /// + /// 接続チームID(0=なし) + /// + internal ExNativeArray teamIdArray; + + /// + /// 読み込み用トランスフォームアクセス配列 + /// この配列は上記の配列グループとインデックが同期している + /// + internal TransformAccessArray transformAccessArray; + + + internal int Count => flagArray?.Count ?? 0; + + //========================================================================================= + /// + /// コンポーネント用ワールド姿勢 + /// + internal ExNativeArray componentPositionArray; + internal ExNativeArray componentMinScaleArray; // このスケール値はXYZの最小の絶対値(用途は0スケール判定) + + /// + /// コンポーネント用トランスフォーム + /// + internal TransformAccessArray componentTransformAccessArray; + + internal NativeReference existFixedTeam; + + bool isValid; + + //========================================================================================= + public void Dispose() + { + isValid = false; + + flagArray?.Dispose(); + initLocalPositionArray?.Dispose(); + initLocalRotationArray?.Dispose(); + baseLocalPositionArray?.Dispose(); + baseLocalRotationArray?.Dispose(); + positionArray?.Dispose(); + rotationArray?.Dispose(); + //inverseRotationArray?.Dispose(); + scaleArray?.Dispose(); + localPositionArray?.Dispose(); + localRotationArray?.Dispose(); + localScaleArray?.Dispose(); + localToWorldMatrixArray?.Dispose(); + teamIdArray?.Dispose(); + //writeIndexArray?.Dispose(); + + flagArray = null; + initLocalPositionArray = null; + initLocalRotationArray = null; + baseLocalPositionArray = null; + baseLocalRotationArray = null; + positionArray = null; + rotationArray = null; + //inverseRotationArray = null; + scaleArray = null; + localPositionArray = null; + localRotationArray = null; + localScaleArray = null; + localToWorldMatrixArray = null; + teamIdArray = null; + //writeIndexArray = null; + + if (transformAccessArray.isCreated) + transformAccessArray.Dispose(); + //if (writeTransformAccessArray.isCreated) + // writeTransformAccessArray.Dispose(); + + componentPositionArray?.Dispose(); + componentMinScaleArray?.Dispose(); + if (componentTransformAccessArray.isCreated) + componentTransformAccessArray.Dispose(); + + if (existFixedTeam.IsCreated) + existFixedTeam.Dispose(); + } + + public void EnterdEditMode() + { + Dispose(); + } + + public void Initialize() + { + Dispose(); + + const int capacity = 256; + flagArray = new ExNativeArray(capacity); + initLocalPositionArray = new ExNativeArray(capacity); + initLocalRotationArray = new ExNativeArray(capacity); + baseLocalPositionArray = new ExNativeArray(capacity); + baseLocalRotationArray = new ExNativeArray(capacity); + positionArray = new ExNativeArray(capacity); + rotationArray = new ExNativeArray(capacity); + //inverseRotationArray = new ExNativeArray(capacity); + scaleArray = new ExNativeArray(capacity); + localPositionArray = new ExNativeArray(capacity); + localRotationArray = new ExNativeArray(capacity); + localScaleArray = new ExNativeArray(capacity); + localToWorldMatrixArray = new ExNativeArray(capacity); + teamIdArray = new ExNativeArray(capacity); + + transformAccessArray = new TransformAccessArray(capacity); + + componentPositionArray = new ExNativeArray(capacity); + componentMinScaleArray = new ExNativeArray(capacity); + componentTransformAccessArray = new TransformAccessArray(capacity); + + existFixedTeam = new NativeReference(Allocator.Persistent); + + isValid = true; + } + + public bool IsValid() + { + return isValid; + } + + //========================================================================================= + /// + /// VirtualMeshのTransformDataを追加する + /// + /// + /// + internal DataChunk AddTransform(VirtualMeshContainer cmesh, int teamId) + { + if (isValid == false) + return default; + + Debug.Assert(cmesh != null); + int cnt = cmesh.GetTransformCount(); + + // データコピー追加 + var c = flagArray.AddRange(cmesh.shareVirtualMesh.transformData.flagArray); + initLocalPositionArray.AddRange(cmesh.shareVirtualMesh.transformData.initLocalPositionArray); + initLocalRotationArray.AddRange(cmesh.shareVirtualMesh.transformData.initLocalRotationArray); + baseLocalPositionArray.AddRange(cmesh.shareVirtualMesh.transformData.initLocalPositionArray); + baseLocalRotationArray.AddRange(cmesh.shareVirtualMesh.transformData.initLocalRotationArray); + + // 領域のみ追加 + positionArray.AddRange(cnt); + rotationArray.AddRange(cnt); + //inverseRotationArray.AddRange(cnt); + scaleArray.AddRange(cnt); + localPositionArray.AddRange(cnt); + localRotationArray.AddRange(cnt); + localScaleArray.AddRange(cnt); + localToWorldMatrixArray.AddRange(cnt); + + // チームID + teamIdArray.AddRange(cnt, (short)teamId); + + // トランスフォーム + int nowcnt = transformAccessArray.length; + + // データチャンクの開始まで埋める + var meshT = cmesh.GetCenterTransform(); + int start = c.startIndex; + while (nowcnt < start) + { + transformAccessArray.Add(meshT); + nowcnt++; + } + + for (int i = 0; i < cnt; i++) + { + Transform t = cmesh.GetTransformFromIndex(i); + if (t == null) + t = meshT; + int index = c.startIndex + i; + if (index < nowcnt) + transformAccessArray[index] = t; + else + transformAccessArray.Add(t); + } + + return c; + } + + /// + /// Transformの領域のみ追加する + /// + /// + /// + internal DataChunk AddTransform(int count, int teamId, Transform t) + { + if (isValid == false) + return default; + + // 領域のみ追加する + var c = flagArray.AddRange(count); + initLocalPositionArray.AddRange(count); + initLocalRotationArray.AddRange(count); + baseLocalPositionArray.AddRange(count); + baseLocalRotationArray.AddRange(count); + positionArray.AddRange(count); + rotationArray.AddRange(count); + //inverseRotationArray.AddRange(count); + scaleArray.AddRange(count); + localPositionArray.AddRange(count); + localRotationArray.AddRange(count); + localScaleArray.AddRange(count); + localToWorldMatrixArray.AddRange(count); + + // チームID + teamIdArray.AddRange(count, (short)teamId); + + // トランスフォームはすべてnullで登録する(Unity6.1でnull登録はNGになった!) + int nowcnt = transformAccessArray.length; + + // データチャンクの開始まで埋める + int start = c.startIndex; + while (nowcnt < start) + { + transformAccessArray.Add(t); + nowcnt++; + } + + for (int i = 0; i < count; i++) + { + //Transform t = null; + int index = c.startIndex + i; + if (index < nowcnt) + transformAccessArray[index] = t; + else + transformAccessArray.Add(t); + } + + return c; + } + + /// + /// Transform1つを追加する + /// + /// + /// + /// + internal DataChunk AddTransform(Transform t, ExBitFlag8 flag, int teamId) + { + if (isValid == false) + return default; + + // データコピー追加 + var c = flagArray.Add(flag); + initLocalPositionArray.Add(t.localPosition); + initLocalRotationArray.Add(t.localRotation); + baseLocalPositionArray.Add(t.localPosition); + baseLocalRotationArray.Add(t.localRotation); + positionArray.Add(t.position); + rotationArray.Add(t.rotation); + //inverseRotationArray.Add(math.inverse(t.rotation)); + scaleArray.Add(t.lossyScale); + localPositionArray.Add(t.localPosition); + localRotationArray.Add(t.localRotation); + localScaleArray.Add(t.localScale); + localToWorldMatrixArray.Add(float4x4.identity); // ここは単位行列 + + // チームID + teamIdArray.Add((short)teamId); + + // トランスフォーム + int nowcnt = transformAccessArray.length; + int index = c.startIndex; + if (index < nowcnt) + transformAccessArray[index] = t; + else + transformAccessArray.Add(t); + + return c; + } + + /// + /// Transform情報を書き換える + /// + /// + /// + /// + internal void SetTransform(Transform t, ExBitFlag8 flag, int index, int teamId) + { + if (isValid == false) + return; + + if (t != null) + { + // データ設定 + flagArray[index] = flag; + initLocalPositionArray[index] = t.localPosition; + initLocalRotationArray[index] = t.localRotation; + baseLocalPositionArray[index] = t.localPosition; + baseLocalRotationArray[index] = t.localRotation; + positionArray[index] = t.position; + rotationArray[index] = t.rotation; + //inverseRotationArray[index] = math.inverse(t.rotation); + scaleArray[index] = t.lossyScale; + localPositionArray[index] = t.localPosition; + localRotationArray[index] = t.localRotation; + localScaleArray[index] = t.localScale; + //localToWorldMatrix[index] = t.localToWorldMatrix; // ここは不要 + teamIdArray[index] = (short)teamId; + transformAccessArray[index] = t; + } + else + { + // データクリア(無効化) + flagArray[index] = default; + transformAccessArray[index] = null; + teamIdArray[index] = 0; + } + } + + /// + /// Transform情報をコピーする + /// + /// + /// + internal void CopyTransform(int fromIndex, int toIndex) + { + if (isValid == false) + return; + + flagArray[toIndex] = flagArray[fromIndex]; + initLocalPositionArray[toIndex] = initLocalPositionArray[fromIndex]; + initLocalRotationArray[toIndex] = initLocalRotationArray[fromIndex]; + baseLocalPositionArray[toIndex] = baseLocalPositionArray[fromIndex]; + baseLocalRotationArray[toIndex] = baseLocalRotationArray[fromIndex]; + positionArray[toIndex] = positionArray[fromIndex]; + rotationArray[toIndex] = rotationArray[fromIndex]; + //inverseRotationArray[toIndex] = inverseRotationArray[fromIndex]; + scaleArray[toIndex] = scaleArray[fromIndex]; + localPositionArray[toIndex] = localPositionArray[fromIndex]; + localRotationArray[toIndex] = localRotationArray[fromIndex]; + localScaleArray[toIndex] = localScaleArray[fromIndex]; + //localToWorldMatrix[toIndex] = localToWorldMatrix[fromIndex]; // ここは不要 + transformAccessArray[toIndex] = transformAccessArray[fromIndex]; + teamIdArray[toIndex] = teamIdArray[fromIndex]; + } + + /// + /// トランスフォームを削除する + /// + /// + internal void RemoveTransform(DataChunk c) + { + if (isValid == false) + return; + if (c.IsValid == false) + return; + + flagArray.RemoveAndFill(c); + initLocalPositionArray.Remove(c); + initLocalRotationArray.Remove(c); + baseLocalPositionArray.Remove(c); + baseLocalRotationArray.Remove(c); + positionArray.Remove(c); + rotationArray.Remove(c); + //inverseRotationArray.Remove(c); + scaleArray.Remove(c); + localPositionArray.Remove(c); + localRotationArray.Remove(c); + localScaleArray.Remove(c); + localToWorldMatrixArray.Remove(c); + teamIdArray.RemoveAndFill(c, 0); + + // トランスフォーム削除 + for (int i = 0; i < c.dataLength; i++) + { + int index = c.startIndex + i; + transformAccessArray[index] = null; + } + } + + /// + /// トランスフォームの有効状態を切り替える + /// + /// + /// true=有効, false=無効 + internal void EnableTransform(DataChunk c, bool sw) + { + if (isValid == false) + return; + if (c.IsValid == false) + return; + + var job = new EnableTransformJob() + { + chunk = c, + sw = sw, + flagList = flagArray.GetNativeArray(), + }; + job.Run(); + } + + [BurstCompile] + struct EnableTransformJob : IJob + { + public DataChunk chunk; + public bool sw; + public NativeArray flagList; + + public void Execute() + { + for (int i = 0; i < chunk.dataLength; i++) + { + int index = chunk.startIndex + i; + + var flag = flagList[index]; + if (flag.Value == 0) + continue; + + flag.SetFlag(Flag_Enable, sw); + flagList[index] = flag; + } + } + } + + /// + /// トランスフォームの有効状態を切り替える + /// + /// + /// true=有効, false=無効 + internal void EnableTransform(int index, bool sw) + { + if (isValid == false) + return; + if (index < 0) + return; + + var flag = flagArray[index]; + if (flag.Value == 0) + return; + flag.SetFlag(Flag_Enable, sw); + flagArray[index] = flag; + } + + internal DataChunk Expand(DataChunk c, int newLength) + { + if (isValid == false) + return default; + + // 領域 + var nc = flagArray.Expand(c, newLength); + initLocalPositionArray.Expand(c, newLength); + initLocalRotationArray.Expand(c, newLength); + baseLocalPositionArray.Expand(c, newLength); + baseLocalRotationArray.Expand(c, newLength); + positionArray.Expand(c, newLength); + rotationArray.Expand(c, newLength); + //inverseRotationArray.Expand(c, newLength); + scaleArray.Expand(c, newLength); + localPositionArray.Expand(c, newLength); + localRotationArray.Expand(c, newLength); + localScaleArray.Expand(c, newLength); + localToWorldMatrixArray.Expand(c, newLength); + + // チームID + teamIdArray.Expand(c, newLength); + + // トランスフォームアクセス配列の拡張 + if (c.startIndex != nc.startIndex) + { + // 旧領域の先頭Transform + Transform frontT = transformAccessArray[c.startIndex]; + + while (transformAccessArray.length < (nc.startIndex + nc.dataLength)) + transformAccessArray.Add(frontT); + + for (int i = 0; i < c.dataLength; i++) + { + Transform t = transformAccessArray[c.startIndex + i]; + transformAccessArray[nc.startIndex + i] = t; + transformAccessArray[c.startIndex + i] = null; + } + } + + return nc; + } + + //========================================================================================= + /// + /// Transformを初期姿勢で復元させるジョブを発行する + /// + /// + /// + /// + public JobHandle RestoreTransform(JobHandle jobHandle) + { + existFixedTeam.Value = false; + if (Count > 0) + { + //Debug.Log("RestoreTransform"); + var job = new RestoreTransformJob() + { + existFixedTeam = existFixedTeam, + + flagList = flagArray.GetNativeArray(), + localPositionArray = initLocalPositionArray.GetNativeArray(), + localRotationArray = initLocalRotationArray.GetNativeArray(), + teamIdArray = teamIdArray.GetNativeArray(), + + teamDataArray = MagicaManager.Team.teamDataArray.GetNativeArray(), + }; + jobHandle = job.Schedule(transformAccessArray, jobHandle); + } + + return jobHandle; + } + + [BurstCompile] + struct RestoreTransformJob : IJobParallelForTransform + { + [NativeDisableParallelForRestriction] + public NativeReference existFixedTeam; + + [Unity.Collections.ReadOnly] + public NativeArray flagList; + + [Unity.Collections.ReadOnly] + public NativeArray localPositionArray; + [Unity.Collections.ReadOnly] + public NativeArray localRotationArray; + [Unity.Collections.ReadOnly] + public NativeArray teamIdArray; + + // team + [Unity.Collections.ReadOnly] + public NativeArray teamDataArray; + + + public void Execute(int index, TransformAccess transform) + { + if (transform.isValid == false) + return; + var flag = flagList[index]; + if (flag.IsSet(Flag_Restore) == false) + return; + + int teamId = teamIdArray[index]; + var tdata = teamDataArray[teamId]; + + // 一度のみ復元フラグが立っている場合は実行する + if (flag.IsSet(Flag_Enable) == false && tdata.flag.IsSet(TeamManager.Flag_RestoreTransformOnlyOnec) == false) + return; + + // Keepカリング時はスキップする + if ((tdata.IsCameraCullingInvisible && tdata.IsCameraCullingKeep) || tdata.IsDistanceCullingInvisible) + return; + + transform.SetLocalPositionAndRotation(localPositionArray[index], localRotationArray[index]); + + // 物理更新チームの存在 + if (tdata.IsFixedUpdate) + existFixedTeam.Value = true; + + //Debug.Log($"RestoreTransform [{index}] lpos:{localPositionArray[index]}, lrot:{localRotationArray[index]}"); + } + } + + //========================================================================================= + /// + /// UnityPhysicsチームかつFixedUpdateが実行されなかったフレームは退避させておいたベース姿勢で再度復元させる + /// + /// + /// + /// + public JobHandle RestoreBaseTransform(JobHandle jobHandle) + { + if (Count > 0) + { + //Debug.Log("RestoreTransform"); + var job = new RestoreBaseTransformJob() + { + flagList = flagArray.GetNativeArray(), + baseLocalPositionArray = baseLocalPositionArray.GetNativeArray(), + baseLocalRotationArray = baseLocalRotationArray.GetNativeArray(), + teamIdArray = teamIdArray.GetNativeArray(), + + teamDataArray = MagicaManager.Team.teamDataArray.GetNativeArray(), + }; + jobHandle = job.Schedule(transformAccessArray, jobHandle); + } + + return jobHandle; + } + + [BurstCompile] + struct RestoreBaseTransformJob : IJobParallelForTransform + { + [Unity.Collections.ReadOnly] + public NativeArray flagList; + [Unity.Collections.ReadOnly] + public NativeArray baseLocalPositionArray; + [Unity.Collections.ReadOnly] + public NativeArray baseLocalRotationArray; + [Unity.Collections.ReadOnly] + public NativeArray teamIdArray; + + // team + [Unity.Collections.ReadOnly] + public NativeArray teamDataArray; + + + public void Execute(int index, TransformAccess transform) + { + if (transform.isValid == false) + return; + var flag = flagList[index]; + if (flag.IsSet(Flag_Restore) == false) + return; + + int teamId = teamIdArray[index]; + var tdata = teamDataArray[teamId]; + + // Fixed更新チームのみ + if (tdata.IsFixedUpdate == false) + return; + + // 一度のみ復元フラグが立っている場合は実行する + if (flag.IsSet(Flag_Enable) == false && tdata.flag.IsSet(TeamManager.Flag_RestoreTransformOnlyOnec) == false) + return; + + // Keepカリング時はスキップする + if ((tdata.IsCameraCullingInvisible && tdata.IsCameraCullingKeep) || tdata.IsDistanceCullingInvisible) + return; + + transform.SetLocalPositionAndRotation(baseLocalPositionArray[index], baseLocalRotationArray[index]); + + //Debug.Log($"RestoreTransform [{index}] lpos:{baseLocalPositionArray[index]}, lrot:{baseLocalRotationArray[index].value}"); + } + } + + //========================================================================================= + /// + /// トランスフォームを読み込むジョブを発行する + /// + /// + /// + public JobHandle ReadTransformSchedule(JobHandle jobHandle) + { + if (Count > 0) + { + var job = new ReadTransformJob() + { + fixedUpdateCount = MagicaManager.Time.FixedUpdateCount, + + flagList = flagArray.GetNativeArray(), + positionArray = positionArray.GetNativeArray(), + rotationArray = rotationArray.GetNativeArray(), + scaleList = scaleArray.GetNativeArray(), + localPositionArray = localPositionArray.GetNativeArray(), + localRotationArray = localRotationArray.GetNativeArray(), + localScaleArray = localScaleArray.GetNativeArray(), + //inverseRotationArray = inverseRotationArray.GetNativeArray(), + localToWorldMatrixArray = localToWorldMatrixArray.GetNativeArray(), + baseLocalPositionArray = baseLocalPositionArray.GetNativeArray(), + baseLocalRotationArray = baseLocalRotationArray.GetNativeArray(), + + teamIdArray = teamIdArray.GetNativeArray(), + + teamDataArray = MagicaManager.Team.teamDataArray.GetNativeArray(), + }; + jobHandle = job.ScheduleReadOnly(transformAccessArray, 8, jobHandle); + } + + return jobHandle; + } + + [BurstCompile] + struct ReadTransformJob : IJobParallelForTransform + { + public int fixedUpdateCount; + + [Unity.Collections.ReadOnly] + public NativeArray flagList; + + [Unity.Collections.WriteOnly] + public NativeArray positionArray; + [Unity.Collections.WriteOnly] + public NativeArray rotationArray; + [Unity.Collections.WriteOnly] + public NativeArray scaleList; + [Unity.Collections.WriteOnly] + public NativeArray localPositionArray; + [Unity.Collections.WriteOnly] + public NativeArray localRotationArray; + [Unity.Collections.WriteOnly] + public NativeArray localScaleArray; + //[Unity.Collections.WriteOnly] + //public NativeArray inverseRotationArray; + [Unity.Collections.WriteOnly] + public NativeArray localToWorldMatrixArray; + [Unity.Collections.WriteOnly] + public NativeArray baseLocalPositionArray; + [Unity.Collections.WriteOnly] + public NativeArray baseLocalRotationArray; + + [Unity.Collections.ReadOnly] + public NativeArray teamIdArray; + + // team + [Unity.Collections.ReadOnly] + public NativeArray teamDataArray; + + public void Execute(int index, TransformAccess transform) + { + if (transform.isValid == false) + return; + var flag = flagList[index]; + if (flag.IsSet(Flag_Enable) == false) + return; + if (flag.IsSet(Flag_Read) == false) + return; + + // カリング時は読み込まない + int teamId = teamIdArray[index]; + var tdata = teamDataArray[teamId]; + if (tdata.IsCullingInvisible) + return; + + transform.GetPositionAndRotation(out var pos, out var rot); + float4x4 LtoW = transform.localToWorldMatrix; + + positionArray[index] = pos; + rotationArray[index] = rot; + localPositionArray[index] = transform.localPosition; + localRotationArray[index] = transform.localRotation; + localScaleArray[index] = transform.localScale; + + // マトリックスから正確なスケール値を算出する(これはTransform.lossyScaleと等価) + var irot = math.inverse(rot); + var m2 = math.mul(new float4x4(irot, float3.zero), LtoW); + var scl = new float3(m2.c0.x, m2.c1.y, m2.c2.z); + scaleList[index] = scl; + + //Debug.Log($"ReadTransform [{index}] pos:{pos}, rot:{rot}, scl:{scl}"); + //Debug.Log($"LtoW:\n{LtoW}"); + + // ワールド->ローカル変換用の逆クォータニオン + //inverseRotationArray[index] = math.inverse(rot); + + // ワールド変換マトリックス + localToWorldMatrixArray[index] = LtoW; + + // 今回の姿勢を基本姿勢として退避させる + // Fixed更新チームかつFixedUpdateが実行されている場合、そもそもFixed更新出ない場合は毎回 + if ((tdata.IsFixedUpdate && fixedUpdateCount > 0) || tdata.IsFixedUpdate == false) + { + baseLocalPositionArray[index] = transform.localPosition; + baseLocalRotationArray[index] = transform.localRotation; + } + + //Debug.Log($"ReadTransform [{index}] pos:{pos}, rot:{rot}"); + } + } + + //========================================================================================= + /// + /// Transformを書き込むジョブを発行する + /// + /// + /// + /// + public JobHandle WriteTransformSchedule(JobHandle jobHandle) + { + var job = new WriteTransformJob() + { + flagList = flagArray.GetNativeArray(), + worldPositions = positionArray.GetNativeArray(), + worldRotations = rotationArray.GetNativeArray(), + localPositions = localPositionArray.GetNativeArray(), + localRotations = localRotationArray.GetNativeArray(), + + teamIdArray = teamIdArray.GetNativeArray(), + + teamDataArray = MagicaManager.Team.teamDataArray.GetNativeArray(), + }; + jobHandle = job.Schedule(transformAccessArray, jobHandle); + + return jobHandle; + } + + [BurstCompile] + struct WriteTransformJob : IJobParallelForTransform + { + [Unity.Collections.ReadOnly] + public NativeArray flagList; + + [Unity.Collections.ReadOnly] + public NativeArray worldPositions; + [Unity.Collections.ReadOnly] + public NativeArray worldRotations; + [Unity.Collections.ReadOnly] + public NativeArray localPositions; + [Unity.Collections.ReadOnly] + public NativeArray localRotations; + + [Unity.Collections.ReadOnly] + public NativeArray teamIdArray; + + // team + [Unity.Collections.ReadOnly] + public NativeArray teamDataArray; + + public void Execute(int index, TransformAccess transform) + { + if (transform.isValid == false) + return; + var flag = flagList[index]; + if (flag.IsSet(Flag_Enable) == false) + return; + + int teamId = teamIdArray[index]; + var tdata = teamDataArray[teamId]; + + // カリング時は書き込まない + if (tdata.IsCullingInvisible) + return; + + // 極小スケール時は書き込まない + if (tdata.IsScaleSuspend) + return; + + // 書き込み停止中ならスキップ + if (tdata.flag.IsSet(TeamManager.Flag_SkipWriting)) + return; + + if (flag.IsSet(Flag_WorldRotWrite)) + { + // ワールド回転 + transform.rotation = worldRotations[index]; + //Debug.Log($"WriteTransform [{index}] (World!) rot:{worldRotations[index]}"); + + // BoneSpringのみワールド座標を書き込む + if (tdata.IsSpring) + { + transform.position = worldPositions[index]; + } + } + else if (flag.IsSet(Flag_LocalPosRotWrite)) + { + // ローカル座標・回転を書き込む + transform.SetLocalPositionAndRotation(localPositions[index], localRotations[index]); + + //Debug.Log($"WriteTransform [{index}] (local!) lpos:{localPositions[index]}, lrot:{localRotations[index]}"); + } + } + } + + //========================================================================================= + /// + /// コンポーネント用トランスフォームの登録 + /// + /// + /// + internal int AddComponentTransform(Transform t) + { + if (isValid == false) + return -1; + Debug.Assert(t); + + int index = componentPositionArray.Add(float3.zero).startIndex; + componentMinScaleArray.Add(1); + + // トランスフォーム + int nowcnt = componentTransformAccessArray.length; + if (index < nowcnt) + componentTransformAccessArray[index] = t; + else + componentTransformAccessArray.Add(t); + + return index; + } + + /// + /// コンポーネント用トランスフォームの削除 + /// + /// + internal void RemoveComponentTransform(int index) + { + if (isValid == false) + return; + if (index < 0) + return; + + componentPositionArray.Remove(index); + componentMinScaleArray.Remove(index); + + // トランスフォーム削除 + componentTransformAccessArray[index] = null; + } + + /// + /// トランスフォームを読み込むジョブを発行する + /// + /// + /// + internal JobHandle ReadComponentTransform(JobHandle jobHandle) + { + if (componentPositionArray.Count > 0) + { + var job = new ReadComponentTransformJob() + { + positionArray = componentPositionArray.GetNativeArray(), + minScaleArray = componentMinScaleArray.GetNativeArray(), + }; + jobHandle = job.ScheduleReadOnly(componentTransformAccessArray, 16, jobHandle); + } + + return jobHandle; + } + + [BurstCompile] + struct ReadComponentTransformJob : IJobParallelForTransform + { + [Unity.Collections.WriteOnly] + public NativeArray positionArray; + [Unity.Collections.WriteOnly] + public NativeArray minScaleArray; + + public void Execute(int index, TransformAccess transform) + { + if (transform.isValid == false) + return; + + positionArray[index] = transform.position; + + // スケールXYZの最小の絶対値 + // コンポーネントの0スケール判定に使用 + float3 scl = transform.localToWorldMatrix.lossyScale; + float minScale = math.cmin(math.abs(scl)); + minScaleArray[index] = minScale; + + //Debug.Log(scl); + //Debug.Log(minScale); + } + } + + + //========================================================================================= + public void InformationLog(StringBuilder allsb) + { + StringBuilder sb = new StringBuilder(); + sb.AppendLine($"========== Transform Manager =========="); + if (IsValid() == false) + { + sb.AppendLine($"Transform Manager. Invalid."); + } + else + { + // transform + int tcnt = transformAccessArray.isCreated ? transformAccessArray.length : 0; + sb.AppendLine($"Transform Manager. Length:{tcnt}"); + sb.AppendLine($" -flagArray:{flagArray.ToSummary()}"); + sb.AppendLine($" -initLocalPositionArray:{initLocalPositionArray.ToSummary()}"); + sb.AppendLine($" -initLocalRotationArray:{initLocalRotationArray.ToSummary()}"); + sb.AppendLine($" -baseLocalPositionArray:{baseLocalPositionArray.ToSummary()}"); + sb.AppendLine($" -baseLocalRotationArray:{baseLocalRotationArray.ToSummary()}"); + sb.AppendLine($" -positionArray:{positionArray.ToSummary()}"); + sb.AppendLine($" -rotationArray:{rotationArray.ToSummary()}"); + //sb.AppendLine($" -inverseRotationArray:{inverseRotationArray.ToSummary()}"); + sb.AppendLine($" -scaleArray:{scaleArray.ToSummary()}"); + sb.AppendLine($" -localPositionArray:{localPositionArray.ToSummary()}"); + sb.AppendLine($" -localRotationArray:{localRotationArray.ToSummary()}"); + sb.AppendLine($" -localScaleArray:{localScaleArray.ToSummary()}"); + sb.AppendLine($" -localToWorldMatirxArray:{localToWorldMatrixArray.ToSummary()}"); + sb.AppendLine($" -teamIdArray:{teamIdArray.ToSummary()}"); + + if (transformAccessArray.isCreated) + { + for (int i = 0; i < tcnt; i++) + { + var t = transformAccessArray[i]; + var flag = flagArray[i]; + var teamId = teamIdArray[i]; + sb.Append($" [{i}] team:{teamId} ("); + sb.Append(flag.IsSet(Flag_Enable) ? "E" : ""); + sb.Append(flag.IsSet(Flag_Restore) ? "R" : ""); + sb.Append(flag.IsSet(Flag_Read) ? "r" : ""); + sb.Append(flag.IsSet(Flag_WorldRotWrite) ? "W" : ""); + sb.Append(flag.IsSet(Flag_LocalPosRotWrite) ? "w" : ""); + if (t) + sb.AppendLine($") {t.name}"); + else + sb.AppendLine($") (null)"); + } + } + + // component + tcnt = componentTransformAccessArray.isCreated ? componentTransformAccessArray.length : 0; + sb.AppendLine($"Component Transform Manager. Length:{tcnt}"); + sb.AppendLine($" -componentPositionArray:{componentPositionArray.ToSummary()}"); + sb.AppendLine($" -componentMinScaleArray:{componentMinScaleArray.ToSummary()}"); + if (componentTransformAccessArray.isCreated) + { + for (int i = 0; i < tcnt; i++) + { + var t = componentTransformAccessArray[i]; + var flag = flagArray[i]; + var teamId = teamIdArray[i]; + sb.Append($" [{i}] team:{teamId} ("); + sb.Append(flag.IsSet(Flag_Enable) ? "E" : ""); + sb.Append(flag.IsSet(Flag_Restore) ? "R" : ""); + sb.Append(flag.IsSet(Flag_Read) ? "r" : ""); + sb.Append(flag.IsSet(Flag_WorldRotWrite) ? "W" : ""); + sb.Append(flag.IsSet(Flag_LocalPosRotWrite) ? "w" : ""); + if (t) + sb.AppendLine($") {t.name}"); + else + sb.AppendLine($") (null)"); + } + } + } + sb.AppendLine(); + Debug.Log(sb.ToString()); + allsb.Append(sb); + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/Manager/TransformManager/TransformManager.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Manager/TransformManager/TransformManager.cs.meta new file mode 100644 index 00000000..65e0c492 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Manager/TransformManager/TransformManager.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: ecc01c078ba26454fb4fd62290d2a22d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Manager/TransformManager/TransformManager.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Manager/TransformManager/TransformRecord.cs b/Assets/MagicaCloth2/Scripts/Core/Manager/TransformManager/TransformRecord.cs new file mode 100644 index 00000000..737b144a --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Manager/TransformManager/TransformRecord.cs @@ -0,0 +1,78 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using System.Collections.Generic; +using UnityEngine; + +namespace MagicaCloth2 +{ + /// + /// トランスフォーム情報の一時記録 + /// + public class TransformRecord : IValid, ITransform + { + public Transform transform; + public MagicaObjectId id; + public Vector3 localPosition; + public Quaternion localRotation; + public Vector3 position; + public Quaternion rotation; + public Vector3 scale; // lossy scale + public Matrix4x4 localToWorldMatrix; + public Matrix4x4 worldToLocalMatrix; + public MagicaObjectId pid; + + public TransformRecord(Transform t, bool read) + { + if (t) + { + transform = t; + id = t.GetMagicaId(); + + if (read) + { + localPosition = t.localPosition; + localRotation = t.localRotation; + position = t.position; + rotation = t.rotation; + scale = t.lossyScale; + localToWorldMatrix = t.localToWorldMatrix; + worldToLocalMatrix = t.worldToLocalMatrix; + } + + if (t.parent) + pid = t.parent.GetMagicaId(); + } + } + + public Vector3 InverseTransformDirection(Vector3 dir) + { + return Quaternion.Inverse(rotation) * dir; + } + + public bool IsValid() + { + return id.IsValid(); + } + + public void GetUsedTransform(HashSet transformSet) + { + transformSet.Add(transform); + } + + public void ReplaceTransform(Dictionary replaceDict) + { + if (replaceDict.ContainsKey(id)) + { + var t = replaceDict[id]; + transform = t; + id = transform.GetMagicaId(); + } + if (replaceDict.ContainsKey(pid)) + { + var t = replaceDict[pid]; + pid = t.GetMagicaId(); + } + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/Manager/TransformManager/TransformRecord.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Manager/TransformManager/TransformRecord.cs.meta new file mode 100644 index 00000000..e3a32625 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Manager/TransformManager/TransformRecord.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 8baf80aea87ff80448fd14763a3a6a94 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Manager/TransformManager/TransformRecord.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Manager/TransformManager/TransformRecordSerializeData.cs b/Assets/MagicaCloth2/Scripts/Core/Manager/TransformManager/TransformRecordSerializeData.cs new file mode 100644 index 00000000..5fb33079 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Manager/TransformManager/TransformRecordSerializeData.cs @@ -0,0 +1,82 @@ +// Magica Cloth 2. +// Copyright (c) 2025 MagicaSoft. +// https://magicasoft.jp +using System.Collections.Generic; +using UnityEngine; + +namespace MagicaCloth2 +{ + [System.Serializable] + public class TransformRecordSerializeData : ITransform + { + public Transform transform; // 利用しないが念の為に記録 + public Vector3 localPosition; + public Quaternion localRotation; + public Vector3 position; + public Quaternion rotation; + public Vector3 scale; // lossy scale + public Matrix4x4 localToWorldMatrix; + public Matrix4x4 worldToLocalMatrix; + + public void Serialize(TransformRecord tr) + { + Debug.Assert(tr != null); + + transform = tr.transform; + localPosition = tr.localPosition; + localRotation = tr.localRotation; + position = tr.position; + rotation = tr.rotation; + scale = tr.scale; + localToWorldMatrix = tr.localToWorldMatrix; + worldToLocalMatrix = tr.worldToLocalMatrix; + } + + public void Deserialize(TransformRecord tr) + { + Debug.Assert(tr != null); + + // 座標系のみ復元する + tr.localPosition = localPosition; + tr.localRotation = localRotation; + tr.position = position; + tr.rotation = rotation; + tr.scale = scale; + tr.localToWorldMatrix = localToWorldMatrix; + tr.worldToLocalMatrix = worldToLocalMatrix; + } + + public int GetLocalHash() + { + int hash = 0; + if (transform) + hash += (123 + transform.childCount * 345); + + return hash; + } + + public int GetGlobalHash() + { + int hash = 0; + + // ローカル姿勢のみ + hash += localPosition.GetHashCode(); + hash += localRotation.GetHashCode(); + + return hash; + } + + public void GetUsedTransform(HashSet transformSet) + { + if (transform) + transformSet.Add(transform); + } + + public void ReplaceTransform(Dictionary replaceDict) + { + MagicaObjectId id = transform != null ? transform.GetMagicaId() : MagicaObjectId.Invalid; + if (id.IsValid() && replaceDict.ContainsKey(id)) + transform = replaceDict[id]; + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/Manager/TransformManager/TransformRecordSerializeData.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Manager/TransformManager/TransformRecordSerializeData.cs.meta new file mode 100644 index 00000000..e8cdb1a5 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Manager/TransformManager/TransformRecordSerializeData.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: f4930f42a38b269439caa19e9603c9aa +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Manager/TransformManager/TransformRecordSerializeData.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Manager/VirtualMesh.meta b/Assets/MagicaCloth2/Scripts/Core/Manager/VirtualMesh.meta new file mode 100644 index 00000000..6d528dd9 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Manager/VirtualMesh.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 0a9459f4f30fe9a4582cc311664181d4 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/MagicaCloth2/Scripts/Core/Manager/VirtualMesh/VirtualMeshManager.cs b/Assets/MagicaCloth2/Scripts/Core/Manager/VirtualMesh/VirtualMeshManager.cs new file mode 100644 index 00000000..c8b39be7 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Manager/VirtualMesh/VirtualMeshManager.cs @@ -0,0 +1,1719 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using System.Text; +using Unity.Burst; +using Unity.Collections; +using Unity.Jobs; +using Unity.Mathematics; +using UnityEngine; + +namespace MagicaCloth2 +{ + /// + /// VirtualMeshの管理マネージャ + /// + public class VirtualMeshManager : IManager, IValid + { + //========================================================================================= + // ■ProxyMesh + //========================================================================================= + // ■共通 + /// + /// 対応するチームID + /// + public ExNativeArray teamIds; + + /// + /// 頂点属性 + /// + public ExNativeArray attributes; + + /// + /// 頂点ごとの接続トライアングルインデックスと法線接線フリップフラグ(最大7つ) + /// これは法線を再計算するために用いられるもので7つあれば十分であると判断したもの。 + /// そのため正確なトライアングル接続を表していない。 + /// データは12-20bitのuintでパックされている + /// 12(hi) = 法線接線のフリップフラグ(法線:0x1,接線:0x2)。ONの場合フリップ。 + /// 20(low) = トライアングルインデックス。 + /// + public ExNativeArray> vertexToTriangles; + + /// + /// 頂点ごとの接続頂点インデックス + /// ※現在未使用 + /// + //public ExNativeArray vertexToVertexIndexArray; + //public ExNativeArray vertexToVertexDataArray; + + /// + /// 頂点ごとのバインドポーズ + /// 頂点バインドにはスケール値は不要 + /// + public ExNativeArray vertexBindPosePositions; + public ExNativeArray vertexBindPoseRotations; + + /// + /// 各頂点の深さ(0.0-1.0) + /// + public ExNativeArray vertexDepths; + + /// + /// 各頂点のルートインデックス(-1=なし) + /// + public ExNativeArray vertexRootIndices; + + /// + /// 各頂点の親からの基準ローカル座標 + /// + public ExNativeArray vertexLocalPositions; + + /// + /// 各頂点の親からの基準ローカル回転 + /// + public ExNativeArray vertexLocalRotations; + + /// + /// 各頂点の親頂点インデックス(-1=なし) + /// + public ExNativeArray vertexParentIndices; + + /// + /// 各頂点の子頂点インデックスリスト + /// + public ExNativeArray vertexChildIndexArray; + public ExNativeArray vertexChildDataArray; + + /// + /// 法線調整用回転 + /// + public ExNativeArray normalAdjustmentRotations; + + /// + /// 各頂点の角度計算用のローカル回転 + /// pitch/yaw個別制限はv1.0では実装しないので一旦停止させる + /// + //public ExNativeArray vertexAngleCalcLocalRotations; + + /// + /// UV + /// VirtualMeshのUVはTangent計算用でありテクスチャマッピング用ではないので注意! + /// + public ExNativeArray uv; + + + public int ProxyVertexCount => teamIds?.Count ?? 0; + + // ■トライアングル ----------------------------------------------------- + public ExNativeArray triangleTeamIdArray; + + /// + /// トライアングル頂点インデックス + /// + public ExNativeArray triangles; + + /// + /// トライアングル法線 + /// + public ExNativeArray triangleNormals; + + /// + /// トライアングル接線 + /// + public ExNativeArray triangleTangents; + + public int ProxyTriangleCount => triangles?.Count ?? 0; + + // ■エッジ ------------------------------------------------------------- + public ExNativeArray edgeTeamIdArray; + + /// + /// エッジ頂点インデックス + /// + public ExNativeArray edges; + + /// + /// エッジ固有フラグ(VirtualMesh.EdgeFlag_~) + /// + public ExNativeArray edgeFlags; + + public int ProxyEdgeCount => edges?.Count ?? 0; + + // ■ベースライン ------------------------------------------------------- + /// + /// ベースラインごとのフラグ + /// + public ExNativeArray baseLineFlags; + + /// + /// ベースラインごとのチームID + /// + public ExNativeArray baseLineTeamIds; + + /// + /// ベースラインごとのデータ開始インデックス + /// + public ExNativeArray baseLineStartDataIndices; + + /// + /// ベースラインごとのデータ数 + /// + public ExNativeArray baseLineDataCounts; + + /// + /// ベースラインデータ(頂点インデックス) + /// + public ExNativeArray baseLineData; + + public int ProxyBaseLineCount => baseLineFlags?.Count ?? 0; + + // ■メッシュ基本(共通) ------------------------------------------------- + public ExNativeArray localPositions; + public ExNativeArray localNormals; + public ExNativeArray localTangents; + public ExNativeArray boneWeights; + public ExNativeArray skinBoneTransformIndices; + public ExNativeArray skinBoneBindPoses; + + public int ProxyLocalPositionCount => localPositions?.Count ?? 0; + + // ■BoneClothのみ ----------------------------------------------------- + public ExNativeArray vertexToTransformRotations; + + // ■最終頂点姿勢 + public ExNativeArray positions; + public ExNativeArray rotations; + + //========================================================================================= + // ■MappingMesh + //========================================================================================= + public ExNativeArray mappingIdArray; // (+1)されているので注意! + public ExNativeArray mappingReferenceIndices; + public ExNativeArray mappingAttributes; + public ExNativeArray mappingLocalPositins; + public ExNativeArray mappingLocalNormals; + public ExNativeArray mappingLocalTangents; + public ExNativeArray mappingBoneWeights; +#if MC2_DEBUG + public ExNativeArray mappingPositions; + //public ExNativeArray mappingNormals; + //public ExNativeArray mappingTangents; +#endif + + public int MappingVertexCount => mappingIdArray?.Count ?? 0; + + //========================================================================================= + bool isValid = false; + + //========================================================================================= + public void Dispose() + { + isValid = false; + + // 作業バッファ + teamIds?.Dispose(); + attributes?.Dispose(); + vertexToTriangles?.Dispose(); + //vertexToVertexIndexArray?.Dispose(); + //vertexToVertexDataArray?.Dispose(); + vertexBindPosePositions?.Dispose(); + vertexBindPoseRotations?.Dispose(); + vertexDepths?.Dispose(); + vertexRootIndices?.Dispose(); + vertexLocalPositions?.Dispose(); + vertexLocalRotations?.Dispose(); + vertexParentIndices?.Dispose(); + vertexChildIndexArray?.Dispose(); + vertexChildDataArray?.Dispose(); + normalAdjustmentRotations?.Dispose(); + //vertexAngleCalcLocalRotations?.Dispose(); + uv?.Dispose(); + teamIds = null; + attributes = null; + vertexToTriangles = null; + //vertexToVertexIndexArray = null; + //vertexToVertexDataArray = null; + vertexBindPosePositions = null; + vertexBindPoseRotations = null; + vertexDepths = null; + vertexRootIndices = null; + vertexLocalPositions = null; + vertexLocalRotations = null; + vertexParentIndices = null; + vertexChildIndexArray = null; + vertexChildDataArray = null; + normalAdjustmentRotations = null; + //vertexAngleCalcLocalRotations = null; + uv = null; + + triangleTeamIdArray?.Dispose(); + triangles?.Dispose(); + triangleNormals?.Dispose(); + triangleTangents?.Dispose(); + triangleTeamIdArray = null; + triangles = null; + triangleNormals = null; + triangleTangents = null; + + edgeTeamIdArray?.Dispose(); + edges?.Dispose(); + edgeFlags?.Dispose(); + edgeTeamIdArray = null; + edges = null; + edgeFlags = null; + + positions?.Dispose(); + rotations?.Dispose(); + positions = null; + rotations = null; + + baseLineFlags?.Dispose(); + baseLineTeamIds?.Dispose(); + baseLineStartDataIndices?.Dispose(); + baseLineDataCounts?.Dispose(); + baseLineData?.Dispose(); + baseLineFlags = null; + baseLineTeamIds = null; + baseLineStartDataIndices = null; + baseLineDataCounts = null; + baseLineData = null; + + localPositions?.Dispose(); + localNormals?.Dispose(); + localTangents?.Dispose(); + boneWeights?.Dispose(); + skinBoneTransformIndices?.Dispose(); + skinBoneBindPoses?.Dispose(); + localPositions = null; + localNormals = null; + localTangents = null; + boneWeights = null; + skinBoneTransformIndices = null; + skinBoneBindPoses = null; + + vertexToTransformRotations?.Dispose(); + vertexToTransformRotations = null; + + mappingIdArray?.Dispose(); + mappingReferenceIndices?.Dispose(); + mappingAttributes?.Dispose(); + mappingLocalPositins?.Dispose(); + mappingLocalNormals?.Dispose(); + mappingLocalTangents?.Dispose(); + mappingBoneWeights?.Dispose(); +#if MC2_DEBUG + mappingPositions?.Dispose(); + //mappingNormals?.Dispose(); + //mappingTangents?.Dispose(); +#endif + mappingIdArray = null; + mappingReferenceIndices = null; + mappingAttributes = null; + mappingLocalPositins = null; + mappingLocalNormals = null; + mappingLocalTangents = null; + mappingBoneWeights = null; + } + + public void EnterdEditMode() + { + Dispose(); + } + + public void Initialize() + { + Dispose(); + + // 作業バッファ + const int capacity = 0; + const bool create = true; + teamIds = new ExNativeArray(capacity, create); + attributes = new ExNativeArray(capacity, create); + vertexToTriangles = new ExNativeArray>(capacity, create); + //vertexToVertexIndexArray = new ExNativeArray(capacity, create); + //vertexToVertexDataArray = new ExNativeArray(capacity, create); + vertexBindPosePositions = new ExNativeArray(capacity, create); + vertexBindPoseRotations = new ExNativeArray(capacity, create); + vertexDepths = new ExNativeArray(capacity, create); + vertexRootIndices = new ExNativeArray(capacity, create); + vertexLocalPositions = new ExNativeArray(capacity, create); + vertexLocalRotations = new ExNativeArray(capacity, create); + vertexParentIndices = new ExNativeArray(capacity, create); + vertexChildIndexArray = new ExNativeArray(capacity, create); + vertexChildDataArray = new ExNativeArray(capacity, create); + normalAdjustmentRotations = new ExNativeArray(capacity, create); + //vertexAngleCalcLocalRotations = new ExNativeArray(capacity, create); + uv = new ExNativeArray(capacity, create); + + triangleTeamIdArray = new ExNativeArray(capacity, create); + triangles = new ExNativeArray(capacity, create); + triangleNormals = new ExNativeArray(capacity, create); + triangleTangents = new ExNativeArray(capacity, create); + + edgeTeamIdArray = new ExNativeArray(capacity, create); + edges = new ExNativeArray(capacity, create); + edgeFlags = new ExNativeArray(capacity, create); + + positions = new ExNativeArray(capacity, create); + rotations = new ExNativeArray(capacity, create); + + baseLineFlags = new ExNativeArray(capacity, create); + baseLineTeamIds = new ExNativeArray(capacity, create); + baseLineStartDataIndices = new ExNativeArray(capacity, create); + baseLineDataCounts = new ExNativeArray(capacity, create); + baseLineData = new ExNativeArray(capacity, create); + + localPositions = new ExNativeArray(capacity, create); + localNormals = new ExNativeArray(capacity, create); + localTangents = new ExNativeArray(capacity, create); + boneWeights = new ExNativeArray(capacity, create); + skinBoneTransformIndices = new ExNativeArray(capacity, create); + skinBoneBindPoses = new ExNativeArray(capacity, create); + + vertexToTransformRotations = new ExNativeArray(capacity, create); + + mappingIdArray = new ExNativeArray(capacity, create); + mappingReferenceIndices = new ExNativeArray(capacity, create); + mappingAttributes = new ExNativeArray(capacity, create); + mappingLocalPositins = new ExNativeArray(capacity, create); + mappingLocalNormals = new ExNativeArray(capacity, create); + mappingLocalTangents = new ExNativeArray(capacity, create); + mappingBoneWeights = new ExNativeArray(capacity, create); +#if MC2_DEBUG + mappingPositions = new ExNativeArray(capacity, create); + //mappingNormals = new ExNativeArray(capacity, create); + //mappingTangents = new ExNativeArray(capacity, create); +#endif + + isValid = true; + } + + public bool IsValid() + { + return isValid; + } + + //========================================================================================= + /// + /// プロキシメッシュをマネージャに登録する + /// + public void RegisterProxyMesh(int teamId, VirtualMeshContainer proxyMeshContainer) + { + if (isValid == false) + return; + + ref var tdata = ref MagicaManager.Team.GetTeamDataRef(teamId); + var proxyMesh = proxyMeshContainer.shareVirtualMesh; + + // mesh type + tdata.proxyMeshType = proxyMesh.meshType; + + // Transform + tdata.proxyTransformChunk = MagicaManager.Bone.AddTransform(proxyMeshContainer, teamId); + + // center transform + tdata.centerTransformIndex = proxyMesh.centerTransformIndex + tdata.proxyTransformChunk.startIndex; + + // 作業用バッファ + // 共通 + int vcnt = proxyMesh.VertexCount; + tdata.proxyCommonChunk = teamIds.AddRange(vcnt, (short)teamId); + attributes.AddRange(proxyMesh.attributes); + vertexToTriangles.AddRange(proxyMesh.vertexToTriangles); + //vertexToVertexIndexArray.AddRange(proxyMesh.vertexToVertexIndexArray); + vertexBindPosePositions.AddRange(proxyMesh.vertexBindPosePositions); + vertexBindPoseRotations.AddRange(proxyMesh.vertexBindPoseRotations); + vertexDepths.AddRange(proxyMesh.vertexDepths); + vertexRootIndices.AddRange(proxyMesh.vertexRootIndices); + vertexLocalPositions.AddRange(proxyMesh.vertexLocalPositions); + vertexLocalRotations.AddRange(proxyMesh.vertexLocalRotations); + vertexParentIndices.AddRange(proxyMesh.vertexParentIndices); + vertexChildIndexArray.AddRange(proxyMesh.vertexChildIndexArray); + normalAdjustmentRotations.AddRange(proxyMesh.normalAdjustmentRotations); + //vertexAngleCalcLocalRotations.AddRange(proxyMesh.vertexAngleCalcLocalRotations); + uv.AddRange(proxyMesh.uv); + positions.AddRange(vcnt); + rotations.AddRange(vcnt); + + // 頂点接続データ + //tdata.proxyVertexToVertexDataChunk = vertexToVertexDataArray.AddRange(proxyMesh.vertexToVertexDataArray); + + // 子頂点データ + tdata.proxyVertexChildDataChunk = vertexChildDataArray.AddRange(proxyMesh.vertexChildDataArray); + + // トライアングル + if (proxyMesh.TriangleCount > 0) + { + tdata.proxyTriangleChunk = triangleTeamIdArray.AddRange(proxyMesh.TriangleCount, (short)teamId); + triangles.AddRange(proxyMesh.triangles); + triangleNormals.AddRange(proxyMesh.TriangleCount); + triangleTangents.AddRange(proxyMesh.TriangleCount); + } + + // エッジ(エッジは利用時のみ) + if (proxyMesh.EdgeCount > 0) + { + tdata.proxyEdgeChunk = edgeTeamIdArray.AddRange(proxyMesh.EdgeCount, (short)teamId); + edges.AddRange(proxyMesh.edges); + edgeFlags.AddRange(proxyMesh.edgeFlags); + } + + // ベースライン + if (proxyMesh.BaseLineCount > 0) + { + tdata.baseLineChunk = baseLineFlags.AddRange(proxyMesh.baseLineFlags); + baseLineStartDataIndices.AddRange(proxyMesh.baseLineStartDataIndices); + baseLineDataCounts.AddRange(proxyMesh.baseLineDataCounts); + baseLineTeamIds.AddRange(proxyMesh.BaseLineCount, (short)teamId); + + tdata.baseLineDataChunk = baseLineData.AddRange(proxyMesh.baseLineData); + } + + // メッシュ基本 + tdata.proxyMeshChunk = localPositions.AddRange(proxyMesh.localPositions); + localNormals.AddRange(proxyMesh.localNormals); + localTangents.AddRange(proxyMesh.localTangents); + boneWeights.AddRange(proxyMesh.boneWeights); + + // スキニング + tdata.proxySkinBoneChunk = skinBoneTransformIndices.AddRange(proxyMesh.skinBoneTransformIndices); + skinBoneBindPoses.AddRange(proxyMesh.skinBoneBindPoses); + + // BoneClothのみ + if (proxyMesh.meshType == VirtualMesh.MeshType.ProxyBoneMesh) + { + tdata.proxyBoneChunk = vertexToTransformRotations.AddRange(proxyMesh.vertexToTransformRotations); + } + + // Lineデータの有無を記録 + tdata.flag.SetBits(TeamManager.Flag_ProxyMeshLine, proxyMesh.LineCount > 0); + //Develop.DebugLog($"Proxy[{proxyMesh.name}] Line:{proxyMesh.LineCount > 0}"); + + // 頂点間の最大距離 + //tdata.maxVertexDistance = proxyMesh.maxVertexDistance.Value; + //Debug.Log($"maxVertexDistance:{proxyMesh.maxVertexDistance.Value}"); + //Debug.Log($"averageVertexDistance:{proxyMesh.averageVertexDistance.Value}"); + } + + /// + /// プロキシメッシュをマネージャから解除する + /// + public void ExitProxyMesh(int teamId) + { + if (isValid == false) + return; + + ref var tdata = ref MagicaManager.Team.GetTeamDataRef(teamId); + + // Transform + MagicaManager.Bone.RemoveTransform(tdata.proxyTransformChunk); + tdata.proxyTransformChunk.Clear(); + + // 作業用バッファ + teamIds.RemoveAndFill(tdata.proxyCommonChunk); // 0で埋める + attributes.RemoveAndFill(tdata.proxyCommonChunk); // 0で埋める + vertexToTriangles.Remove(tdata.proxyCommonChunk); + //vertexToVertexIndexArray.Remove(tdata.proxyCommonChunk); + vertexBindPosePositions.Remove(tdata.proxyCommonChunk); + vertexBindPoseRotations.Remove(tdata.proxyCommonChunk); + vertexDepths.Remove(tdata.proxyCommonChunk); + vertexRootIndices.Remove(tdata.proxyCommonChunk); + vertexLocalPositions.Remove(tdata.proxyCommonChunk); + vertexLocalRotations.Remove(tdata.proxyCommonChunk); + vertexParentIndices.Remove(tdata.proxyCommonChunk); + vertexChildIndexArray.Remove(tdata.proxyCommonChunk); + normalAdjustmentRotations.Remove(tdata.proxyCommonChunk); + //vertexAngleCalcLocalRotations.Remove(tdata.proxyCommonChunk); + uv.Remove(tdata.proxyCommonChunk); + positions.Remove(tdata.proxyCommonChunk); + rotations.Remove(tdata.proxyCommonChunk); + tdata.proxyCommonChunk.Clear(); + + //vertexToVertexDataArray.Remove(tdata.proxyVertexToVertexDataChunk); + //tdata.proxyVertexToVertexDataChunk.Clear(); + + vertexChildDataArray.Remove(tdata.proxyVertexChildDataChunk); + tdata.proxyVertexChildDataChunk.Clear(); + + triangleTeamIdArray.RemoveAndFill(tdata.proxyTriangleChunk, 0); // 0で埋める + triangles.Remove(tdata.proxyTriangleChunk); + triangleNormals.Remove(tdata.proxyTriangleChunk); + triangleTangents.Remove(tdata.proxyTriangleChunk); + tdata.proxyTriangleChunk.Clear(); + + edgeTeamIdArray.RemoveAndFill(tdata.proxyEdgeChunk, 0); // 0で埋める + edges.Remove(tdata.proxyEdgeChunk); + edgeFlags.Remove(tdata.proxyEdgeChunk); + + baseLineFlags.RemoveAndFill(tdata.baseLineChunk); // 0で埋める + baseLineTeamIds.Remove(tdata.baseLineChunk); + baseLineStartDataIndices.Remove(tdata.baseLineChunk); + baseLineDataCounts.Remove(tdata.baseLineChunk); + tdata.baseLineChunk.Clear(); + + baseLineData.Remove(tdata.baseLineDataChunk); + tdata.baseLineDataChunk.Clear(); + + localPositions.Remove(tdata.proxyMeshChunk); + localNormals.Remove(tdata.proxyMeshChunk); + localTangents.Remove(tdata.proxyMeshChunk); + boneWeights.Remove(tdata.proxyMeshChunk); + tdata.proxyMeshChunk.Clear(); + + skinBoneTransformIndices.Remove(tdata.proxySkinBoneChunk); + skinBoneBindPoses.Remove(tdata.proxySkinBoneChunk); + tdata.proxySkinBoneChunk.Clear(); + + vertexToTransformRotations.Remove(tdata.proxyBoneChunk); + tdata.proxyBoneChunk.Clear(); + + // 同時に連動するマッピングメッシュも解放する + var mappingList = MagicaManager.Team.teamMappingIndexArray[teamId]; + int mcnt = mappingList.Length; + for (int i = 0; i < mcnt; i++) + { + int mappingIndex = mappingList[i]; + ExitMappingMesh(teamId, mappingIndex); + } + } + + //========================================================================================= + /// + /// マッピングメッシュをマネージャに登録する(チームにも登録される) + /// + /// + /// + /// + public DataChunk RegisterMappingMesh( + int teamId, + VirtualMeshContainer mappingMeshContainer, + int renderDataWorkIndex + ) + { + if (isValid == false) + return DataChunk.Empty; + + ref var tdata = ref MagicaManager.Team.GetTeamDataRef(teamId); + ref var mappingList = ref MagicaManager.Team.GetTeamMappingRef(teamId); + + var mdata = new TeamManager.MappingData(); + mdata.teamId = teamId; + + var mappingMesh = mappingMeshContainer.shareVirtualMesh; + + // transform + var ct = mappingMeshContainer.GetCenterTransform(); + var c = MagicaManager.Bone.AddTransform(ct, new ExBitFlag8(TransformManager.Flag_Read | TransformManager.Flag_Enable), teamId); + mdata.centerTransformIndex = c.startIndex; + + // プロキシメッシュへの変換 + mdata.toProxyMatrix = mappingMesh.toProxyMatrix; + mdata.toProxyRotation = mappingMesh.toProxyRotation; + + // 登録インデックスが必要なので先に登録する + c = MagicaManager.Team.mappingDataArray.Add(mdata); + int mappingIndex = c.startIndex; + + // 基本データ + int vcnt = mappingMesh.VertexCount; + mdata.mappingCommonChunk = mappingIdArray.AddRange(vcnt, (short)(mappingIndex + 1)); // (+1)されるので注意! + + mappingReferenceIndices.AddRange(mappingMesh.referenceIndices); + mappingAttributes.AddRange(mappingMesh.attributes); + mappingLocalPositins.AddRange(mappingMesh.localPositions); + mappingLocalNormals.AddRange(mappingMesh.localNormals); + mappingLocalTangents.AddRange(mappingMesh.localTangents); + mappingBoneWeights.AddRange(mappingMesh.boneWeights); +#if MC2_DEBUG + mappingPositions.AddRange(vcnt); + //mappingNormals.AddRange(vcnt); + //mappingTangents.AddRange(vcnt); +#endif + + // RenderMeshWorkデータと紐づけ + mdata.renderDataWorkIndex = renderDataWorkIndex; + ref var wdata = ref MagicaManager.Render.GetRenderDataWorkRef(renderDataWorkIndex); + wdata.AddMappingIndex(mappingIndex); + + // 再登録 + MagicaManager.Team.mappingDataArray[mappingIndex] = mdata; + mappingList.MC2Set((short)mappingIndex); + + // vmeshにも記録する + mappingMesh.mappingId = mappingIndex; + + Develop.DebugLog($"RegisterMappingMesh. team:{teamId}, mappingIndex:{mappingIndex}"); + + // マッピングメッシュの登録チャンクを返す + return mdata.mappingCommonChunk; + } + + public void ExitMappingMesh(int teamId, int mappingIndex) + { + if (isValid == false) + return; + + ref var tdata = ref MagicaManager.Team.GetTeamDataRef(teamId); + ref var mdata = ref MagicaManager.Team.mappingDataArray.GetRef(mappingIndex); + ref var mappingList = ref MagicaManager.Team.GetTeamMappingRef(teamId); + + // Transform解放 + MagicaManager.Bone.RemoveTransform(new DataChunk(mdata.centerTransformIndex, 1)); + + // 作業バッファ解放 + mappingIdArray.RemoveAndFill(mdata.mappingCommonChunk, 0); + mappingReferenceIndices.Remove(mdata.mappingCommonChunk); + mappingAttributes.Remove(mdata.mappingCommonChunk); + mappingLocalPositins.Remove(mdata.mappingCommonChunk); + mappingLocalNormals.Remove(mdata.mappingCommonChunk); + mappingLocalTangents.Remove(mdata.mappingCommonChunk); + mappingBoneWeights.Remove(mdata.mappingCommonChunk); +#if MC2_DEBUG + mappingPositions.Remove(mdata.mappingCommonChunk); + //mappingNormals.Remove(mdata.mappingCommonChunk); + //mappingTangents.Remove(mdata.mappingCommonChunk); +#endif + + // RenderMeshWorkデータとの紐づけ解除 + ref var wdata = ref MagicaManager.Render.GetRenderDataWorkRef(mdata.renderDataWorkIndex); + wdata.RemoveMappingIndex(mappingIndex); + + // チームから削除する + mappingList.MC2RemoveItemAtSwapBack((short)mappingIndex); + + MagicaManager.Team.mappingDataArray.RemoveAndFill(new DataChunk(mappingIndex, 1)); + + Develop.DebugLog($"ExitMappingMesh. team:{teamId}, mappingIndex:{mappingIndex}"); + } + + //========================================================================================= + // Simulation + //========================================================================================= + /// + /// プロキシメッシュの頂点スキニングを行い座標・法線・接線を求める + /// [BoneCloth][MeshCloth]兼用 + /// 姿勢はワールド座標で格納される + /// + internal static void SimulationPreProxyMeshUpdate( + DataChunk chunk, + // team + int teamId, + ref TeamManager.TeamData tdata, + + // vmesh + in NativeArray attributes, + in NativeArray localPositions, + in NativeArray localNormals, + in NativeArray localTangents, + in NativeArray boneWeights, + in NativeArray skinBoneTransformIndices, + in NativeArray skinBoneBindPoses, + ref NativeArray positions, + ref NativeArray rotations, + + // transform + in NativeArray transformLocalToWorldMatrixArray + ) + { + var pc = tdata.proxyCommonChunk; + if (pc.dataLength == 0) + return; + + // ProxyMeshをスキニングして頂点姿勢を求める + //int vindex = pc.startIndex; + int vindex = pc.startIndex + chunk.startIndex; + //int mvindex = tdata.proxyMeshChunk.startIndex; + int mvindex = tdata.proxyMeshChunk.startIndex + chunk.startIndex; + int sb_start = tdata.proxySkinBoneChunk.startIndex; + int t_start = tdata.proxyTransformChunk.startIndex; + float4x3 wpose = 0; + float4x3 _pose = 0; + float4x3 _lpose = 0; + //for (int k = 0; k < pc.dataLength; k++, vindex++, mvindex++) + for (int k = 0; k < chunk.dataLength; k++, vindex++, mvindex++) + { + var bw = boneWeights[mvindex]; + int wcnt = bw.Count; + + wpose = 0; + _pose = 0; + + _lpose.c0 = new float4(localPositions[mvindex], 1); + _lpose.c1 = new float4(localNormals[mvindex], 0); + _lpose.c2 = new float4(localTangents[mvindex], 0); + + for (int i = 0; i < wcnt; i++) + { + float w = bw.weights[i]; + + _pose = _lpose; + //Debug.Log($"[{mvindex}] lpos:{lpos}, lnor:{lnor}, ltan:{ltan}"); + + // ボーンローカル空間に変換 + int l_boneIndex = bw.boneIndices[i]; + float4x4 bp = skinBoneBindPoses[sb_start + l_boneIndex]; + _pose = math.mul(bp, _pose); + + // 現在のワールド空間に変換 + int tindex = skinBoneTransformIndices[sb_start + l_boneIndex] + t_start; + var lw = transformLocalToWorldMatrixArray[tindex]; + _pose = math.mul(lw, _pose); + + // ウエイト + wpose += _pose * w; + } + + float3 wpos = wpose.c0.xyz; + float3 wnor = wpose.c1.xyz; + float3 wtan = wpose.c2.xyz; + + // バインドポーズにスケールが入るので単位化する必要がある +#if MC2_DEBUG + Develop.Assert(math.length(wnor) > 0.0f); + Develop.Assert(math.length(wtan) > 0.0f); +#endif + wnor = math.normalize(wnor); + wtan = math.normalize(wtan); + var wrot = MathUtility.ToRotation(wnor, wtan); + + positions[vindex] = wpos; + rotations[vindex] = wrot; + + //Debug.Log($"[{teamId}] pv:{vindex}, wpos:{wpos}"); + } + } + + /// + /// クロスシミュレーションの結果をProxyMeshへ反映させる + /// ラインがある場合はベースラインごとに姿勢を整える + /// + internal static void SimulationPostProxyMeshUpdateLine( + DataChunk chunk, + // team + ref TeamManager.TeamData tdata, + ref ClothParameters param, + // vmesh + ref NativeArray attributes, + ref NativeArray positions, + ref NativeArray rotations, + ref NativeArray vertexLocalPositions, + ref NativeArray vertexLocalRotations, + ref NativeArray vertexChildIndexArray, + ref NativeArray vertexChildDataArray, + ref NativeArray baseLineFlags, + ref NativeArray baseLineStartIndices, + ref NativeArray baseLineDataCounts, + ref NativeArray baseLineData, + // temp + ref NativeArray tempVectorBufferA, + ref NativeArray tempRotationBufferA + ) + { + // ラインがある場合はベースラインごとに姿勢を整える + // ただしLineが存在しないメッシュはスキップする。トライアングルベースの回転制御にすべて上書きされるため。 + if (tdata.baseLineChunk.IsValid && tdata.flag.IsSet(TeamManager.Flag_ProxyMeshLine)) + { + // parameter + float averageRate = param.rotationalInterpolation; // 回転平均化割合 + float rootInterpolation = param.rootRotation; + float animeRatio = tdata.animationPoseRatio; + float blendWeight = tdata.blendWeight; + + int s_vindex = tdata.proxyCommonChunk.startIndex; + int s_pindex = tdata.particleChunk.startIndex; + int s_dataIndex = tdata.baseLineDataChunk.startIndex; + int s_childDataIndex = tdata.proxyVertexChildDataChunk.startIndex; + + int bindex = tdata.baseLineChunk.startIndex + chunk.startIndex; + for (int k = 0; k < chunk.dataLength; k++, bindex++) + { + // ラインを含む場合のみ実行する + var bflag = baseLineFlags[bindex]; + if (bflag.IsSet(VirtualMesh.BaseLineFlag_IncludeLine) == false) + continue; + + // ベースラインをルートから走査する + int dataIndex = baseLineStartIndices[bindex] + s_dataIndex; + int dataCnt = baseLineDataCounts[bindex]; + for (int i = 0; i < dataCnt; i++, dataIndex++) + { + // 自身を親とする + int lindex = baseLineData[dataIndex]; + int vindex = lindex + s_vindex; + int pindex = lindex + s_pindex; + var pos = positions[vindex]; + var rot = rotations[vindex]; + var attr = attributes[vindex]; + + //Debug.Log($"p:[{vindex}] rot:[{rot}] wn:{MathUtility.ToNormal(rot)}, wt:{MathUtility.ToTangent(rot)}"); + + // 子の情報 + var pack = vertexChildIndexArray[vindex]; + int cstart = DataUtility.Unpack12_20Low(pack); + int ccnt = DataUtility.Unpack12_20Hi(pack); + + // ★Ver2.17.0より変更。以下の問題を修正 + // BoneClothの制御Transformがアニメーションにより姿勢制御されている場合に最終回転が全体的におかしくなる + // これは回転計算の元をアニメーション姿勢ではなく初期姿勢に固定しているため + // そのためBlendWeight=0にしてもオリジナルの姿勢に戻らなくなる + // またベクトルのゼロ距離判定を強化 + + // 現在のベース姿勢 + var basePos = tempVectorBufferA[pindex]; + var baseRot = tempRotationBufferA[pindex]; + var baseInvRot = math.inverse(baseRot); + + if (ccnt > 0 && attr.IsInvalid() == false) + { + // 子への平均ベクトル + float3 ctv = 0; + float3 cv = 0; + + // 自身を基準に子の回転を求める、また子への平均ベクトルを加算する + for (int j = 0; j < ccnt; j++) + { + int clindex = vertexChildDataArray[s_childDataIndex + cstart + j]; + int cvindex = clindex + s_vindex; + int cpindex = clindex + s_pindex; + + // 子の属性 + var cattr = attributes[cvindex]; + + // このゼロ距離状態 + bool isC0 = cattr.IsSet(VertexAttribute.Flag_ZeroDistance); + + // 子の座標 + var cpos = positions[cvindex]; + + // 子の現在のベース姿勢とローカル姿勢 + var cbasePos = tempVectorBufferA[cpindex]; + var cbaseRot = tempRotationBufferA[cpindex]; + float3 cbaseLocalPos = math.mul(baseInvRot, cbasePos - basePos); + quaternion cbaseLocalRot = math.mul(baseInvRot, cbaseRot); + + // 計算基準のローカル位置とローカル回転 + // AnimationPoseRatioにより補間 + float3 lpos = math.lerp(vertexLocalPositions[cvindex] * tdata.negativeScaleDirection, cbaseLocalPos, animeRatio); + quaternion lrot = math.slerp(vertexLocalRotations[cvindex].value * tdata.negativeScaleQuaternionValue, cbaseLocalRot, animeRatio); + + // 子の本来のベクトル + float3 tv = isC0 ? 0.0f : math.mul(rot, lpos); + + ctv += tv; + + // 子の現在ベクトル + if (cattr.IsMove()) + { + float3 v = cpos - pos; + cv += v; + + bool isV0 = MathUtility.IsZeroDistance(v); + + // 子の回転を決定 + // この時点で子は親の方向(1.0)の回転となる + var crot = math.mul(rot, lrot); + + // 現在のベクトル変位による補正 + if(isC0 == false) + { + var q = MathUtility.FromToRotation(tv, v); + crot = math.mul(q, crot); + } + + rotations[cvindex] = crot; + } + else + { + cv += tv; + } + } + + // 子の方向への回転調整 + float t = attr.IsMove() ? averageRate : rootInterpolation; + bool isCtv0 = MathUtility.IsZeroDistance(ctv); + bool isCv0 = MathUtility.IsZeroDistance(cv); + var cq = (isCtv0 || isCv0) ? quaternion.identity : MathUtility.FromToRotation(ctv, cv, t); + rot = math.mul(cq, rot); + } + + // ブレンドウエイト適用 + rot = math.slerp(baseRot, rot, blendWeight); + + // 自身の姿勢を確定させる + rotations[vindex] = rot; + } + } + } + } + + /// + /// クロスシミュレーションの結果をProxyMeshへ反映させる + /// トライアングルの法線と接線を求める + /// + internal static void SimulationPostProxyMeshUpdateTriangle( + DataChunk chunk, + // team + ref TeamManager.TeamData tdata, + // vmesh + ref NativeArray positions, + ref NativeArray triangles, + ref NativeArray triangleNormals, + ref NativeArray triangleTangents, + ref NativeArray uvs + ) + { + + // トライアングルがある場合はトライアングル接続情報から最終的な姿勢を求める + if (tdata.TriangleCount > 0) + { + // トライアングルの法線と接線を求める + // 座標系の変換は行わない + //int tindex = tdata.proxyTriangleChunk.startIndex; + int tindex = tdata.proxyTriangleChunk.startIndex + chunk.startIndex; + //for (int k = 0; k < tdata.proxyTriangleChunk.dataLength; k++, tindex++) + for (int k = 0; k < chunk.dataLength; k++, tindex++) + { + int3 tri = triangles[tindex]; + + // トライアングル法線を求める + int start = tdata.proxyCommonChunk.startIndex; + var pos1 = positions[start + tri.x]; + var pos2 = positions[start + tri.y]; + var pos3 = positions[start + tri.z]; + float3 cross = math.cross(pos2 - pos1, pos3 - pos1); + float len = math.length(cross); + if (len > Define.System.Epsilon) + { + float3 nor = cross / len; + + // マイナススケール + nor *= tdata.negativeScaleTriangleSign.x; + + triangleNormals[tindex] = nor; + } +#if MC2_DEBUG + else + Debug.LogWarning("CalcTriangleNormalTangentJob.normal = 0!"); +#endif + + // トライアングル接線を求める + var uv1 = uvs[start + tri.x]; + var uv2 = uvs[start + tri.y]; + var uv3 = uvs[start + tri.z]; + var tan = MathUtility.TriangleTangent(pos1, pos2, pos3, uv1, uv2, uv3); + if (math.lengthsq(tan) > 0.0f) + { + // マイナススケール + tan *= tdata.negativeScaleTriangleSign.y; + + triangleTangents[tindex] = tan; + } +#if MC2_DEBUG + else + Debug.LogWarning("CalcTriangleNormalTangentJob.tangent = 0!"); +#endif + } + } + } + + /// + /// クロスシミュレーションの結果をProxyMeshへ反映させる + /// トライアングルの法線接線から頂点法線接線を平均化して求める + /// + internal static void SimulationPostProxyMeshUpdateTriangleSum( + DataChunk chunk, + // team + ref TeamManager.TeamData tdata, + // vmesh + ref NativeArray rotations, + ref NativeArray triangleNormals, + ref NativeArray triangleTangents, + ref NativeArray> vertexToTriangles, + ref NativeArray normalAdjustmentRotations + ) + { + // トライアングルがある場合はトライアングル接続情報から最終的な姿勢を求める + if (tdata.TriangleCount > 0) + { + // トライアングルの法線接線から頂点法線接線を平均化して求める + // (ワールド座標空間) + //int vindex = tdata.proxyCommonChunk.startIndex; + int vindex = tdata.proxyCommonChunk.startIndex + chunk.startIndex; + //for (int k = 0; k < tdata.proxyCommonChunk.dataLength; k++, vindex++) + for (int k = 0; k < chunk.dataLength; k++, vindex++) + { + var tlist = vertexToTriangles[vindex]; + if (tlist.Length > 0) + { + float3 nor = 0; + float3 tan = 0; + for (int i = 0; i < tlist.Length; i++) + { + // 12-20bitのパックで格納されている + // 12(hi) = 法線と接線のフリップフラグ + // 20(low) = トライアングルインデックス + uint data = tlist[i]; + int flipFlag = DataUtility.Unpack12_20Hi(data); + int tindex = DataUtility.Unpack12_20Low(data); + + tindex += tdata.proxyTriangleChunk.startIndex; + nor += triangleNormals[tindex] * ((flipFlag & 0x1) == 0 ? 1 : -1); + tan += triangleTangents[tindex] * ((flipFlag & 0x2) == 0 ? 1 : -1); + } + //Debug.Log($"Vertex:{vindex} nor:{nor}, tan:{tan}"); + + // 法線0を考慮する。法線を0にするとポリゴンが欠けるため + float ln = math.length(nor); + float lt = math.length(tan); + if (ln > 1e-06f && lt > 1e-06f) + { + nor = nor / ln; + tan = tan / lt; + + float dot = math.dot(nor, tan); + if (dot != 1.0f && dot != -1.0f) + { + // トライアングル回転は従法線から算出するように変更(v2.1.7) + float3 binor = math.normalize(math.cross(nor, tan)); + var rot = quaternion.LookRotation(binor, nor); + + // 法線調整用回転を乗算する(不要な場合は単位回転が入っている) + // マイナススケール + rot = math.mul(rot, normalAdjustmentRotations[vindex].value * tdata.negativeScaleQuaternionValue); + //rot = math.mul(rot, normalAdjustmentRotations[vindex]); // オリジナル + + rotations[vindex] = rot; + } + } + } + } + } + } + + /// + /// クロスシミュレーションの結果をProxyMeshへ反映させる + /// BoneClothの場合は頂点姿勢から連動するトランスフォームのワールド姿勢を計算する + /// + internal static void SimulationPostProxyMeshUpdateWorldTransform( + DataChunk chunk, + // team + ref TeamManager.TeamData tdata, + // vmesh + ref NativeArray positions, + ref NativeArray rotations, + ref NativeArray vertexToTransformRotations, + // transform + ref NativeArray transformPositionArray, + ref NativeArray transformRotationArray + ) + { + // Transformパーティクル + if (tdata.proxyMeshType == VirtualMesh.MeshType.ProxyBoneMesh) + { + // Transformパーティクルの場合はvertexToTransform回転を乗算してTransformDataに情報を書き戻す + //int vindex = tdata.proxyCommonChunk.startIndex; + int vindex = tdata.proxyCommonChunk.startIndex + chunk.startIndex; + //for (int k = 0; k < tdata.proxyCommonChunk.dataLength; k++, vindex++) + for (int k = 0; k < chunk.dataLength; k++, vindex++) + { + // pos/rotはワールド空間 + var pos = positions[vindex]; + var rot = rotations[vindex]; + + // 本来のTransformの姿勢を求める回転を掛ける + //int boneIndex = tdata.proxyBoneChunk.startIndex + k; + int boneIndex = tdata.proxyBoneChunk.startIndex + chunk.startIndex + k; + quaternion v2t = vertexToTransformRotations[boneIndex]; + + // マイナススケール + rot = math.mul(rot, v2t.value * tdata.negativeScaleQuaternionValue); + //rot = math.mul(rot, v2t); // オリジナル + + // ワールド姿勢 + //int tindex = tdata.proxyTransformChunk.startIndex + k; + int tindex = tdata.proxyTransformChunk.startIndex + chunk.startIndex + k; + transformPositionArray[tindex] = pos; + transformRotationArray[tindex] = rot; + } + } + } + + /// + /// BoneClothの場合はTransformのローカル姿勢を計算する + /// + internal static void SimulationPostProxyMeshUpdateLocalTransform( + // team + ref TeamManager.TeamData tdata, + // vmesh + ref NativeArray attributes, + ref NativeArray parentIndices, + // transform + ref NativeArray transformPositionArray, + ref NativeArray transformRotationArray, + ref NativeArray transformScaleArray, + ref NativeArray transformLocalPositionArray, + ref NativeArray transformLocalRotationArray + ) + { + // Transformパーティクル + if (tdata.proxyMeshType == VirtualMesh.MeshType.ProxyBoneMesh) + { + // Transformパーティクルは親からのローカル姿勢を計算してTransformData情報に書き込む + int vindex = tdata.proxyCommonChunk.startIndex; + //vindex = tdata.proxyCommonChunk.startIndex + chunk.startIndex; + for (int k = 0; k < tdata.proxyCommonChunk.dataLength; k++, vindex++) + //for (int k = 0; k < chunk.dataLength; k++, vindex++) + { + int parentIndex = parentIndices[vindex]; + if (parentIndex < 0) + continue; + + var attr = attributes[vindex]; + if (attr.IsMove() == false) + continue; + + // 親からのローカル姿勢を計算しトランスフォーム情報に書き込む + int tindex = tdata.proxyTransformChunk.startIndex + k; + //int tindex = tdata.proxyTransformChunk.startIndex + chunk.startIndex + k; + int ptindex = tdata.proxyTransformChunk.startIndex + parentIndex; + var ppos = transformPositionArray[ptindex]; + var prot = transformRotationArray[ptindex]; + var pscl = transformScaleArray[ptindex]; + var pos = transformPositionArray[tindex]; + var rot = transformRotationArray[tindex]; + +#if true + var iprot = math.inverse(prot); + var v = pos - ppos; + var lpos = math.mul(iprot, v); + + //Develop.Assert(pscl.x > 0.0f && pscl.y > 0.0f && pscl.z > 0.0f); + lpos /= pscl; + var lrot = math.mul(iprot, rot); +#endif + + // マイナススケール + lrot = lrot.value * tdata.negativeScaleQuaternionValue; + + transformLocalPositionArray[tindex] = lpos; + transformLocalRotationArray[tindex] = lrot; + } + } + } + + /// + /// マッピングメッシュの頂点姿勢を連動するプロキシメッシュからスキニングして求める + /// + internal JobHandle PostMappingMeshUpdateBatchSchedule(JobHandle jobHandle, int workerCount) + { + if (MagicaManager.Team.MappingCount == 0) + return jobHandle; + + var tm = MagicaManager.Team; + var bm = MagicaManager.Bone; + var rm = MagicaManager.Render; + + // マッピングメッシュの変換マトリックスを求める + var calcMeshConvert_A_Job = new CalcMeshConvert_A_Job() + { + // team + teamDataArray = tm.teamDataArray.GetNativeArray(), + // transform + transformPositionArray = bm.positionArray.GetNativeArray(), + transformRotationArray = bm.rotationArray.GetNativeArray(), + transformScaleArray = bm.scaleArray.GetNativeArray(), + // mapping + mappingDataArray = tm.mappingDataArray.GetNativeArray(), + // render mesh + renderDataWorkArray = rm.renderDataWorkArray.GetNativeArray(), + }; + jobHandle = calcMeshConvert_A_Job.Schedule(tm.MappingCount, 1, jobHandle); + + // マッピングメッシュの頂点姿勢をプロキシメッシュから逆スキニングして求める + // マッピングメッシュの頂点姿勢を書き込み用バッファに書き込む + // 必要があればボーンウエイトも書き込む + var calcMeshConvert_B_Job = new CalcMeshConvert_B_Job() + { + workerCount = workerCount, + // team + teamDataArray = tm.teamDataArray.GetNativeArray(), + // mapping + mappingDataArray = tm.mappingDataArray.GetNativeArray(), + //mappingIdArray = mappingIdArray.GetNativeArray(), + mappingAttributes = mappingAttributes.GetNativeArray(), + mappingLocalPositions = mappingLocalPositins.GetNativeArray(), + mappingLocalNormals = mappingLocalNormals.GetNativeArray(), + mappingLocalTangents = mappingLocalTangents.GetNativeArray(), + mappingBoneWeights = mappingBoneWeights.GetNativeArray(), +#if MC2_DEBUG + mappingPositions = mappingPositions.GetNativeArray(), + //mappingNormals = mappingNormals.GetNativeArray(), + //mappingTangents = mappingTangents.GetNativeArray(), +#endif + mappingReferenceIndices = mappingReferenceIndices.GetNativeArray(), + // proxy + proxyPositions = positions.GetNativeArray(), + proxyRotations = rotations.GetNativeArray(), + proxyVertexBindPosePositions = vertexBindPosePositions.GetNativeArray(), + proxyVertexBindPoseRotations = vertexBindPoseRotations.GetNativeArray(), + // render mesh + renderDataWorkArray = rm.renderDataWorkArray.GetNativeArray(), + renderMeshPositions = rm.renderMeshPositions.GetNativeArray(), + renderMeshNormals = rm.renderMeshNormals.GetNativeArray(), + renderMeshTangents = rm.renderMeshTangents.GetNativeArray(), + renderMeshBoneWeights = rm.renderMeshBoneWeights.GetNativeArray(), + }; + jobHandle = calcMeshConvert_B_Job.Schedule(tm.MappingCount * workerCount, 1, jobHandle); + + // レンダーメッシュデータの後処理 + var postRenderDataJob = new PostRenderMeshWorkDataBatchJob() + { + // render mesh + renderDataWorkArray = rm.renderDataWorkArray.GetNativeArray(), + // mapping data + mappingDataArray = tm.mappingDataArray.GetNativeArray(), + }; + jobHandle = postRenderDataJob.Schedule(rm.RenderDataWorkCount, 8, jobHandle); + + return jobHandle; + } + + /// + /// プロキシメッシュからマッピングメッシュへの変換マトリックスを求める + /// + [BurstCompile] + struct CalcMeshConvert_A_Job : IJobParallelFor + { + // team + [Unity.Collections.ReadOnly] + public NativeArray teamDataArray; + + // transform + [Unity.Collections.ReadOnly] + public NativeArray transformPositionArray; + [Unity.Collections.ReadOnly] + public NativeArray transformRotationArray; + [Unity.Collections.ReadOnly] + public NativeArray transformScaleArray; + + // mapping + public NativeArray mappingDataArray; + + // render mesh + [Unity.Collections.ReadOnly] + public NativeArray renderDataWorkArray; + + // マッピングメッシュごと + public void Execute(int index) + { + var mdata = mappingDataArray[index]; + if (mdata.IsValid() == false) + return; + + var tdata = teamDataArray[mdata.teamId]; + if (tdata.IsProcess == false) + return; + + // RenderMeshWorkData + var wdata = renderDataWorkArray[mdata.renderDataWorkIndex]; + if (wdata.UseCustomMesh == false) + return; + + //======================================================================= + // ■マッピングメッシュとプロキシメッシュの座標変換マトリックスを求める + { + // mapping + var pos = transformPositionArray[mdata.centerTransformIndex]; + var rot = transformRotationArray[mdata.centerTransformIndex]; + var scl = transformScaleArray[mdata.centerTransformIndex]; + var irot = math.inverse(rot); + + // proxy + var ppos = transformPositionArray[tdata.centerTransformIndex]; + var prot = transformRotationArray[tdata.centerTransformIndex]; + var pscl = transformScaleArray[tdata.centerTransformIndex]; + + // プロキシメッシュとマッピングメッシュの座標空間が等しいか判定 + bool sameSpace = MathUtility.CompareTransform(pos, rot, scl, ppos, prot, pscl); + mdata.sameSpace = sameSpace; + //Debug.Log($"sameSpace:{sameSpace}, scl:{scl}, pscl:{pscl}"); + + // ワールド空間からマッピングメッシュへの座標空間変換 + mdata.toMappingMatrix = math.inverse(MathUtility.LocalToWorldMatrix(pos, rot, scl)); + mdata.toMappingRotation = irot; + + // マッピングメッシュ用のスケール比率 + // チームのステップ実行とは無関係に毎フレーム適用する必要があるためチームスケール比率と分離する + var initScaleLength = math.length(tdata.initScale); + Develop.Assert(initScaleLength > 0.0f); + mdata.scaleRatio = math.length(pscl) / initScaleLength; + } + + //======================================================================= + // ■マッピングメッシュメッシュ頂点姿勢をプロキシメッシュから逆スキニングして求める + // 接線の有無 + bool useTangent = tdata.IsTangent; + // ボーンウエイトの書き込み + bool modifyBoneWeight = wdata.HasBoneWeight && mdata.flag.IsSet(TeamManager.MappingDataFlag_ModifyBoneWeight); + + //======================================================================= + // ■結果格納 + mdata.flag.SetBits(TeamManager.MappingDataFlag_ChangePositionNormal, true); + mdata.flag.SetBits(TeamManager.MappingDataFlag_ChangeTangent, useTangent); + mdata.flag.SetBits(TeamManager.MappingDataFlag_ChangeBoneWeight, modifyBoneWeight); + mappingDataArray[index] = mdata; + } + } + + /// + /// マッピングメッシュの頂点姿勢をプロキシメッシュから逆スキニングして求める + /// マッピングメッシュの頂点姿勢を書き込み用バッファに書き込む + /// 必要があればボーンウエイトも書き込む + /// + [BurstCompile] + struct CalcMeshConvert_B_Job : IJobParallelFor + { + public int workerCount; + + // team + [Unity.Collections.ReadOnly] + public NativeArray teamDataArray; + + // mapping + [Unity.Collections.ReadOnly] + public NativeArray mappingDataArray; + [Unity.Collections.ReadOnly] + public NativeArray mappingAttributes; + [Unity.Collections.ReadOnly] + public NativeArray mappingLocalPositions; + [Unity.Collections.ReadOnly] + public NativeArray mappingLocalNormals; + [Unity.Collections.ReadOnly] + public NativeArray mappingLocalTangents; + [Unity.Collections.ReadOnly] + public NativeArray mappingBoneWeights; +#if MC2_DEBUG + [NativeDisableParallelForRestriction] + [Unity.Collections.WriteOnly] + public NativeArray mappingPositions; +#endif + [Unity.Collections.ReadOnly] + public NativeArray mappingReferenceIndices; + + // proxy mesh + [Unity.Collections.ReadOnly] + public NativeArray proxyPositions; + [Unity.Collections.ReadOnly] + public NativeArray proxyRotations; + [Unity.Collections.ReadOnly] + public NativeArray proxyVertexBindPosePositions; + [Unity.Collections.ReadOnly] + public NativeArray proxyVertexBindPoseRotations; + + // render mesh + [Unity.Collections.ReadOnly] + public NativeArray renderDataWorkArray; + [NativeDisableParallelForRestriction] + [Unity.Collections.WriteOnly] + public NativeArray renderMeshPositions; + [NativeDisableParallelForRestriction] + [Unity.Collections.WriteOnly] + public NativeArray renderMeshNormals; + [NativeDisableParallelForRestriction] + public NativeArray renderMeshTangents; + [NativeDisableParallelForRestriction] + [Unity.Collections.WriteOnly] + public NativeArray renderMeshBoneWeights; + + // マッピングメッシュごと + public void Execute(int dataIndex) + { + // チームIDとワーカーID + int localIndex = dataIndex / workerCount; + int workerIndex = dataIndex % workerCount; + + var mdata = mappingDataArray[localIndex]; + if (mdata.IsValid() == false) + return; + + var tdata = teamDataArray[mdata.teamId]; + if (tdata.IsProcess == false) + return; + + // RenderMeshWorkData + var wdata = renderDataWorkArray[mdata.renderDataWorkIndex]; + if (wdata.UseCustomMesh == false) + return; + + // 範囲 + var chunk = MathUtility.GetWorkerChunk(mdata.mappingCommonChunk.dataLength, workerCount, workerIndex); + if (chunk.IsValid == false) + return; + + //======================================================================= + // ■マッピングメッシュメッシュ頂点姿勢をプロキシメッシュから逆スキニングして求める + // 接線の有無 + bool useTangent = tdata.IsTangent; + // マイナススケール + float4 negativeScl = new float4(tdata.negativeScaleDirection, 1); + // ProxyMeshスケール + float3 proxyScl = tdata.initScale * mdata.scaleRatio; // 初期スケール x 現在のスケール比率 + // ボーンウエイトの書き込み + bool modifyBoneWeight = wdata.HasBoneWeight && mdata.flag.IsSet(TeamManager.MappingDataFlag_ModifyBoneWeight); + + //int mvindex = mdata.mappingCommonChunk.startIndex; + int mvindex = mdata.mappingCommonChunk.startIndex + chunk.startIndex; + //for (int k = 0; k < mdata.mappingCommonChunk.dataLength; k++, mvindex++) + for (int k = 0; k < chunk.dataLength; k++, mvindex++) + { + // 無効頂点は無視する + var attr = mappingAttributes[mvindex]; + if (attr.IsInvalid()) + continue; + + // 固定も書き込まない + if (attr.IsFixed()) + continue; + + // マッピングメッシュ姿勢 + float4x3 _pose = 0; + _pose.c0 = new float4(mappingLocalPositions[mvindex], 1); + _pose.c1 = new float4(mappingLocalNormals[mvindex], 0); + _pose.c2 = math.select(0, new float4(mappingLocalTangents[mvindex], 0), useTangent); + + // プロキシメッシュの座標空間に変換する + if (mdata.sameSpace == false) + { + // 現在の姿勢ではなくマッピング時の姿勢で変換を行う + _pose = math.mul(mdata.toProxyMatrix, _pose); + } + + // マイナススケール + _pose *= new float4x3(negativeScl, negativeScl, negativeScl); + + // 以降計算はすべてプロキシメッシュのローカル空間で行う + var bw = mappingBoneWeights[mvindex]; + int wcnt = bw.Count; + float4x3 _opose = 0; + // ProxyMeshスケール + for (int i = 0; i < wcnt; i++) + { + float w = bw.weights[i]; + + int tvindex = bw.boneIndices[i] + tdata.proxyCommonChunk.startIndex; + + // バインドポーズの逆座標と逆回転 + float3 bipos = proxyVertexBindPosePositions[tvindex]; + quaternion birot = proxyVertexBindPoseRotations[tvindex]; + + // マイナススケール + bipos *= tdata.negativeScaleDirection; + birot = birot.value * tdata.negativeScaleQuaternionValue; + + // quaternionからmatrixへの変換が重いのでここはそのまま + float3 pos = math.mul(birot, _pose.c0.xyz + bipos); + float3 nor = math.mul(birot, _pose.c1.xyz); + float3 tan = math.mul(birot, _pose.c2.xyz); + + float3 ppos = proxyPositions[tvindex]; + quaternion prot = proxyRotations[tvindex]; + + // ワールド変換 + // quaternionからmatrixへの変換が重いのでここはそのまま + pos = math.mul(prot, pos * proxyScl) + ppos; + nor = math.mul(prot, nor); + tan = math.mul(prot, tan); + + // ウエイト + _opose.c0.xyz += pos * w; + _opose.c1.xyz += nor * w; + _opose.c2.xyz += tan * w; + } + + // ここまでのopos/orotはワールド空間 + // マッピングメッシュのローカル空間に変換する + _opose.c0.w = 1; + _opose = math.mul(mdata.toMappingMatrix, _opose); + +#if MC2_DEBUG + + // 結果格納 + mappingPositions[mvindex] = _opose.c0.xyz; + //mappingNormals[mvindex] = math.normalize(_opose.c1.xyz); + //if (useTangent) + // mappingTangents[mvindex] = math.normalize(_opose.c2.xyz); +#endif +#if true + // ■結果格納 + // 書き込む頂点インデックス + int buffIndex = mappingReferenceIndices[mvindex]; + + // positoins / normals + int windex = wdata.renderMeshPositionAndNormalChunk.startIndex + buffIndex; + renderMeshPositions[windex] = _opose.c0.xyz; + renderMeshNormals[windex] = math.normalize(_opose.c1.xyz); + + // tangents + if (useTangent) + { + windex = wdata.renderMeshTangentChunk.startIndex + buffIndex; + float4 tan = renderMeshTangents[windex]; + renderMeshTangents[windex] = new float4(math.normalize(_opose.c2.xyz), tan.w); + } +#endif + // bone weights + if (modifyBoneWeight) + { + // 使用頂点のウエイトはcenterTransform100%で書き込む + windex = wdata.renderMeshBoneWeightChunk.startIndex + buffIndex; + renderMeshBoneWeights[windex] = wdata.centerBoneWeight; + } + } + //Debug.Log($"[{index}] renderMeshPositions:start={mdata.renderMeshPositionAndNormalChunk.startIndex}, length={mdata.renderMeshPositionAndNormalChunk.dataLength}"); + } + } + + /// + /// レンダーメッシュデータの後処理 + /// + [BurstCompile] + struct PostRenderMeshWorkDataBatchJob : IJobParallelFor + { + // render mesh + public NativeArray renderDataWorkArray; + + // mapping + [NativeDisableParallelForRestriction] + public NativeArray mappingDataArray; + + // RenderDataWorkごと + public void Execute(int windex) + { + var wdata = renderDataWorkArray[windex]; + if (wdata.IsValid() == false) + return; + if (wdata.UseCustomMesh == false) + return; + + // 各種書き込みフラグを設定する + bool changePositionNormal = false; + bool changeTangent = false; + bool changeBoneWeight = false; + int mcnt = wdata.mappingDataIndexList.Length; + for (int k = 0; k < mcnt; k++) + { + int mindex = wdata.mappingDataIndexList[k]; + var mdata = mappingDataArray[mindex]; + + if (mdata.flag.IsSet(TeamManager.MappingDataFlag_ChangePositionNormal)) + { + changePositionNormal = true; + mdata.flag.SetBits(TeamManager.MappingDataFlag_ChangePositionNormal, false); + } + if (mdata.flag.IsSet(TeamManager.MappingDataFlag_ChangeTangent)) + { + changeTangent = true; + mdata.flag.SetBits(TeamManager.MappingDataFlag_ChangeTangent, false); + } + if (mdata.flag.IsSet(TeamManager.MappingDataFlag_ChangeBoneWeight)) + { + changeBoneWeight = true; + mdata.flag.SetBits(TeamManager.MappingDataFlag_ChangeBoneWeight, false); + mdata.flag.SetBits(TeamManager.MappingDataFlag_ModifyBoneWeight, false); // Modifyフラグも消す + } + + mappingDataArray[mindex] = mdata; + } + + // 書き込みフラグ設定 + wdata.flag.SetBits(RenderManager.RenderDataFlag_WritePositionNormal, changePositionNormal); + wdata.flag.SetBits(RenderManager.RenderDataFlag_WriteTangent, changeTangent); + wdata.flag.SetBits(RenderManager.RenderDataFlag_WriteBoneWeight, changeBoneWeight); + + renderDataWorkArray[windex] = wdata; + } + } + + //========================================================================================= + public void InformationLog(StringBuilder allsb) + { + StringBuilder sb = new StringBuilder(); + sb.AppendLine($"========== VMesh Manager =========="); + if (IsValid() == false) + { + sb.AppendLine($"VirtualMesh Manager. Invalid."); + } + else + { + sb.AppendLine($"VirtualMesh Manager."); + sb.AppendLine($" -ProxyVertexCount:{ProxyVertexCount}"); + sb.AppendLine($" -ProxyEdgeCount:{ProxyEdgeCount}"); + sb.AppendLine($" -ProxyTriangleCount:{ProxyTriangleCount}"); + sb.AppendLine($" -ProxyBaseLineCount:{ProxyBaseLineCount}"); + sb.AppendLine($" -ProxyLocalPositionCount:{ProxyLocalPositionCount}"); + + sb.AppendLine($" [ProxyMesh]"); + sb.AppendLine($" -teamIds:{teamIds.ToSummary()}"); + sb.AppendLine($" -attributes:{attributes.ToSummary()}"); + sb.AppendLine($" -vertexToTriangles:{vertexToTriangles.ToSummary()}"); + sb.AppendLine($" -vertexBindPosePositions:{vertexBindPosePositions.ToSummary()}"); + sb.AppendLine($" -vertexBindPoseRotations:{vertexBindPoseRotations.ToSummary()}"); + sb.AppendLine($" -vertexDepths:{vertexDepths.ToSummary()}"); + sb.AppendLine($" -vertexRootIndices:{vertexRootIndices.ToSummary()}"); + sb.AppendLine($" -vertexLocalPositions:{vertexLocalPositions.ToSummary()}"); + sb.AppendLine($" -vertexLocalRotations:{vertexLocalRotations.ToSummary()}"); + sb.AppendLine($" -vertexParentIndices:{vertexParentIndices.ToSummary()}"); + sb.AppendLine($" -vertexChildIndexArray:{vertexChildIndexArray.ToSummary()}"); + sb.AppendLine($" -vertexChildDataArray:{vertexChildDataArray.ToSummary()}"); + sb.AppendLine($" -normalAdjustmentRotations:{normalAdjustmentRotations.ToSummary()}"); + sb.AppendLine($" -uv:{uv.ToSummary()}"); + + sb.AppendLine($" -triangleTeamIdArray:{triangleTeamIdArray.ToSummary()}"); + sb.AppendLine($" -triangles:{triangles.ToSummary()}"); + sb.AppendLine($" -triangleNormals:{triangleNormals.ToSummary()}"); + sb.AppendLine($" -triangleTangents:{triangleTangents.ToSummary()}"); + + sb.AppendLine($" -edgeTeamIdArray:{edgeTeamIdArray.ToSummary()}"); + sb.AppendLine($" -edges:{edges.ToSummary()}"); + sb.AppendLine($" -edgeFlags:{edgeFlags.ToSummary()}"); + + sb.AppendLine($" -baseLineFlags:{baseLineFlags.ToSummary()}"); + sb.AppendLine($" -baseLineTeamIds:{baseLineTeamIds.ToSummary()}"); + sb.AppendLine($" -baseLineStartDataIndices:{baseLineStartDataIndices.ToSummary()}"); + sb.AppendLine($" -baseLineDataCounts:{baseLineDataCounts.ToSummary()}"); + sb.AppendLine($" -baseLineData:{baseLineData.ToSummary()}"); + + sb.AppendLine($" [Mesh Common]"); + sb.AppendLine($" -localPositions:{localPositions.ToSummary()}"); + sb.AppendLine($" -localNormals:{localNormals.ToSummary()}"); + sb.AppendLine($" -localTangents:{localTangents.ToSummary()}"); + sb.AppendLine($" -boneWeights:{boneWeights.ToSummary()}"); + sb.AppendLine($" -skinBoneTransformIndices:{skinBoneTransformIndices.ToSummary()}"); + sb.AppendLine($" -skinBoneBindPoses:{skinBoneBindPoses.ToSummary()}"); + + sb.AppendLine($" [Mesh Other]"); + sb.AppendLine($" -vertexToTransformRotations:{vertexToTransformRotations.ToSummary()}"); + sb.AppendLine($" -positions:{positions.ToSummary()}"); + sb.AppendLine($" -rotations:{rotations.ToSummary()}"); + + sb.AppendLine($" [Mapping]"); + sb.AppendLine($" -MappingVertexCount:{MappingVertexCount}"); + sb.AppendLine($" -mappingReferenceIndices:{mappingReferenceIndices.ToSummary()}"); + sb.AppendLine($" -mappingAttributes:{mappingAttributes.ToSummary()}"); + sb.AppendLine($" -mappingLocalPositins:{mappingLocalPositins.ToSummary()}"); + sb.AppendLine($" -mappingLocalNormals:{mappingLocalNormals.ToSummary()}"); + sb.AppendLine($" -mappingBoneWeights:{mappingBoneWeights.ToSummary()}"); + //sb.AppendLine($" -mappingPositions:{mappingPositions.ToSummary()}"); + //sb.AppendLine($" -mappingNormals:{mappingNormals.ToSummary()}"); + + //sb.AppendLine($" [RenderMeshBuffer]"); + //sb.AppendLine($" -renderMeshPositions:{renderMeshPositions.ToSummary()}"); + //sb.AppendLine($" -renderMeshNormals:{renderMeshNormals.ToSummary()}"); + //sb.AppendLine($" -renderMeshTangents:{renderMeshTangents.ToSummary()}"); + } + sb.AppendLine(); + Debug.Log(sb.ToString()); + allsb.Append(sb); + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/Manager/VirtualMesh/VirtualMeshManager.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Manager/VirtualMesh/VirtualMeshManager.cs.meta new file mode 100644 index 00000000..c372b9f6 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Manager/VirtualMesh/VirtualMeshManager.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: ae2cd7d531771f9438f7fb94e886ee25 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Manager/VirtualMesh/VirtualMeshManager.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/PreBuild.meta b/Assets/MagicaCloth2/Scripts/Core/PreBuild.meta new file mode 100644 index 00000000..d9315f58 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/PreBuild.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 1f85ba9270154ec4ea99adc777266a0f +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/MagicaCloth2/Scripts/Core/PreBuild/PreBuildScriptableObject.cs b/Assets/MagicaCloth2/Scripts/Core/PreBuild/PreBuildScriptableObject.cs new file mode 100644 index 00000000..99c105ca --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/PreBuild/PreBuildScriptableObject.cs @@ -0,0 +1,64 @@ +// Magica Cloth 2. +// Copyright (c) 2024 MagicaSoft. +// https://magicasoft.jp +using System.Collections.Generic; +using UnityEngine; + +namespace MagicaCloth2 +{ + /// + /// PreBuildの保存アセットデータ + /// + [CreateAssetMenu(fileName = "Data", menuName = "MagicaCloth2/PreBuildScriptableObject")] + public class PreBuildScriptableObject : ScriptableObject + { + /// + /// 複数のPreBuildデータを格納可能 + /// + public List sharePreBuildDataList = new List(); + + //========================================================================================= + public bool HasPreBuildData(string buildId) + { + return GetPreBuildData(buildId) != null; + } + + public SharePreBuildData GetPreBuildData(string buildId) + { + foreach (var sdata in sharePreBuildDataList) + { + if (sdata.CheckBuildId(buildId)) + return sdata; + } + + return null; + } + + public void AddPreBuildData(SharePreBuildData sdata) + { + int index = sharePreBuildDataList.FindIndex(x => x.buildId == sdata.buildId); + if (index >= 0) + sharePreBuildDataList[index] = sdata; + else + sharePreBuildDataList.Add(sdata); + } + + //========================================================================================= + /// + /// すべてのPreBuildデータをデシリアライズしてマネージャに登録します + /// この処理は負荷が高いため事前に実行しておくことでクロスデータ利用時の負荷を軽減できます + /// Deserialize all PreBuild data and register it with the manager. + /// This process requires a high load, so running it in advance can reduce the load when using cross data. + /// + public void Warmup() + { + if (Application.isPlaying == false) + return; + + sharePreBuildDataList.ForEach(sdata => + { + MagicaManager.PreBuild.RegisterPreBuildData(sdata, false); + }); + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/PreBuild/PreBuildScriptableObject.cs.meta b/Assets/MagicaCloth2/Scripts/Core/PreBuild/PreBuildScriptableObject.cs.meta new file mode 100644 index 00000000..a7a81d93 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/PreBuild/PreBuildScriptableObject.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 45b12b58fd27b9a4bae4f50db55b4459 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/PreBuild/PreBuildScriptableObject.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/PreBuild/PreBuildSerializeData.cs b/Assets/MagicaCloth2/Scripts/Core/PreBuild/PreBuildSerializeData.cs new file mode 100644 index 00000000..ec3ccac3 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/PreBuild/PreBuildSerializeData.cs @@ -0,0 +1,101 @@ +// Magica Cloth 2. +// Copyright (c) 2024 MagicaSoft. +// https://magicasoft.jp +using System; +using System.Collections.Generic; +using UnityEngine; + +namespace MagicaCloth2 +{ + /// + /// PreBuildの保存データ + /// + [System.Serializable] + public class PreBuildSerializeData : ITransform + { + /// + /// 有効状態 + /// Valid state. + /// + public bool enabled = false; + + /// + /// ビルド識別ID + /// + public string buildId; + + /// + /// ビルドデータの共有部分 + /// このデータは複数のインスタンスで共有されるためScriptableObjectとして外部アセットとして保存される + /// + public PreBuildScriptableObject preBuildScriptableObject = null; + + /// + /// ビルドデータの固有部分 + /// このデータはインスタンスごとに固有となる + /// + public UniquePreBuildData uniquePreBuildData; + + //========================================================================================= + /// + /// PreBuild利用の有無 + /// + /// + public bool UsePreBuild() => enabled; + + /// + /// PreBuildデータの検証 + /// + /// + public ResultCode DataValidate() + { + if (uniquePreBuildData == null) + return new ResultCode(Define.Result.PreBuildData_Empty); + + var preBuildData = GetSharePreBuildData(); + if (preBuildData == null) + return new ResultCode(Define.Result.PreBuildData_Empty); + + var result = preBuildData.DataValidate(); + if (result.IsFaild()) + return result; + + result = uniquePreBuildData.DataValidate(); + if (result.IsFaild()) + return result; + + return ResultCode.Success; + } + + public SharePreBuildData GetSharePreBuildData() + { + if (preBuildScriptableObject == null) + return null; + + if (string.IsNullOrEmpty(buildId)) + return null; + + return preBuildScriptableObject.GetPreBuildData(buildId); ; + } + + /// + /// ビルドIDを生成する(英数字8文字) + /// + /// + public static string GenerateBuildID() + { + Guid g = Guid.NewGuid(); + return g.ToString().Substring(0, 8); + } + + public void GetUsedTransform(HashSet transformSet) + { + uniquePreBuildData.GetUsedTransform(transformSet); + } + + public void ReplaceTransform(Dictionary replaceDict) + { + uniquePreBuildData.ReplaceTransform(replaceDict); + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/PreBuild/PreBuildSerializeData.cs.meta b/Assets/MagicaCloth2/Scripts/Core/PreBuild/PreBuildSerializeData.cs.meta new file mode 100644 index 00000000..f074ebfa --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/PreBuild/PreBuildSerializeData.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 5c7522d5a2a34f84c9588683c5574fa9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/PreBuild/PreBuildSerializeData.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/PreBuild/SharePreBuildData.cs b/Assets/MagicaCloth2/Scripts/Core/PreBuild/SharePreBuildData.cs new file mode 100644 index 00000000..c8cc0326 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/PreBuild/SharePreBuildData.cs @@ -0,0 +1,69 @@ +// Magica Cloth 2. +// Copyright (c) 2024 MagicaSoft. +// https://magicasoft.jp +using System.Collections.Generic; +using System.Text; +using UnityEngine; + +namespace MagicaCloth2 +{ + /// + /// PreBuildデータの共有部分 + /// + [System.Serializable] + public class SharePreBuildData + { + public int version; + public string buildId; + public ResultCode buildResult; + public Vector3 buildScale; + + public List renderSetupDataList = new List(); + + public VirtualMesh.ShareSerializationData proxyMesh; + public List renderMeshList = new List(); + + public DistanceConstraint.ConstraintData distanceConstraintData; + public TriangleBendingConstraint.ConstraintData bendingConstraintData; + public InertiaConstraint.ConstraintData inertiaConstraintData; + + //========================================================================================= + public ResultCode DataValidate() + { + if (version != Define.System.LatestPreBuildVersion) + return new ResultCode(Define.Result.PreBuildData_VersionMismatch); + + if (buildScale.x < Define.System.Epsilon) + return new ResultCode(Define.Result.PreBuildData_InvalidScale); + + if (buildResult.IsFaild()) + return buildResult; + + return ResultCode.Success; + } + + public bool CheckBuildId(string buildId) + { + if (string.IsNullOrEmpty(buildId)) + return false; + + return this.buildId == buildId; + } + + public override string ToString() + { + StringBuilder sb = new StringBuilder(1024); + + sb.AppendLine("<<<<< PreBuildData >>>>>"); + sb.AppendLine($"Version:{version}"); + sb.AppendLine($"BuildID:{buildId}"); + sb.AppendLine($"BuildResult:{buildResult.GetResultString()}"); + sb.AppendLine($"BuildScale:{buildScale}"); + sb.AppendLine(proxyMesh.ToString()); + sb.AppendLine($"renderMeshList:{renderMeshList.Count}"); + sb.AppendLine($"renderSetupDataList:{renderSetupDataList.Count}"); + + return sb.ToString(); + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/PreBuild/SharePreBuildData.cs.meta b/Assets/MagicaCloth2/Scripts/Core/PreBuild/SharePreBuildData.cs.meta new file mode 100644 index 00000000..748ebb35 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/PreBuild/SharePreBuildData.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 280185e34f035f44d999fc83fffe8ab9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/PreBuild/SharePreBuildData.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/PreBuild/UniquePreBuildData.cs b/Assets/MagicaCloth2/Scripts/Core/PreBuild/UniquePreBuildData.cs new file mode 100644 index 00000000..b700c559 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/PreBuild/UniquePreBuildData.cs @@ -0,0 +1,49 @@ +// Magica Cloth 2. +// Copyright (c) 2024 MagicaSoft. +// https://magicasoft.jp +using System.Collections.Generic; +using UnityEngine; + +namespace MagicaCloth2 +{ + /// + /// PreBuildデータの固有部分 + /// + [System.Serializable] + public class UniquePreBuildData : ITransform + { + public int version; + public ResultCode buildResult; + + public List renderSetupDataList = new List(); + + public VirtualMesh.UniqueSerializationData proxyMesh; + public List renderMeshList = new List(); + + //========================================================================================= + public ResultCode DataValidate() + { + if (version != Define.System.LatestPreBuildVersion) + return new ResultCode(Define.Result.PreBuildData_VersionMismatch); + + if (buildResult.IsFaild()) + return buildResult; + + return ResultCode.Success; + } + + public void GetUsedTransform(HashSet transformSet) + { + renderSetupDataList.ForEach(x => x?.GetUsedTransform(transformSet)); + proxyMesh?.GetUsedTransform(transformSet); + renderMeshList.ForEach(x => x?.GetUsedTransform(transformSet)); + } + + public void ReplaceTransform(Dictionary replaceDict) + { + renderSetupDataList.ForEach(x => x?.ReplaceTransform(replaceDict)); + proxyMesh?.ReplaceTransform(replaceDict); + renderMeshList.ForEach(x => x?.ReplaceTransform(replaceDict)); + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/PreBuild/UniquePreBuildData.cs.meta b/Assets/MagicaCloth2/Scripts/Core/PreBuild/UniquePreBuildData.cs.meta new file mode 100644 index 00000000..c76b5cbc --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/PreBuild/UniquePreBuildData.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 0cee094d81395864ba3ef342016a8de6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/PreBuild/UniquePreBuildData.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Reduction.meta b/Assets/MagicaCloth2/Scripts/Core/Reduction.meta new file mode 100644 index 00000000..99e86e91 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Reduction.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: ca42d530d97d6bf40aa8379befc72777 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/MagicaCloth2/Scripts/Core/Reduction/ReductionSettings.cs b/Assets/MagicaCloth2/Scripts/Core/Reduction/ReductionSettings.cs new file mode 100644 index 00000000..4447fe72 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Reduction/ReductionSettings.cs @@ -0,0 +1,77 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using Unity.Mathematics; +using UnityEngine; + +namespace MagicaCloth2 +{ + /// + /// Configuration data for reduction. + /// リダクション用の設定データ + /// + [System.Serializable] + public class ReductionSettings : IDataValidate + { + /// + /// Simple distance reduction (% of AABB maximum distance) (0.0 ~ 1.0). + /// 単純な距離による削減(AABB最大距離の%)(0.0 ~ 1.0) + /// [NG] Runtime changes. + /// [NG] Export/Import with Presets + /// + [Range(0.0f, 0.2f)] + public float simpleDistance = 0.0f; + + /// + /// Reduction by distance considering geometry (% of AABB maximum distance) (0.0 ~ 1.0). + /// 形状を考慮した距離による削減(AABB最大距離の%)(0.0 ~ 1.0) + /// [NG] Runtime changes. + /// [NG] Export/Import with Presets + /// + [Range(0.0f, 0.2f)] + public float shapeDistance = 0.0f; + + //========================================================================================= + public bool IsEnabled => Define.System.ReductionEnable; + + public float GetMaxConnectionDistance() + { + return math.max(math.max(Define.System.ReductionSameDistance, simpleDistance), shapeDistance); + } + + public ReductionSettings Clone() + { + return new ReductionSettings() + { + simpleDistance = simpleDistance, + shapeDistance = shapeDistance, + }; + } + + public void DataValidate() + { + simpleDistance = Mathf.Clamp(simpleDistance, 0.0f, 0.2f); + shapeDistance = Mathf.Clamp(shapeDistance, 0.0f, 0.2f); + } + + /// + /// エディタメッシュの更新を判定するためのハッシュコード + /// (このハッシュは実行時には利用されない編集用のもの) + /// + /// + public override int GetHashCode() + { + int hash = 0; + hash += simpleDistance.GetHashCode(); + hash += shapeDistance.GetHashCode(); + + return hash; + } + + public override string ToString() + { + return $"ReductionSettings. sameDist:{Define.System.ReductionSameDistance}, simpleDist:{simpleDistance}, shapeDist:{shapeDistance} maxStep:{Define.System.ReductionMaxStep}"; + } + + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/Reduction/ReductionSettings.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Reduction/ReductionSettings.cs.meta new file mode 100644 index 00000000..6be4d30d --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Reduction/ReductionSettings.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 143de5f6b100ea74a87486d4d796dd38 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Reduction/ReductionSettings.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Reduction/ReductionWorkData.cs b/Assets/MagicaCloth2/Scripts/Core/Reduction/ReductionWorkData.cs new file mode 100644 index 00000000..24de3b53 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Reduction/ReductionWorkData.cs @@ -0,0 +1,141 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using System; +using Unity.Collections; +using Unity.Mathematics; + +namespace MagicaCloth2 +{ + public class ReductionWorkData : IDisposable + { + public VirtualMesh vmesh; + + //========================================================================================= + // リダクション作業データ + //========================================================================================= + /// + /// 頂点の結合先インデックス(-1=生存している, 0以上=削除されている) + /// + public NativeArray vertexJoinIndices; + + /// + /// 頂点ごとの接続頂点インデックスリスト + /// + public NativeParallelMultiHashMap vertexToVertexMap; + + //========================================================================================= + // メッシュ最適化作業データ + //========================================================================================= + /// + /// 古い頂点インデックスから新しい頂点インデックスへの変換リスト + /// + public NativeArray vertexRemapIndices; + + /// + /// スキニングボーンのインデックス変換辞書 + /// キー:最適化前のボーンインデックス、データ:最適化後のボーンインデックス + /// + public NativeParallelHashMap useSkinBoneMap; + + /// + /// 新しい頂点の頂点接続リスト + /// + public NativeParallelMultiHashMap newVertexToVertexMap; + + public NativeParallelHashSet edgeSet; + public NativeParallelHashSet triangleSet; + + + //========================================================================================= + // 最終的なメッシュデータ + //========================================================================================= + public int oldVertexCount; + public int newVertexCount; + public int removeVertexCount; + + public ExSimpleNativeArray newAttributes; + public ExSimpleNativeArray newLocalPositions; + public ExSimpleNativeArray newLocalNormals; + public ExSimpleNativeArray newLocalTangents; + public ExSimpleNativeArray newUv; + public ExSimpleNativeArray newBoneWeights; + + public NativeReference newSkinBoneCount; + public NativeList newSkinBoneTransformIndices; + public NativeList newSkinBoneBindPoseList; + + public NativeList newLineList; + public NativeList newTriangleList; + + //========================================================================================= + public ReductionWorkData(VirtualMesh vmesh) + { + this.vmesh = vmesh; + } + + public void Dispose() + { + if (vertexJoinIndices.IsCreated) + vertexJoinIndices.Dispose(); + if (vertexToVertexMap.IsCreated) + vertexToVertexMap.Dispose(); + if (vertexRemapIndices.IsCreated) + vertexRemapIndices.Dispose(); + if (useSkinBoneMap.IsCreated) + useSkinBoneMap.Dispose(); + if (newVertexToVertexMap.IsCreated) + newVertexToVertexMap.Dispose(); + if (edgeSet.IsCreated) + edgeSet.Dispose(); + if (triangleSet.IsCreated) + triangleSet.Dispose(); + + // 最終メッシュデータ + newAttributes?.Dispose(); + newLocalPositions?.Dispose(); + newLocalNormals?.Dispose(); + newLocalTangents?.Dispose(); + newUv?.Dispose(); + newBoneWeights?.Dispose(); + if (newSkinBoneCount.IsCreated) + newSkinBoneCount.Dispose(); + if (newSkinBoneTransformIndices.IsCreated) + newSkinBoneTransformIndices.Dispose(); + if (newSkinBoneBindPoseList.IsCreated) + newSkinBoneBindPoseList.Dispose(); + if (newLineList.IsCreated) + newLineList.Dispose(); + if (newTriangleList.IsCreated) + newTriangleList.Dispose(); + } + +#if false + + public void DebugVerify() + { + // vertexToVertexMap + //using var keyArray = vertexToVertexMap.GetKeyArray(Allocator.TempJob); + //foreach (var key in keyArray) + //{ + // int cnt = vertexToVertexMap.CountValuesForKey(key); + // if (cnt == 0) + // { + // Develop.DebugLogWarning($"vertexToVertexMap. no data! :{key}"); + // } + //} + } + + public void DebugInfo() + { + // vertexToVertexMap + //using var keyArray = vertexToVertexMap.GetKeyArray(Allocator.TempJob); + //foreach (var key in keyArray) + //{ + // int cnt = vertexToVertexMap.CountValuesForKey(key); + // Develop.DebugLog($"vertexToVertexMap [{key}] cnt:{cnt}"); + //} + } +#endif + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/Reduction/ReductionWorkData.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Reduction/ReductionWorkData.cs.meta new file mode 100644 index 00000000..4311ef44 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Reduction/ReductionWorkData.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 96acdb752b9af6746a6eb571598ca2dd +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Reduction/ReductionWorkData.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Reduction/SameDistanceReduction.cs b/Assets/MagicaCloth2/Scripts/Core/Reduction/SameDistanceReduction.cs new file mode 100644 index 00000000..81bb4ad1 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Reduction/SameDistanceReduction.cs @@ -0,0 +1,560 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using System; +using Unity.Burst; +using Unity.Collections; +using Unity.Jobs; +using Unity.Mathematics; +using UnityEngine; +#if MAGICACLOTH2_REDUCTION_DEBUG +using UnityEngine; +#endif + +namespace MagicaCloth2 +{ + /// + /// 距離内のすべての頂点を一度に結合させる + /// + public class SameDistanceReduction : IDisposable + { + string name = string.Empty; + VirtualMesh vmesh; + ReductionWorkData workData; + ResultCode result; + float mergeLength; + + //========================================================================================= + GridMap gridMap; + //NativeParallelHashSet joinPairSet; + NativeParallelMultiHashMap joinPairMap; + NativeReference resultRef; + + //========================================================================================= + public SameDistanceReduction() { } + + public SameDistanceReduction( + string name, + VirtualMesh mesh, + ReductionWorkData workingData, + float mergeLength + ) + { + this.name = name; + this.vmesh = mesh; + this.workData = workingData; + this.result = ResultCode.None; + this.mergeLength = math.max(mergeLength, 1e-09f); + } + + public virtual void Dispose() + { + //if (joinPairSet.IsCreated) + // joinPairSet.Dispose(); + if (joinPairMap.IsCreated) + joinPairMap.Dispose(); + if (resultRef.IsCreated) + resultRef.Dispose(); + gridMap?.Dispose(); + } + + public ResultCode Result => result; + + //========================================================================================= + /// + /// リダクション実行(スレッド可) + /// + /// + public ResultCode Reduction() + { + //bool success = false; + result.Clear(); + + try + { + // グリッドマップ + gridMap = new GridMap(vmesh.VertexCount); + + // 最適なグリッドサイズを割り出す(mergeLengthは>0が保証されている) + float gridSize = mergeLength * 2.0f; + + // 頂点ごとの接続マップ + // インデックスが若い方が記録する + //joinPairSet = new NativeParallelHashSet(vmesh.VertexCount / 4, Allocator.Persistent); + joinPairMap = new NativeParallelMultiHashMap(vmesh.VertexCount, Allocator.Persistent); + resultRef = new NativeReference(Allocator.Persistent); + + // ポイントをグリッドに登録 + var initGridJob = new InitGridJob() + { + vcnt = vmesh.VertexCount, + gridSize = gridSize, + localPositions = vmesh.localPositions.GetNativeArray(), + joinIndices = workData.vertexJoinIndices, + gridMap = gridMap.GetMultiHashMap(), + }; + initGridJob.Run(); + + // 近傍頂点を検索、結合マップに登録する + var searchJoinJob = new SearchJoinJob() + { + vcnt = vmesh.VertexCount, + gridSize = gridSize, + radius = mergeLength, + localPositions = vmesh.localPositions.GetNativeArray(), + joinIndices = workData.vertexJoinIndices, + gridMap = gridMap.GetMultiHashMap(), + //joinPairSet = joinPairSet, + joinPairMap = joinPairMap, + }; + searchJoinJob.Run(); + + // 結合する +#if false + var joinJob = new JoinJob() + { + vertexCount = vmesh.VertexCount, + //joinPairSet = joinPairSet, + joinPairMap = joinPairMap, + joinIndices = workData.vertexJoinIndices, + vertexToVertexMap = workData.vertexToVertexMap, + boneWeights = vmesh.boneWeights.GetNativeArray(), + attributes = vmesh.attributes.GetNativeArray(), + result = resultRef, + }; + joinJob.Run(); +#endif +#if true + // 高速化および詳細メッシュがある場合に1つの頂点に大量に結合しオーバーフローが発生する問題を回避したもの + // 以前はA->B->C結合時にA->C間が接続距離以上でもA->Cが結合されてしまったが、この改良版ではそれがおこならない + // そのため以前とは結果がことなることに注意! + using var tempList = new NativeList(2048, Allocator.Persistent); + var joinJob2 = new JoinJob2() + { + vertexCount = vmesh.VertexCount, + joinPairMap = joinPairMap, + joinIndices = workData.vertexJoinIndices, + vertexToVertexMap = workData.vertexToVertexMap, + boneWeights = vmesh.boneWeights.GetNativeArray(), + attributes = vmesh.attributes.GetNativeArray(), + result = resultRef, + tempList = tempList, + }; + joinJob2.Run(); +#endif + + // 頂点の接続状態を最新に更新する。すべて最新の生存ポイントを指すように変更する + UpdateJoinAndLink(); + + // 頂点情報を整理する + // 法線単位化 + // ボーンウエイトを1に平均化 + UpdateReductionResultJob(); + + // 削除頂点数集計 + int removeVertexCount = resultRef.Value; + workData.removeVertexCount += removeVertexCount; + //Debug.Log($"[SameDistanceReduction [{name}]] mergeLength:{mergeLength} RemoveVertex:{removeVertexCount}"); + + // 完了 + //success = true; + result.SetSuccess(); + } + catch (Exception exception) + { + Debug.LogError(exception); + result.SetError(Define.Result.Reduction_SameDistanceException); + } + finally + { + // 作業バッファを解放する(重要) + // ★仮にタスクが例外やキャンセルされたとしてもこれで作成したバッファは正しくDispose()される + //MagicaManager.Discard.Add(); + + // 登録したジョブを解除する(重要) + // ★仮にタスクが例外やキャンセルされたとしてもこれで発行したJobは正しくComplete()される + //MagicaManager.Thread.DisposeJob(int); + } + + return result; + } + + //========================================================================================= + [BurstCompile] + struct InitGridJob : IJob + { + public int vcnt; + public float gridSize; + [Unity.Collections.ReadOnly] + public NativeArray localPositions; + [Unity.Collections.ReadOnly] + public NativeArray joinIndices; + public NativeParallelMultiHashMap gridMap; + + // 頂点ごと + public void Execute() + { + for (int vindex = 0; vindex < vcnt; vindex++) + { + if (joinIndices[vindex] >= 0) + continue; // isDelete + + GridMap.AddGrid(localPositions[vindex], vindex, gridMap, gridSize); + } + } + } + + [BurstCompile] + struct SearchJoinJob : IJob + { + public int vcnt; + public float gridSize; + public float radius; + + [Unity.Collections.ReadOnly] + public NativeArray localPositions; + [Unity.Collections.ReadOnly] + public NativeArray joinIndices; + [Unity.Collections.ReadOnly] + public NativeParallelMultiHashMap gridMap; + + //public NativeParallelHashSet joinPairSet; + public NativeParallelMultiHashMap joinPairMap; + + public void Execute() + { + for (int vindex = 0; vindex < vcnt; vindex++) + { + if (joinIndices[vindex] >= 0) + continue; // isDelete + + float3 pos = localPositions[vindex]; + + // 範囲グリッド走査 + foreach (int3 grid in GridMap.GetArea(pos, radius, gridMap, gridSize)) + { + if (gridMap.ContainsKey(grid) == false) + continue; + + // このグリッドを検索する + foreach (int tvindex in gridMap.GetValuesForKey(grid)) + { + // 自身は弾く + if (tvindex == vindex) + continue; + + // 距離判定 + float3 tpos = localPositions[tvindex]; + float dist = math.distance(pos, tpos); + if (dist > radius) + continue; + + // 結合登録 + //int2 ehash = DataUtility.PackInt2(vindex, tvindex); + //joinPairSet.Add(ehash); + joinPairMap.Add((ushort)vindex, (ushort)tvindex); + } + } + } + } + } + + [BurstCompile] + struct JoinJob2 : IJob + { + public int vertexCount; + + [Unity.Collections.ReadOnly] + public NativeParallelMultiHashMap joinPairMap; + + public NativeArray joinIndices; + public NativeParallelMultiHashMap vertexToVertexMap; + public NativeArray boneWeights; + public NativeArray attributes; + public NativeReference result; + + public NativeList tempList; + + public void Execute() + { + int cnt = 0; + + for (ushort vindexLive = 0; vindexLive < vertexCount; vindexLive++) + { + // すでに結合済みならスキップ + if (joinIndices[vindexLive] >= 0) + continue; + + // 対象ループ + foreach (ushort vindexDead in joinPairMap.GetValuesForKey(vindexLive)) + { + // 対象がすでに結合ずみならスキップ + if (joinIndices[vindexDead] >= 0) + continue; + + // 結合(vertexDead -> vertexLive) + joinIndices[vindexDead] = vindexLive; + cnt++; + + vertexToVertexMap.MC2RemoveValue(vindexLive, vindexDead); + + tempList.Clear(); + foreach (ushort i in vertexToVertexMap.GetValuesForKey(vindexDead)) + { + tempList.Add(i); + } + foreach (ushort i in tempList) + { + if (joinIndices[i] >= 0) + continue; + if (i == vindexLive || i == vindexDead) + continue; + + vertexToVertexMap.MC2RemoveValue(i, vindexDead); + + vertexToVertexMap.MC2UniqueAdd(vindexLive, i); + vertexToVertexMap.MC2UniqueAdd(i, vindexLive); + + // p2にBoneWeightを結合 + var bw = boneWeights[vindexLive]; + bw.AddWeight(boneWeights[vindexDead]); + boneWeights[vindexLive] = bw; + + // 属性 + var attr1 = attributes[vindexDead]; + var attr2 = attributes[vindexLive]; + attributes[vindexLive] = VertexAttribute.JoinAttribute(attr1, attr2); + attributes[vindexDead] = VertexAttribute.Invalid; // 削除頂点は無効にする + } + } + } + + // 削除頂点数記録 + result.Value = cnt; + } + } + +#if false // old + [BurstCompile] + struct JoinJob : IJob + { + [Unity.Collections.ReadOnly] + public NativeParallelHashSet joinPairSet; + + public NativeArray joinIndices; + public NativeParallelMultiHashMap vertexToVertexMap; + public NativeArray boneWeights; + public NativeArray attributes; + public NativeReference result; + + public void Execute() + { + var workSet = new FixedList512Bytes(); + int cnt = 0; + + foreach (var ehash in joinPairSet) + { + int vindexLive = ehash[0]; // 生存側 + int vindexDead = ehash[1]; // 削除側 + + while (joinIndices[vindexDead] >= 0) + { + vindexDead = joinIndices[vindexDead]; + } + while (joinIndices[vindexLive] >= 0) + { + vindexLive = joinIndices[vindexLive]; + } + if (vindexDead == vindexLive) + continue; + + // 結合(vertex1 -> vertex2) + joinIndices[vindexDead] = vindexLive; + cnt++; + + // 接続数を結合する(重複は弾かれる) + workSet.Clear(); + foreach (ushort i in vertexToVertexMap.GetValuesForKey((ushort)vindexDead)) + { + int index = i; + // 生存インデックス + while (joinIndices[index] >= 0) + { + index = joinIndices[index]; + } + if (index != vindexDead && index != vindexLive) + workSet.MC2Set((ushort)index); + } + foreach (ushort i in vertexToVertexMap.GetValuesForKey((ushort)vindexLive)) + { + int index = i; + // 生存インデックス + while (joinIndices[index] >= 0) + { + index = joinIndices[index]; + } + if (index != vindexDead && index != vindexLive) + workSet.MC2Set((ushort)index); + } + vertexToVertexMap.Remove((ushort)vindexLive); + for (int i = 0; i < workSet.Length; i++) + { + vertexToVertexMap.Add((ushort)vindexLive, workSet[i]); + } + //Debug.Assert(workSet.Length > 0); + + // p2にBoneWeightを結合 + var bw = boneWeights[vindexLive]; + bw.AddWeight(boneWeights[vindexDead]); + boneWeights[vindexLive] = bw; + + // 属性 + var attr1 = attributes[vindexDead]; + var attr2 = attributes[vindexLive]; + attributes[vindexLive] = VertexAttribute.JoinAttribute(attr1, attr2); + attributes[vindexDead] = VertexAttribute.Invalid; // 削除頂点は無効にする + } + + // 削除頂点数記録 + result.Value = cnt; + } + } +#endif + + //========================================================================================= + /// + /// 接続状態を最新に更新するジョブを発行する + /// + /// + /// + void UpdateJoinAndLink() + { + // JoinIndexの状態を更新する。現在の最新の生存ポイントを指すように変更する + var updateJoinIndexJob = new UpdateJoinIndexJob() + { + joinIndices = workData.vertexJoinIndices, + }; + updateJoinIndexJob.Run(vmesh.VertexCount); + + // 頂点の接続頂点リストを最新に更新する。すべて最新の生存ポイントを指すように変更する + var updateLinkIndexJob = new UpdateLinkIndexJob() + { + joinIndices = workData.vertexJoinIndices, + vertexToVertexMap = workData.vertexToVertexMap, + }; + updateLinkIndexJob.Run(vmesh.VertexCount); + } + + [BurstCompile] + struct UpdateJoinIndexJob : IJobParallelFor + { + [NativeDisableParallelForRestriction] + public NativeArray joinIndices; + + public void Execute(int vindex) + { + int join = joinIndices[vindex]; + if (join >= 0) + { + // 削除されている + // 最終的な生存ポイントに連結させる + while (joinIndices[join] >= 0) + { + join = joinIndices[join]; + } + joinIndices[vindex] = join; + } + } + } + + [BurstCompile] + struct UpdateLinkIndexJob : IJobParallelFor + { + [NativeDisableParallelForRestriction] + public NativeArray joinIndices; + public NativeParallelMultiHashMap vertexToVertexMap; + + public void Execute(int vindex) + { + int join = joinIndices[vindex]; + + // 自身が削除されている場合は無視 + if (join >= 0) + return; + + // 自身が生存している + // 現在の接続インデックスから削除されたものを生存インデックスに入れ替える + var newLinkSet = new FixedList512Bytes(); + foreach (ushort i in vertexToVertexMap.GetValuesForKey((ushort)vindex)) + { + int tvindex = i; + int tjoin = joinIndices[tvindex]; + if (tjoin >= 0) + { + // 削除されている + tvindex = tjoin; + Debug.Assert(joinIndices[tvindex] < 0); + } + + // 自身は弾く + if (tvindex == vindex) + continue; + + newLinkSet.MC2Set((ushort)tvindex); + } + // 生存のみの新しいセットに入れ替え + vertexToVertexMap.Remove((ushort)vindex); + for (int i = 0; i < newLinkSet.Length; i++) + { + vertexToVertexMap.Add((ushort)vindex, newLinkSet[i]); + } + //Debug.Assert(newLinkSet.Length > 0); + } + } + + //========================================================================================= + /// + /// リダクション後のデータを整える + /// + void UpdateReductionResultJob() + { + // 頂点法線の単位化、およびボーンウエイトを1に整える + var finalVertexJob = new FinalMergeVertexJob() + { + joinIndices = workData.vertexJoinIndices, + localNormals = vmesh.localNormals.GetNativeArray(), + boneWeights = vmesh.boneWeights.GetNativeArray(), + }; + finalVertexJob.Run(vmesh.VertexCount); + } + + [BurstCompile] + struct FinalMergeVertexJob : IJobParallelFor + { + [Unity.Collections.ReadOnly] + public NativeArray joinIndices; + + public NativeArray localNormals; + public NativeArray boneWeights; + + // 頂点ごと + public void Execute(int vindex) + { + int join = joinIndices[vindex]; + if (join >= 0) + { + // 削除されている + return; + } + + // 法線単位化 + localNormals[vindex] = math.normalize(localNormals[vindex]); + + // ボーンウエイトを平均化 + var bw = boneWeights[vindex]; + bw.AdjustWeight(); + boneWeights[vindex] = bw; + } + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/Reduction/SameDistanceReduction.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Reduction/SameDistanceReduction.cs.meta new file mode 100644 index 00000000..adceda8f --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Reduction/SameDistanceReduction.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 9a8f11c168bca19409d6e7cec1de9fc8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Reduction/SameDistanceReduction.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Reduction/ShapeDistanceReduction.cs b/Assets/MagicaCloth2/Scripts/Core/Reduction/ShapeDistanceReduction.cs new file mode 100644 index 00000000..12b5973d --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Reduction/ShapeDistanceReduction.cs @@ -0,0 +1,145 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using Unity.Burst; +using Unity.Collections; +using Unity.Jobs; +using Unity.Mathematics; + +namespace MagicaCloth2 +{ + /// + /// 形状に合わせた頂点リダクション + /// このリダクションは頂点の接続状態に沿ってリダクションを行う + /// + public class ShapeDistanceReduction : StepReductionBase + { + //========================================================================================= + public ShapeDistanceReduction( + string name, + VirtualMesh mesh, + ReductionWorkData workingData, + float startMergeLength, + float endMergeLength, + int maxStep, + bool dontMakeLine, + float joinPositionAdjustment + ) + : base($"ShapeReduction [{name}]", mesh, workingData, startMergeLength, endMergeLength, maxStep, dontMakeLine, joinPositionAdjustment) + { + } + + public override void Dispose() + { + base.Dispose(); + } + + protected override void StepInitialize() + { + base.StepInitialize(); + } + + protected override void CustomReductionStep() + { + // 近傍ペアを検索、結合エッジリストに登録 + var searchJob = new SearchJoinEdgeJob() + { + vcnt = vmesh.VertexCount, + radius = nowMergeLength, + dontMakeLine = dontMakeLine, + localPositions = vmesh.localPositions.GetNativeArray(), + joinIndices = workData.vertexJoinIndices, + //vertexToVertexArray = workData.vertexToVertexArray, + vertexToVertexMap = workData.vertexToVertexMap, + joinEdgeList = joinEdgeList, + }; + searchJob.Run(); + } + + [BurstCompile] + struct SearchJoinEdgeJob : IJob + { + public int vcnt; + public float radius; + public bool dontMakeLine; + + [Unity.Collections.ReadOnly] + public NativeArray localPositions; + [Unity.Collections.ReadOnly] + public NativeArray joinIndices; + [Unity.Collections.ReadOnly] + public NativeParallelMultiHashMap vertexToVertexMap; + //public NativeArray> vertexToVertexArray; + + public NativeList joinEdgeList; + + public void Execute() + { + for (int vindex = 0; vindex < vcnt; vindex++) + { + if (joinIndices[vindex] >= 0) + continue; // isDelete + + // 接続頂点リスト + int vcnt = vertexToVertexMap.CountValuesForKey((ushort)vindex); + if (vcnt == 0) + continue; // 接続なし + //var vlist = vertexToVertexArray[vindex]; + //if (vlist.Count == 0) + // continue; // 接続なし + + float3 pos = localPositions[vindex]; + + // 自身の接続頂点数 + //float linkCount = math.max(vlist.Count - 1, 1); + float linkCount = math.max(vcnt - 1, 1); + + // 範囲内で最もコストが低い接続ペアを登録する + float minCost = float.MaxValue; + int minVindex = -1; + //for (int i = 0; i < vlist.Count; i++) + foreach (ushort tvindex in vertexToVertexMap.GetValuesForKey((ushort)vindex)) + { + //int tvindex = vlist.Get(i); + + // 距離判定 + float3 tpos = localPositions[tvindex]; + float dist = math.distance(pos, tpos); + if (dist > radius) + continue; + + // 相手の接続頂点数 + float tlinkCount = math.max(vertexToVertexMap.CountValuesForKey(tvindex) - 1, 1); + //var tvlist = vertexToVertexArray[tvindex]; + //float tlinkCount = math.max(tvlist.Count - 1, 1); + + // この頂点を結合して問題がないか調べる + //if (CheckJoin(vertexToVertexArray, vindex, tvindex, vlist, tvlist, dontMakeLine) == false) + if (CheckJoin2(vertexToVertexMap, vindex, tvindex, dontMakeLine) == false) + continue; + + // コスト計算 + float cost = dist * (1.0f + (linkCount + tlinkCount) / 2.0f); // とりあえず + + // 最小コスト判定 + if (cost < minCost) + { + minCost = cost; + minVindex = tvindex; + } + } + if (minVindex >= 0) + { + // 登録 + var pair = new JoinEdge() + { + vertexPair = new int2(vindex, minVindex), + cost = minCost, + }; + joinEdgeList.Add(pair); + } + } + } + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/Reduction/ShapeDistanceReduction.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Reduction/ShapeDistanceReduction.cs.meta new file mode 100644 index 00000000..64c37c81 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Reduction/ShapeDistanceReduction.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 2b8b32d329a0b2541afe170d131c5f76 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Reduction/ShapeDistanceReduction.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Reduction/SimpleDistanceReduction.cs b/Assets/MagicaCloth2/Scripts/Core/Reduction/SimpleDistanceReduction.cs new file mode 100644 index 00000000..a9d39564 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Reduction/SimpleDistanceReduction.cs @@ -0,0 +1,182 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using Unity.Burst; +using Unity.Collections; +using Unity.Jobs; +using Unity.Mathematics; + +namespace MagicaCloth2 +{ + /// + /// 単純な頂点間の距離によるリダクション + /// このリダクションは頂点の接続状態を無視する + /// + public class SimpleDistanceReduction : StepReductionBase + { + /// + /// グリッドマップ + /// + private GridMap gridMap; + + //========================================================================================= + public SimpleDistanceReduction( + string name, + VirtualMesh mesh, + ReductionWorkData workingData, + float startMergeLength, + float endMergeLength, + int maxStep, + bool dontMakeLine, + float joinPositionAdjustment + ) + : base($"SimpleDistanceReduction [{name}]", mesh, workingData, startMergeLength, endMergeLength, maxStep, dontMakeLine, joinPositionAdjustment) + { + } + + public override void Dispose() + { + base.Dispose(); + gridMap.Dispose(); + } + + protected override void StepInitialize() + { + base.StepInitialize(); + gridMap = new GridMap(vmesh.VertexCount); + } + + protected override void CustomReductionStep() + { + // 最適なグリッドサイズを割り出す(nowMergeLengthは>0が保証されている) + float gridSize = nowMergeLength * 2.0f; // 1.5? + + // 作業用バッファクリア + gridMap.GetMultiHashMap().Clear(); + + // ポイントをグリッドに登録 + var initGridJob = new InitGridJob() + { + vcnt = vmesh.VertexCount, + gridSize = gridSize, + localPositions = vmesh.localPositions.GetNativeArray(), + joinIndices = workData.vertexJoinIndices, + gridMap = gridMap.GetMultiHashMap(), + }; + initGridJob.Run(); + + // 近傍ポイントを検索、結合エッジリストに登録 + var searchJob = new SearchJoinEdgeJob() + { + vcnt = vmesh.VertexCount, + gridSize = gridSize, + radius = nowMergeLength, + localPositions = vmesh.localPositions.GetNativeArray(), + joinIndices = workData.vertexJoinIndices, + vertexToVertexMap = workData.vertexToVertexMap, // cost用 + gridMap = gridMap.GetMultiHashMap(), + joinEdgeList = joinEdgeList, + }; + searchJob.Run(); + } + + [BurstCompile] + struct InitGridJob : IJob + { + public int vcnt; + public float gridSize; + + [Unity.Collections.ReadOnly] + public NativeArray localPositions; + [Unity.Collections.ReadOnly] + public NativeArray joinIndices; + + public NativeParallelMultiHashMap gridMap; + + // 頂点ごと + public void Execute() + { + for (int vindex = 0; vindex < vcnt; vindex++) + { + if (joinIndices[vindex] >= 0) + continue; // isDelete + + GridMap.AddGrid(localPositions[vindex], vindex, gridMap, gridSize); + } + } + } + + [BurstCompile] + struct SearchJoinEdgeJob : IJob + { + public int vcnt; + public float gridSize; + public float radius; + + [Unity.Collections.ReadOnly] + public NativeArray localPositions; + [Unity.Collections.ReadOnly] + public NativeArray joinIndices; + + [Unity.Collections.ReadOnly] + public NativeParallelMultiHashMap vertexToVertexMap; + [Unity.Collections.ReadOnly] + public NativeParallelMultiHashMap gridMap; + + [Unity.Collections.WriteOnly] + public NativeList joinEdgeList; + + // 頂点ごと + public void Execute() + { + for (int vindex = 0; vindex < vcnt; vindex++) + { + if (joinIndices[vindex] >= 0) + continue; // isDelete + + float3 pos = localPositions[vindex]; + + // 自身の接続頂点数 + float linkCount = math.max(vertexToVertexMap.CountValuesForKey((ushort)vindex) - 1, 1); + + // 範囲グリッド走査 + foreach (int3 grid in GridMap.GetArea(pos, radius, gridMap, gridSize)) + { + if (gridMap.ContainsKey(grid) == false) + continue; + + // このグリッドを検索する + foreach (int tindex in gridMap.GetValuesForKey(grid)) + { + // 自身は弾く + if (tindex == vindex) + continue; + + // 距離判定 + float3 tpos = localPositions[tindex]; + float dist = math.distance(pos, tpos); + if (dist > radius) + continue; + + // 相手の接続頂点数 + float tlinkCount = math.max(vertexToVertexMap.CountValuesForKey((ushort)tindex) - 1, 1); + + // コスト計算 + //float cost = dist / (linkCount + tlinkCount); // todo:とりあえずテスト + //float cost = dist * (1.0f / (linkCount + tlinkCount)); + float cost = dist * (1.0f + (linkCount + tlinkCount) / 2.0f); // 12 + + // 全部登録 + var pair = new JoinEdge() + { + vertexPair = new int2(vindex, tindex), + cost = cost, + }; + joinEdgeList.Add(pair); + } + } + } + } + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/Reduction/SimpleDistanceReduction.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Reduction/SimpleDistanceReduction.cs.meta new file mode 100644 index 00000000..dc65c991 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Reduction/SimpleDistanceReduction.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: b244c982dfa4761478be41f4a264d73e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Reduction/SimpleDistanceReduction.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Reduction/StepReductionBase.cs b/Assets/MagicaCloth2/Scripts/Core/Reduction/StepReductionBase.cs new file mode 100644 index 00000000..b4e09a24 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Reduction/StepReductionBase.cs @@ -0,0 +1,773 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using System; +using Unity.Burst; +using Unity.Collections; +using Unity.Jobs; +using Unity.Mathematics; +using UnityEngine; +#if MAGICACLOTH2_REDUCTION_DEBUG +using UnityEngine; +#endif + +namespace MagicaCloth2 +{ + /// + /// 結合距離を拡大させながら段階的にリダクションする方式のベースクラス + /// 高速化のため結合候補のペアのうち頂点が被らないものを1回のステップですべて結合させる。 + /// このため結合距離内にもかかわらず結合されないペアが発生することになる。 + /// この問題は手順を複数可実行することで徐々に収束させて解決する。 + /// + public abstract class StepReductionBase : IDisposable + { + protected string name = string.Empty; + protected VirtualMesh vmesh; + protected ReductionWorkData workData; + protected ResultCode result; + + protected float startMergeLength; + protected float endMergeLength; + protected int maxStep; + protected bool dontMakeLine; + protected float joinPositionAdjustment; + + protected int nowStepIndex; + protected float nowMergeLength; + protected float nowStepScale; + + //========================================================================================= + /// + /// 結合エッジ情報 + /// + public struct JoinEdge : IComparable + { + public int2 vertexPair; + public float cost; + + public bool Contains(in int2 pair) + { + if (vertexPair.x == pair.x || vertexPair.x == pair.y || vertexPair.y == pair.x || vertexPair.y == pair.y) + return true; + else + return false; + } + + public int CompareTo(JoinEdge other) + { + // コストの昇順 + if (cost != other.cost) + return cost < other.cost ? -1 : 1; + else + return 0; + } + } + protected NativeList joinEdgeList; + + // すでに結合された頂点セット + private NativeParallelHashSet completeVertexSet; + + // 結合された頂点ペア(x->yへ結合) + private NativeList removePairList; + + // ステップごとの削減頂点数 + private NativeArray resultArray; + + //========================================================================================= + public StepReductionBase() { } + + public StepReductionBase( + string name, + VirtualMesh mesh, + ReductionWorkData workingData, + float startMergeLength, + float endMergeLength, + int maxStep, + bool dontMakeLine, + float joinPositionAdjustment + ) + { + this.name = name; + this.vmesh = mesh; + this.workData = workingData; + this.result = ResultCode.None; + this.startMergeLength = math.max(startMergeLength, 1e-09f); + this.endMergeLength = math.max(endMergeLength, 1e-09f); + this.maxStep = math.min(maxStep, 100); + this.dontMakeLine = dontMakeLine; + this.joinPositionAdjustment = joinPositionAdjustment; + } + + public virtual void Dispose() + { + if (joinEdgeList.IsCreated) + joinEdgeList.Dispose(); + if (completeVertexSet.IsCreated) + completeVertexSet.Dispose(); + if (removePairList.IsCreated) + removePairList.Dispose(); + if (resultArray.IsCreated) + resultArray.Dispose(); + } + + public ResultCode Result => result; + + //========================================================================================= + /// + /// リダクション実行(スレッド可) + /// + /// + public ResultCode Reduction() + { + //bool success = false; + result.Clear(); + + try + { + // ステップ前初期化 + StepInitialize(); + + // 開始範囲から終了範囲までを半径を拡大にしながら実行する + InitStep(); + while (nowStepIndex < maxStep) + { + // リダクションステップ実行 + ReductionStep(); + + nowStepIndex++; + if (IsEndStep()) + break; + NextStep(); + } + // 最後に追加で数回実行する(残り物処理) + if (nowStepIndex < maxStep) + { + // リダクションステップ実行 + ReductionStep(); + nowStepIndex++; + } + + //Debug.Log(nowStepIndex); + + // 頂点情報を整理する + // 法線単位化 + // ボーンウエイトを1に平均化 + UpdateReductionResultJob(); + + // 削除頂点数集計 + int removeVertexCount = 0; + for (int i = 0; i < nowStepIndex; i++) + { + removeVertexCount += resultArray[i]; + //Debug.Log($"[Step:{i + 1}] => {resultArray[i]}"); + } + workData.removeVertexCount += removeVertexCount; + + // 完了 + //success = true; + result.SetSuccess(); + } + catch (Exception exception) + { + Debug.LogError(exception); + if (result.IsError() == false) + { + if (this is SimpleDistanceReduction) + result.SetError(Define.Result.Reduction_SimpleDistanceException); + else if (this is ShapeDistanceReduction) + result.SetError(Define.Result.Reduction_ShapeDistanceException); + else + result.SetError(Define.Result.Reduction_Exception); + } + } + finally + { + // 作業バッファを解放する(重要) + // ★仮にタスクが例外やキャンセルされたとしてもこれで作成したバッファは正しくDispose()される + //MagicaManager.Discard.Add(); + + // 登録したジョブを解除する(重要) + // ★仮にタスクが例外やキャンセルされたとしてもこれで発行したJobは正しくComplete()される + //MagicaManager.Thread.DisposeJob(int); + } + + return result; + } + + void InitStep() + { + nowStepIndex = 0; + nowMergeLength = startMergeLength; + nowStepScale = 2.0f; + } + + bool IsEndStep() + { + return nowMergeLength == endMergeLength; + } + + void NextStep() + { + nowStepScale = math.max(nowStepScale * 0.93f, 1.1f); + nowMergeLength = math.min(nowMergeLength * nowStepScale, endMergeLength); + } + + /// + /// リダクションステップ処理 + /// + /// + /// + /// + /// + /// + void ReductionStep() + { + //Debug.Log($"nowMergeLength:{nowMergeLength}"); + + // ステップ前処理 + // 結合ペアリストのクリア + PreReductionStep(); + + // 結合ペアの追加 + CustomReductionStep(); + + // ステップ後処理 + // 結合ペアリストから頂点が被らないペアを摘出し結合を実行する + // 結合後に頂点の接続状態を最新に更新する + PostReductionStep(); + } + + //========================================================================================= + /// + /// ステップ処理前初期化 + /// この関数をオーバーライドし必要なステップ前初期化を追加する + /// + protected virtual void StepInitialize() + { + int vcnt = vmesh.VertexCount; + joinEdgeList = new NativeList(vcnt / 4, Allocator.Persistent); + completeVertexSet = new NativeParallelHashSet(vcnt, Allocator.Persistent); + removePairList = new NativeList(vcnt, Allocator.Persistent); + resultArray = new NativeArray(maxStep, Allocator.Persistent); + } + + /// + /// この関数をオーバーライドしjoinEdgeListに削除候補のペアを追加する処理を記述する + /// + /// + /// + protected virtual void CustomReductionStep() + { + } + + //========================================================================================= + /// + /// リダクションステップ前処理 + /// + /// + /// + void PreReductionStep() + { + // 作業用バッファクリア + joinEdgeList.Clear(); + } + + //========================================================================================= + /// + /// リダクションステップ後処理 + /// + /// + /// + void PostReductionStep() + { + // 結合候補をソートする + SortJoinEdge(); + + // 結合リストを作成する + DetermineJoinEdge(); + + // 結合を実行する + RunJoinEdge(); + + // 頂点の接続状態を最新に更新する。すべて最新の生存ポイントを指すように変更する + UpdateJoinAndLink(); + + //Debug.Log($"[{name}] Step:{nowStepIndex} mergeLength:{nowMergeLength} RemoveVertex:{resultArray[nowStepIndex]}"); + } + + //========================================================================================= + /// + /// 結合候補のペアリストをコストの昇順でソートするジョブを発行する + /// + /// + /// + void SortJoinEdge() + { + // コストの昇順でソートする + joinEdgeList.Sort(); + } + + //========================================================================================= + /// + /// 結合候補から距離順位に頂点が被らないように結合ペアを選択するジョブを発行する + /// 頂点が被らないのでこれらのペアは並列に結合処理を行っても問題なくなる + /// + /// + /// + void DetermineJoinEdge() + { + var reductionJob = new DeterminJoinEdgeJob() + { + stepIndex = nowStepIndex, + mergeLength = nowMergeLength, + joinEdgeList = joinEdgeList, + completeVertexSet = completeVertexSet, + removePairList = removePairList, + resultArray = resultArray, + }; + reductionJob.Run(); + //Debug.Log($"Step:{nowStepIndex} mergeLength:{nowMergeLength} RemoveVertex:{resultArray[nowStepIndex]}"); + } + + [BurstCompile] + struct DeterminJoinEdgeJob : IJob + { + public int stepIndex; + public float mergeLength; + + [Unity.Collections.ReadOnly] + public NativeList joinEdgeList; + + public NativeParallelHashSet completeVertexSet; + public NativeList removePairList; + public NativeArray resultArray; + + public void Execute() + { + // すでに結合された頂点セット + completeVertexSet.Clear(); + removePairList.Clear(); + + int cnt = 0; + for (int i = 0; i < joinEdgeList.Length; i++) + { + var joinEdge = joinEdgeList[i]; + var vertexPair = joinEdge.vertexPair; + + // 頂点がすでに結合されているならばスキップする + if (completeVertexSet.Contains(vertexPair.x) || completeVertexSet.Contains(vertexPair.y)) + continue; + + // このエッジを結合する + // 結合リストに追加する + removePairList.Add(vertexPair.xy); + + // 処理済みマップに追加 + completeVertexSet.Add(vertexPair.x); + completeVertexSet.Add(vertexPair.y); + + cnt++; + } + + // 削減頂点数を保存 + resultArray[stepIndex] = cnt; + + } + } + + //========================================================================================= + /// + /// 結合ペアを実際に結合するジョブを発行する + /// + /// + /// + void RunJoinEdge() + { + var organizeJoinEdgeJob = new JoinPairJob() + { + joinPositionAdjustment = joinPositionAdjustment, + removePairList = removePairList, + localPositions = vmesh.localPositions.GetNativeArray(), + localNormals = vmesh.localNormals.GetNativeArray(), + joinIndices = workData.vertexJoinIndices, + vertexToVertexMap = workData.vertexToVertexMap, + boneWeights = vmesh.boneWeights.GetNativeArray(), + attributes = vmesh.attributes.GetNativeArray(), + }; + organizeJoinEdgeJob.Run(); + } + + [BurstCompile] + struct JoinPairJob : IJob + { + public float joinPositionAdjustment; + + [Unity.Collections.ReadOnly] + public NativeList removePairList; + + public NativeArray localPositions; + public NativeArray localNormals; + public NativeParallelMultiHashMap vertexToVertexMap; + public NativeArray boneWeights; + public NativeArray attributes; + + public NativeArray joinIndices; + + public void Execute() + { + for (int index = 0; index < removePairList.Length; index++) + { + int2 pair = removePairList[index]; + + // pair.x -> pair.yに結合する + int vindex1 = pair.x; + int vindex2 = pair.y; + float3 pos1 = localPositions[vindex1]; + float3 pos2 = localPositions[vindex2]; + float3 nor1 = localNormals[vindex1]; + float3 nor2 = localNormals[vindex2]; + + // vertex2にvertex1を結合し、vertex1は削除としてマークする + // 結合(vertex1 -> vertex2) + joinIndices[vindex1] = vindex2; + + // vertex2の新しい座標 + // 各頂点の接続数に応じて結合位置のウエイトを変える(接続数が多いほど動かない) + float linkCnt1 = math.max(vertexToVertexMap.CountValuesForKey((ushort)vindex1) - 1, 1); // 接続トライアングルを想定して1を引く + float linkCnt2 = math.max(vertexToVertexMap.CountValuesForKey((ushort)vindex2) - 1, 1); // 接続トライアングルを想定して1を引く + float ratio = linkCnt2 / (linkCnt1 + linkCnt2); + + // 頂点接合位置のユーザー調整(1.0の場合は平均位置になる) + ratio = math.lerp(ratio, 0.5f, joinPositionAdjustment); + + // p2の座標を変更 + float3 newpos = math.lerp(pos2, pos1, ratio); + localPositions[vindex2] = newpos; + localNormals[vindex2] = (nor1 + nor2); + + // 接続数を結合する(重複は弾かれる) + var newLink = new FixedList512Bytes(); + foreach (ushort nindex in vertexToVertexMap.GetValuesForKey((ushort)vindex1)) + { + if (nindex != vindex1 && nindex != vindex2) + newLink.MC2Set(nindex); + } + foreach (ushort nindex in vertexToVertexMap.GetValuesForKey((ushort)vindex2)) + { + if (nindex != vindex1 && nindex != vindex2) + newLink.MC2Set(nindex); + } + vertexToVertexMap.Remove((ushort)vindex2); + for (int i = 0; i < newLink.Length; i++) + { + vertexToVertexMap.Add((ushort)vindex2, newLink[i]); + } + //Debug.Assert(newLink.Length > 0); + + // p2にBoneWeightを結合 + var bw = boneWeights[vindex2]; + bw.AddWeight(boneWeights[vindex1]); + boneWeights[vindex2] = bw; + + // 頂点属性 + var attr1 = attributes[vindex1]; + var attr2 = attributes[vindex2]; + attributes[vindex2] = VertexAttribute.JoinAttribute(attr1, attr2); + attributes[vindex1] = VertexAttribute.Invalid; // 削除頂点は無効にする + } + } + } + + //========================================================================================= + /// + /// 接続状態を最新に更新するジョブを発行する + /// + /// + /// + void UpdateJoinAndLink() + { + // JoinIndexの状態を更新する。現在の最新の生存ポイントを指すように変更する + var updateJoinIndexJob = new UpdateJoinIndexJob() + { + joinIndices = workData.vertexJoinIndices, + }; + updateJoinIndexJob.Run(vmesh.VertexCount); + + // 頂点の接続頂点リストを最新に更新する。すべて最新の生存ポイントを指すように変更する + var updateLinkIndexJob = new UpdateLinkIndexJob() + { + joinIndices = workData.vertexJoinIndices, + vertexToVertexMap = workData.vertexToVertexMap, + }; + updateLinkIndexJob.Run(vmesh.VertexCount); + } + + [BurstCompile] + struct UpdateJoinIndexJob : IJobParallelFor + { + [NativeDisableParallelForRestriction] + public NativeArray joinIndices; + + public void Execute(int vindex) + { + int join = joinIndices[vindex]; + if (join >= 0) + { + // 削除されている + // 最終的な生存ポイントに連結させる + while (joinIndices[join] >= 0) + { + join = joinIndices[join]; + } + joinIndices[vindex] = join; + } + } + } + + [BurstCompile] + struct UpdateLinkIndexJob : IJobParallelFor + { + [NativeDisableParallelForRestriction] + public NativeArray joinIndices; + + public NativeParallelMultiHashMap vertexToVertexMap; + + public void Execute(int vindex) + { + int join = joinIndices[vindex]; + + // 自身が削除されている場合は無視 + if (join >= 0) + return; + + // 自身が生存している + // 現在の接続インデックスから削除されたものを生存インデックスに入れ替える + var newLinkSet = new FixedList512Bytes(); + foreach (ushort i in vertexToVertexMap.GetValuesForKey((ushort)vindex)) + { + int tvindex = i; + int tjoin = joinIndices[tvindex]; + if (tjoin >= 0) + { + // 削除されている + tvindex = tjoin; + Debug.Assert(joinIndices[tvindex] < 0); + } + + // 自身は弾く + if (tvindex == vindex) + continue; + + newLinkSet.MC2Set((ushort)tvindex); + } + // 生存のみの新しいセットに入れ替え + vertexToVertexMap.Remove((ushort)vindex); + for (int i = 0; i < newLinkSet.Length; i++) + { + vertexToVertexMap.Add((ushort)vindex, newLinkSet[i]); + } + //Debug.Assert(newLinkSet.Length > 0); + } + } + + //========================================================================================= + /// + /// リダクション後のデータを整える + /// + void UpdateReductionResultJob() + { + // 頂点法線の単位化、およびボーンウエイトを1に整える + var finalVertexJob = new FinalMergeVertexJob() + { + joinIndices = workData.vertexJoinIndices, + localNormals = vmesh.localNormals.GetNativeArray(), + boneWeights = vmesh.boneWeights.GetNativeArray(), + }; + finalVertexJob.Run(vmesh.VertexCount); + } + + [BurstCompile] + struct FinalMergeVertexJob : IJobParallelFor + { + [Unity.Collections.ReadOnly] + public NativeArray joinIndices; + + public NativeArray localNormals; + public NativeArray boneWeights; + + public void Execute(int vindex) + { + int join = joinIndices[vindex]; + if (join >= 0) + { + // 削除されている + return; + } + + // 法線単位化 + localNormals[vindex] = math.normalize(localNormals[vindex]); + + // ボーンウエイトを平均化 + var bw = boneWeights[vindex]; + bw.AdjustWeight(); + boneWeights[vindex] = bw; + } + } + + //========================================================================================= + // Job Utility + //========================================================================================= + /// + /// 頂点を結合して問題がないか調べる + /// + /// + /// + /// + /// + /// + /// + /// + protected static bool CheckJoin2( + in NativeParallelMultiHashMap vertexToVertexMap, + int vindex, + int tvindex, + bool dontMakeLine + ) + { + // 結合後の接続リストを仮作成する + var joinVlink = new FixedList512Bytes(); + + foreach (ushort index in vertexToVertexMap.GetValuesForKey((ushort)vindex)) + { + if (index != vindex && index != tvindex) + joinVlink.MC2Set(index); + } + foreach (ushort index in vertexToVertexMap.GetValuesForKey((ushort)tvindex)) + { + if (index != vindex && index != tvindex) + joinVlink.MC2Set(index); + } + + // 点になるのはNG + // 結合後に接続が0になる場合はNG + if (joinVlink.Length == 0) + { + //Debug.LogWarning("joinVlink.Count = 0!"); + return false; + } + + // 可能な限りラインを作らない(オプション) + if (dontMakeLine) + { + // 結合後のトライアングルの外周をひと筆書きし、すべての外周頂点が使われているならOK! + // 外周頂点が一筆書きできない場合は2つ以上のグループに分かれいる(X型になる) + var stack = new FixedList512Bytes(); + stack.MC2Push(joinVlink[0]); + while (stack.Length > 0) + { + ushort index = stack.MC2Pop(); + if (joinVlink.Contains(index) == false) + continue; + joinVlink.MC2RemoveItemAtSwapBack(index); + + foreach (ushort nindex in vertexToVertexMap.GetValuesForKey((ushort)index)) + { + if (joinVlink.Contains(nindex)) + { + // next + stack.MC2Push(nindex); + } + } + } + if (joinVlink.Length > 0) + { + // 外周を一筆書きしたあとでもまだ頂点が残っている! + // これは頂点がX型になるのでNG! + return false; + } + } + + // 大丈夫 + return true; + } + + /// + /// 頂点を結合して問題がないか調べる + /// + /// + /// + /// + /// + /// + /// + /// + protected static bool CheckJoin( + in NativeArray> vertexToVertexArray, + int vindex, + int tvindex, + in FixedList128Bytes vlist, + in FixedList128Bytes tvlist, + bool dontMakeLine + ) + { + // 結合後の接続リストを仮作成する + var joinVlink = new FixedList128Bytes(); + for (int i = 0; i < vlist.Length; i++) + { + int index = vlist[i]; + if (index != vindex && index != tvindex) + joinVlink.MC2SetLimit((ushort)index); + } + for (int i = 0; i < tvlist.Length; i++) + { + int index = tvlist[i]; + if (index != vindex && index != tvindex) + joinVlink.MC2SetLimit((ushort)index); + } + + // 点になるのはNG + // 結合後に接続が0になる場合はNG + if (joinVlink.Length == 0) + { + //Debug.LogWarning("joinVlink.Count = 0!"); + return false; + } + + // 可能な限りラインを作らない(オプション) + if (dontMakeLine) + { + // 結合後のトライアングルの外周をひと筆書きし、すべての外周頂点が使われているならOK! + // 外周頂点が一筆書きできない場合は2つ以上のグループに分かれいる(X型になる) + var stack = new FixedList512Bytes(); + stack.MC2Push(joinVlink[0]); + while (stack.Length > 0) + { + ushort index = stack.MC2Pop(); + if (joinVlink.Contains(index) == false) + continue; + joinVlink.MC2RemoveItemAtSwapBack(index); + + var link = vertexToVertexArray[index]; + for (int i = 0; i < link.Length; i++) + { + ushort nindex = link[i]; + if (joinVlink.Contains(nindex)) + { + // next + stack.MC2Push(nindex); + } + } + } + if (joinVlink.Length > 0) + { + // 外周を一筆書きしたあとでもまだ頂点が残っている! + // これは頂点がX型になるのでNG! + return false; + } + } + + // 大丈夫 + return true; + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/Reduction/StepReductionBase.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Reduction/StepReductionBase.cs.meta new file mode 100644 index 00000000..5a322f53 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Reduction/StepReductionBase.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: facec8b9837c5ca4d8d05ccc7f1ca6a9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Reduction/StepReductionBase.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Settings.meta b/Assets/MagicaCloth2/Scripts/Core/Settings.meta new file mode 100644 index 00000000..d877e19a --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Settings.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: a4f9ed180f9a7b14093bd9e1104e33ea +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/MagicaCloth2/Scripts/Core/Settings/ClothDebugSettings.cs b/Assets/MagicaCloth2/Scripts/Core/Settings/ClothDebugSettings.cs new file mode 100644 index 00000000..c133b74b --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Settings/ClothDebugSettings.cs @@ -0,0 +1,120 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +#if MC2_DEBUG +using UnityEngine; +#endif + +namespace MagicaCloth2 +{ + /// + /// クロスのデバッグ表示設定 + /// + [System.Serializable] + public class ClothDebugSettings + { + public enum DebugAxis + { + None, + Normal, + All, + } + + //===================================================================== + // ■公開するもの + //===================================================================== + public bool enable = false; + public bool ztest = false; + public bool position = true; + public DebugAxis axis = DebugAxis.None; + public bool shape = false; + public bool baseLine = false; + public bool depth = false; + public bool collider = true; + public bool animatedPosition = false; + public DebugAxis animatedAxis = DebugAxis.None; + public bool animatedShape = false; + public bool inertiaCenter = true; + public bool customSkinningBone = true; + + //===================================================================== + // ■デバッグ用 + //===================================================================== +#if MC2_DEBUG + //[Space] + //[Header("[MC2_DEBUG]")] + [Header("<<< MC2_DEBUG >>>")] + [Range(0.003f, 0.1f)] + public float pointSize = 0.01f; + public bool referOldPos = false; + public bool radius = true; + public bool localNumber = false; + public bool particleNumber = false; + public bool triangleNumber = false; + public bool friction = false; + public bool staticFriction = false; + public bool attribute = false; + //public bool verticalDistanceConstraint = false; + //public bool horizontalDistanceConstraint = false; + public bool collisionNormal = false; + public bool cellCube = false; + public bool baseLinePos = false; + public int vertexMinIndex = 0; + public int vertexMaxIndex = 100000; + public int triangleMinIndex = 0; + public int triangleMaxIndex = 100000; +#endif + + //========================================================================================= + public bool CheckParticleDrawing(int index) + { +#if MC2_DEBUG + return index >= vertexMinIndex && index <= vertexMaxIndex; +#else + return true; +#endif + } + + public bool CheckTriangleDrawing(int index) + { +#if MC2_DEBUG + return index >= triangleMinIndex && index <= triangleMaxIndex; +#else + return true; +#endif + } + + public bool CheckRadiusDrawing() + { +#if MC2_DEBUG + return radius; +#else + return true; +#endif + } + + public float GetPointSize() + { +#if MC2_DEBUG + return pointSize; +#else + return 0.01f; +#endif + } + + public float GetLineSize() => 0.05f; // 固定 + + public float GetInertiaCenterRadius() => 0.01f; // 固定 + + public float GetCustomSkinningRadius() => 0.02f; // 固定 + + public bool IsReferOldPos() + { +#if MC2_DEBUG + return referOldPos; +#else + return false; +#endif + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/Settings/ClothDebugSettings.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Settings/ClothDebugSettings.cs.meta new file mode 100644 index 00000000..3bb27e71 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Settings/ClothDebugSettings.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 376c4b12fa90b6e429730e7ff5424c71 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Settings/ClothDebugSettings.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Settings/VirtualMeshDebugSettings.cs b/Assets/MagicaCloth2/Scripts/Core/Settings/VirtualMeshDebugSettings.cs new file mode 100644 index 00000000..9a6fcb04 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Settings/VirtualMeshDebugSettings.cs @@ -0,0 +1,54 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +#if MC2_DEBUG +using UnityEngine; +#endif + +namespace MagicaCloth2 +{ +#if MC2_DEBUG + /// + /// VirtualMeshのデバッグ表示設定 + /// + [System.Serializable] + public class VirtualMeshDebugSettings + { + public enum DebugAxis + { + None, + Normal, + All, + } + + [Header("<<< MC2_DEBUG >>>")] + public bool enable = false; + [Range(0.003f, 0.1f)] + public float pointSize = 0.01f; + [Range(0.003f, 0.1f)] + public float lineSize = 0.03f; + public bool position = true; + public bool axis = false; + public bool indexNumber = false; + public bool boneWeight = false; + public bool uv = false; + public bool depth = false; + public bool rootIndex = false; + public bool parentIndex = false; + public bool line = true; + public bool edgeNumber = false; + public bool triangle = true; + public bool triangleNormal = false; + public bool triangleTangent = false; + public bool triangleNumber = false; + public bool baseLine = false; + public bool boneName = false; + public int vertexMinIndex = 0; + public int vertexMaxIndex = 100000; + public int edgeMinIndex = 0; + public int edgeMaxIndex = 100000; + public int triangleMinIndex = 0; + public int triangleMaxIndex = 100000; + } +#endif // MC2_DEBUG +} diff --git a/Assets/MagicaCloth2/Scripts/Core/Settings/VirtualMeshDebugSettings.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Settings/VirtualMeshDebugSettings.cs.meta new file mode 100644 index 00000000..110f7fc3 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Settings/VirtualMeshDebugSettings.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 531c6af0cb86f0e40b49ae9f19e2f83d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Settings/VirtualMeshDebugSettings.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Utility.meta b/Assets/MagicaCloth2/Scripts/Core/Utility.meta new file mode 100644 index 00000000..dc76c6d4 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Utility.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 1751485edafdc6c41b324979e75d0a46 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/MagicaCloth2/Scripts/Core/Utility/Data.meta b/Assets/MagicaCloth2/Scripts/Core/Utility/Data.meta new file mode 100644 index 00000000..74a0f3c7 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Utility/Data.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 95fa82dc80bceb64688ab606c9212a14 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/MagicaCloth2/Scripts/Core/Utility/Data/DataUtility.cs b/Assets/MagicaCloth2/Scripts/Core/Utility/Data/DataUtility.cs new file mode 100644 index 00000000..20053116 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Utility/Data/DataUtility.cs @@ -0,0 +1,528 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using System; +using System.Runtime.CompilerServices; +using Unity.Mathematics; +using UnityEngine; + +namespace MagicaCloth2 +{ + public class DataUtility + { + /// + /// 2つのintをint2にパックする + /// データは昇順にソートされる + /// + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int2 PackInt2(int d0, int d1) + { + return d0 < d1 ? new int2(d0, d1) : new int2(d1, d0); + } + + /// + /// int2をデータの昇順にソートして格納し直す + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int2 PackInt2(in int2 d) => PackInt2(d.x, d.y); + + /// + /// 3つのintをint3にパックする + /// データは昇順にソートされる + /// + /// + /// + /// + /// + public static int3 PackInt3(int d0, int d1, int d2) + { + if (d0 < d1 && d0 < d2) + { + // d0,x,x + if (d1 < d2) + return new int3(d0, d1, d2); + else + return new int3(d0, d2, d1); + } + if (d1 < d2) + { + // d1,x,x + if (d0 < d2) + return new int3(d1, d0, d2); + else + return new int3(d1, d2, d0); + } + else + { + // d2,x,x + if (d0 < d1) + return new int3(d2, d0, d1); + else + return new int3(d2, d1, d0); + } + } + + public static int3 PackInt3(in int3 d) => PackInt3(d.x, d.y, d.z); + + /// + /// 4つのintをint4にパックする + /// データは昇順にソートされる + /// + /// + /// + /// + /// + /// + public static int4 PackInt4(int d0, int d1, int d2, int d3) + { + int w; + + // step1 + if (d0 > d3) + { + w = d0; + d0 = d3; + d3 = w; + } + if (d1 > d2) + { + w = d1; + d1 = d2; + d2 = w; + } + + // step2 + if (d0 > d1) + { + w = d0; + d0 = d1; + d1 = w; + } + if (d2 > d3) + { + w = d2; + d2 = d3; + d3 = w; + } + + // step3 + if (d1 > d2) + { + w = d1; + d1 = d2; + d2 = w; + } + + return new int4(d0, d1, d2, d3); + } + + public static int4 PackInt4(int4 d) => PackInt4(d.x, d.y, d.z, d.w); + + + /// + /// 2つのintをushortに変換し1つのuintにパッキングする + /// + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static uint Pack32(int hi, int low) + { + return (uint)hi << 16 | (uint)low & 0xffff; + } + + /// + /// 2つのintをushortに変換し1つのuintにパッキングする + /// データの小さいほうが上位に格納されるようにソートされる + /// + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static uint Pack32Sort(int a, int b) + { + if (a > b) + { + return (uint)b << 16 | (uint)a & 0xffff; + } + else + { + return (uint)a << 16 | (uint)b & 0xffff; + } + } + + /// + /// uintパックデータから上位16bitをintにして返す + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int Unpack32Hi(uint pack) + { + return (int)((pack >> 16) & 0xffff); + } + + /// + /// uintパックデータから下位16bitをintにして返す + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int Unpack32Low(uint pack) + { + return (int)(pack & 0xffff); + } + +#if false + /// + /// 2つのintをhi(10bit)とlow(22bit)に切り詰めて1つのuintにパッキングする + /// + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static uint Pack10_22(int hi, int low) + { + return (uint)hi << 22 | (uint)low & 0x3fffff; + } + + /// + /// uint10-22パックデータから上位10bitデータをintにして返す + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int Unpack10_22Hi(uint pack) + { + return (int)((pack >> 22) & 0x3ff); + } + + /// + /// uint10-22パックデータから下位22bitデータをintにして返す + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int Unpack10_22Low(uint pack) + { + return (int)(pack & 0x3fffff); + } + + /// + /// uint10-22パックデータを分解して2つのintとして返す + /// + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void Unpack10_22(uint pack, out int hi, out int low) + { + hi = (int)((pack >> 22) & 0x3ff); + low = (int)(pack & 0x3fffff); + } +#endif + + /// + /// 2つのintをhi(12bit)とlow(20bit)に切り詰めて1つのuintにパッキングする + /// + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static uint Pack12_20(int hi, int low) + { + return (uint)hi << 20 | (uint)low & 0xfffff; + } + + /// + /// uint12-20パックデータから上位12bitデータをintにして返す + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int Unpack12_20Hi(uint pack) + { + return (int)((pack >> 20) & 0xfff); + } + + /// + /// uint12-20パックデータから下位20bitデータをintにして返す + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int Unpack12_20Low(uint pack) + { + return (int)(pack & 0xfffff); + } + + /// + /// uint12-20パックデータを分解して2つのintとして返す + /// + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void Unpack12_20(uint pack, out int hi, out int low) + { + hi = (int)((pack >> 20) & 0xfff); + low = (int)(pack & 0xfffff); + } + + /// + /// 4つのintをushortに変換し1つのulongにパッキングする + /// + /// + /// + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ulong Pack64(int x, int y, int z, int w) + { + return (((ulong)x) & 0xffff) << 48 | (((ulong)y) & 0xffff) << 32 | (((ulong)z) & 0xffff) << 16 | ((ulong)w) & 0xffff; + } + + /// + /// int4をushortに変換し1つのulongにパッキングする + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ulong Pack64(in int4 a) + { + return Pack64(a.x, a.y, a.z, a.w); + } + + /// + /// ulongパックデータからint4に展開して返す + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int4 Unpack64(in ulong pack) + { + return new int4( + (int)((pack >> 48) & 0xffff), + (int)((pack >> 32) & 0xffff), + (int)((pack >> 16) & 0xffff), + (int)(pack & 0xffff) + ); + } + + /// + /// ulongパックデータからx値を取り出す + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int Unpack64X(in ulong pack) + { + return (int)((pack >> 48) & 0xffff); + } + + /// + /// ulongパックデータからy値を取り出す + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int Unpack64Y(in ulong pack) + { + return (int)((pack >> 32) & 0xffff); + } + + /// + /// ulongパックデータからz値を取り出す + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int Unpack64Z(in ulong pack) + { + return (int)((pack >> 16) & 0xffff); + } + + /// + /// ulongパックデータからw値を取り出す + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int Unpack64W(in ulong pack) + { + return (int)(pack & 0xffff); + } + + /// + /// 4つのintをbyteに変換し1つのuintにパッキングする + /// + /// + /// + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static uint Pack32(int x, int y, int z, int w) + { + return (((uint)x) & 0xff) << 24 | (((uint)y) & 0xff) << 16 | (((uint)z) & 0xff) << 8 | ((uint)w) & 0xff; + } + + /// + /// int4をbyteに変換し1つのuintにパッキングする + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ulong Pack32(in int4 a) + { + return Pack64(a.x, a.y, a.z, a.w); + } + + /// + /// uintパックデータからint4に展開して返す + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int4 Unpack32(in uint pack) + { + return new int4( + (int)((pack >> 24) & 0xff), + (int)((pack >> 16) & 0xff), + (int)((pack >> 8) & 0xff), + (int)(pack & 0xff) + ); + } + + /// + /// int3のうちuse(int2)で使われていない残りの1つのデータを返す + /// + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int RemainingData(in int3 data, in int2 use) + { + if (data.x != use.x && data.x != use.y) + return data.x; + if (data.y != use.x && data.y != use.y) + return data.y; + return data.z; + } + + //========================================================================================= + /// + /// AnimationCurveを16個のfloatのリスト(float4x4)に変換する + /// + /// + /// + public static float4x4 ConvertAnimationCurve(AnimationCurve curve) + { + float4x4 m = 0; + for (int i = 0; i < 16; i++) + { + float time = i / 15.0f; + float val = curve.Evaluate(time); + m.MC2SetValue(i, val); + } + + return m; + } + + /// + /// AnimationCurveが格納されたfloat4x4からデータを取得する + /// + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float EvaluateCurve(in float4x4 curve, float time) + { + const float interval = 1.0f / 15.0f; + int index = (int)(math.saturate(time) * 15); + time -= index * interval; + float t = time / interval; + return math.lerp(curve.MC2GetValue(index), curve.MC2GetValue(index + 1), t); + } + + //========================================================================================= + /// + /// 16bitフラグにコライダータイプを設定する + /// + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ExBitFlag16 SetColliderType(ExBitFlag16 flag, ColliderManager.ColliderType ctype) + { + flag.Value = (ushort)((flag.Value & 0xfff0) | (ushort)ctype); + return flag; + } + + /// + /// 16bitフラグからコライダータイプを取得する + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ColliderManager.ColliderType GetColliderType(in ExBitFlag16 flag) + { + return (ColliderManager.ColliderType)(flag.Value & 0x000f); + } + + /// + /// 16bitフラグにシンメトリータイプを設定する + /// + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ExBitFlag16 SetSymmetryType(ExBitFlag16 flag, ColliderManager.SymmetryType stype) + { + flag.Value = (ushort)((flag.Value & 0xff0f) | (((ushort)stype) << 4)); + return flag; + } + + /// + /// 16bitフラグからシンメトリータイプを取得する + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ColliderManager.SymmetryType GetSymmetryType(in ExBitFlag16 flag) + { + return (ColliderManager.SymmetryType)((flag.Value & 0x00f0) >> 4); + } + + //========================================================================================= + /// + /// 配列をDeepコピーする + /// + /// + /// + /// + public static void ArrayCopy(T[] src, ref T[] dst) + { + if (src == null) + { + dst = null; + return; + } + if (src.Length == 0) + { + dst = new T[0]; + } + else + { + dst = new T[src.Length]; + Array.Copy(src, dst, src.Length); + } + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/Utility/Data/DataUtility.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Utility/Data/DataUtility.cs.meta new file mode 100644 index 00000000..5c22d260 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Utility/Data/DataUtility.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 5749112885888a44fa11de392614144a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Utility/Data/DataUtility.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Utility/Data/MagicaObjectId.cs b/Assets/MagicaCloth2/Scripts/Core/Utility/Data/MagicaObjectId.cs new file mode 100644 index 00000000..8e9ab68a --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Utility/Data/MagicaObjectId.cs @@ -0,0 +1,98 @@ +// Magica Cloth 2. +// Copyright (c) 2026 MagicaSoft. +// https://magicasoft.jp +using System; +using UnityEngine; + +namespace MagicaCloth2 +{ + /// + /// Unityのバージョン差異(InstanceID vs EntityId)を吸収するID構造体。 + /// 現在はUnity6.4以上でEntityIdに切り替え + /// + public readonly struct MagicaObjectId : IEquatable + { + // ------------------------------------------------------- + // 内部データ保持 + // ------------------------------------------------------- +#if UNITY_6000_4_OR_NEWER + private readonly EntityId _value; + + public MagicaObjectId(EntityId id) + { + _value = id; + } + + // 無効なIDの定義(EntityIdの仕様に合わせる) + public static readonly MagicaObjectId Invalid = new(EntityId.None); + + public bool IsValid() => _value.IsValid(); + +#else + private readonly int _value; + + public MagicaObjectId(int id) + { + _value = id; + } + + // 従来のInstanceIDでは0が事実上の無効値として扱われることが多い + public static readonly MagicaObjectId Invalid = new MagicaObjectId(0); + + public bool IsValid() => _value != 0; +#endif + + public bool Equals(MagicaObjectId other) + { + return _value.Equals(other._value); + } + + public override bool Equals(object obj) + { + return obj is MagicaObjectId other && Equals(other); + } + + public override int GetHashCode() + { + return _value.GetHashCode(); + } + + public static bool operator ==(MagicaObjectId left, MagicaObjectId right) + { + return left.Equals(right); + } + + public static bool operator !=(MagicaObjectId left, MagicaObjectId right) + { + return !left.Equals(right); + } + + // これはデバッグ用途以外では使わない + public override string ToString() + { + return _value.ToString(); + } + } + + // ------------------------------------------------------- + // 拡張メソッド + // ------------------------------------------------------- + public static class MagicaObjectIdExtensions + { + /// + /// GameObjectやComponentからバージョンに合わせたIDを取得する + /// + public static MagicaObjectId GetMagicaId(this UnityEngine.Object obj) + { + if (obj == null) return MagicaObjectId.Invalid; + +#if UNITY_6000_4_OR_NEWER + // Unity 6.4 API + return new MagicaObjectId(obj.GetEntityId()); +#else + // 従来の API + return new MagicaObjectId(obj.GetInstanceID()); +#endif + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/Utility/Data/MagicaObjectId.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Utility/Data/MagicaObjectId.cs.meta new file mode 100644 index 00000000..be415d5b --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Utility/Data/MagicaObjectId.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 527929c5c74a0224b91228de398467f3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Utility/Data/MagicaObjectId.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Utility/Data/MultiDataBuilder.cs b/Assets/MagicaCloth2/Scripts/Core/Utility/Data/MultiDataBuilder.cs new file mode 100644 index 00000000..0f3c79ee --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Utility/Data/MultiDataBuilder.cs @@ -0,0 +1,133 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using System; +using System.Collections.Generic; +using Unity.Collections; + +namespace MagicaCloth2 +{ + /// + /// T型のデータリストを構築し要素ごとにそのスタートインデックスとデータカウンタを生成する + /// 出力はT型のデータ配列と、要素ごとのスタートインデックスとカウンタが1つのuintにパックされた配列の2つ + /// + /// + public class MultiDataBuilder : IDisposable where T : unmanaged + { + int indexCount; + + public NativeParallelMultiHashMap Map; + + //========================================================================================= + public MultiDataBuilder(int indexCount, int dataCapacity) + { + this.indexCount = indexCount; + Map = new NativeParallelMultiHashMap(dataCapacity, Allocator.Persistent); + } + + + public void Dispose() + { + if (Map.IsCreated) + Map.Dispose(); + } + + public int Count() => Map.Count(); + + public int GetDataCount(int index) + { + if (Map.ContainsKey(index) == false) + return 0; + + return Map.CountValuesForKey(index); + } + + public void Add(int key, T data) + { + Map.Add(key, data); + } + + //public int AddAndReturnIndex(int key, T data) + //{ + // int cnt = Map.CountValuesForKey(key); + // Map.Add(key, data); + // return cnt; + //} + + public int CountValuesForKey(int key) + { + return Map.CountValuesForKey(key); + } + + //========================================================================================= + /// + /// 内部HashMapのデータをT型配列と要素ごとのスタートインデックスとカウンタ配列の2つに分離して返す + /// 出力はT型のデータ配列と、要素ごとのスタートインデックス(20bit)とカウンタ(12bit)を1つのuintにパックした配列となる + /// + /// + public (T[], uint[]) ToArray() + { + if (Map.IsCreated == false || indexCount == 0) + return (null, null); + + var indexArray = new uint[indexCount]; + var dataList = new List(Map.Capacity); + + for (int i = 0; i < indexCount; i++) + { + int start = dataList.Count; + int cnt = 0; + + if (Map.ContainsKey(i)) + { + foreach (var data in Map.GetValuesForKey(i)) + { + dataList.Add(data); + cnt++; + } + } + + indexArray[i] = DataUtility.Pack12_20(cnt, start); + } + + return (dataList.ToArray(), indexArray); + } + + public uint[] ToIndexArray() + { + (var _, uint[] indexArray) = ToArray(); + return indexArray; + } + + /// + /// 内部HashMapのデータをT型配列と要素ごとのスタートインデックス+カウンタの2つのNativeArrayに分離して返す + /// 出力はT型のデータ配列と、要素ごとのスタートインデックス(20bit)とカウンタ(12bit)を1つのuintにパックした配列となる + /// + /// + /// + public void ToNativeArray(out NativeArray indexArray, out NativeArray dataArray) + { + indexArray = new NativeArray(indexCount, Allocator.Persistent); + var dataList = new List(Map.Capacity); + + for (int i = 0; i < indexCount; i++) + { + int start = dataList.Count; + int cnt = 0; + + if (Map.ContainsKey(i)) + { + foreach (var data in Map.GetValuesForKey(i)) + { + dataList.Add(data); + cnt++; + } + } + + indexArray[i] = DataUtility.Pack12_20(cnt, start); + } + + dataArray = new NativeArray(dataList.ToArray(), Allocator.Persistent); + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/Utility/Data/MultiDataBuilder.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Utility/Data/MultiDataBuilder.cs.meta new file mode 100644 index 00000000..2a25722e --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Utility/Data/MultiDataBuilder.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 437001a616042194796b2fa354bebbb3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Utility/Data/MultiDataBuilder.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Utility/Grid.meta b/Assets/MagicaCloth2/Scripts/Core/Utility/Grid.meta new file mode 100644 index 00000000..c9e7fc4b --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Utility/Grid.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: a4a34e42bc2ef104fb3237f69dbdd2f0 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/MagicaCloth2/Scripts/Core/Utility/Grid/GridMap.cs b/Assets/MagicaCloth2/Scripts/Core/Utility/Grid/GridMap.cs new file mode 100644 index 00000000..08cceaee --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Utility/Grid/GridMap.cs @@ -0,0 +1,233 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using System; +using System.Collections; +using System.Collections.Generic; +using System.Runtime.CompilerServices; +using Unity.Collections; +using Unity.Mathematics; + +namespace MagicaCloth2 +{ + /// + /// グリッドマップとユーティリティ関数群 + /// Jobで利用するために最低限の管理データのみ + /// そのためGridSizeなどのデータはこのクラスでは保持しない + /// GridSize>0である必要あり! + /// + /// + public class GridMap : IDisposable where T : unmanaged // , IEquatable + { + private NativeParallelMultiHashMap gridMap; + + //========================================================================================= + public GridMap(int capacity = 0) + { + gridMap = new NativeParallelMultiHashMap(capacity, Allocator.Persistent); + } + + public void Dispose() + { + if (gridMap.IsCreated) + gridMap.Dispose(); + } + + public NativeParallelMultiHashMap GetMultiHashMap() => gridMap; + + public int DataCount => gridMap.Count(); + + //========================================================================================= + /// + /// グリッド範囲を走査するEnumeratorを返す + /// + /// + /// + /// + public static GridEnumerator GetArea(int3 startGrid, int3 endGrid, NativeParallelMultiHashMap gridMap) + { + return new GridEnumerator + { + gridMap = gridMap, + startGrid = math.min(startGrid, endGrid), + endGrid = math.max(startGrid, endGrid), + currentGrid = math.min(startGrid, endGrid), + isFirst = true, + }; + } + + /// + /// 球範囲を走査するEnumeratorを返す + /// + /// + /// + /// + public static GridEnumerator GetArea(float3 pos, float radius, NativeParallelMultiHashMap gridMap, float gridSize) + { + // 検索グリッド範囲 + int3 minGrid = GetGrid(pos - radius, gridSize); + int3 maxGrid = GetGrid(pos + radius, gridSize); + + return GetArea(minGrid, maxGrid, gridMap); + } + + /// + /// グリッド走査用Enumerator + /// + public struct GridEnumerator : IEnumerator + { + internal NativeParallelMultiHashMap gridMap; + internal int3 startGrid; + internal int3 endGrid; + internal int3 currentGrid; + internal bool isFirst; + + public int3 Current => currentGrid; + + object IEnumerator.Current => Current; + + public void Dispose() + { + } + + public bool MoveNext() + { + // データが存在しなくとも走査する + if (isFirst) + { + isFirst = false; + return true; + } + 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) + { + return false; + } + } + } + return true; + } + + public void Reset() + { + currentGrid = startGrid; + isFirst = true; + } + + public GridEnumerator GetEnumerator() { return this; } + } + + + //========================================================================================= + /// + /// 座標から3次元グリッド座標を割り出す + /// + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int3 GetGrid(float3 pos, float gridSize) + { + Develop.Assert(gridSize > 0); + return new int3(math.floor(pos / gridSize)); + } + + /// + /// グリッドマップにデータを追加する + /// + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void AddGrid(int3 grid, T data, NativeParallelMultiHashMap gridMap) + { + gridMap.Add(grid, data); + } + + /// + /// 座標からグリッドマップにデータを追加する + /// + /// + /// + /// + /// + /// + /// 追加されたグリッドを返す + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int3 AddGrid(float3 pos, T data, NativeParallelMultiHashMap gridMap, float gridSize) + { + int3 grid = GetGrid(pos, gridSize); + gridMap.Add(grid, data); + return grid; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int3 AddGrid(float3 pos, T data, NativeParallelMultiHashMap.ParallelWriter gridMap, float gridSize) + { + int3 grid = GetGrid(pos, gridSize); + gridMap.Add(grid, data); + return grid; + } + + /// + /// グリッドマップからデータを削除する + /// + /// + /// + /// + /// 削除に成功した場合はtrue + public static bool RemoveGrid(int3 grid, T data, NativeParallelMultiHashMap gridMap) + { + if (gridMap.ContainsKey(grid)) + { + NativeParallelMultiHashMapIterator it; + T item; + if (gridMap.TryGetFirstValue(grid, out item, out it)) + { + do + { + if (item.Equals(data)) + { + gridMap.Remove(it); + return true; + } + } + while (gridMap.TryGetNextValue(out item, ref it)); + } + } + + return false; + } + + /// + /// グリッドマップからデータを移動させる + /// + /// + /// + /// + /// + /// データが移動された場合true, 移動の必要がない場合はfalse + public static bool MoveGrid(int3 fromGrid, int3 toGrid, T data, NativeParallelMultiHashMap gridMap) + { + // 移動の必要がなければ終了 + if (fromGrid.Equals(toGrid)) + return false; + + // remove + RemoveGrid(fromGrid, data, gridMap); + + // add + AddGrid(toGrid, data, gridMap); + + return true; + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/Utility/Grid/GridMap.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Utility/Grid/GridMap.cs.meta new file mode 100644 index 00000000..d4b86f90 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Utility/Grid/GridMap.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: f11ea30bdf2932444ae39633749006cb +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Utility/Grid/GridMap.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Utility/Jobs.meta b/Assets/MagicaCloth2/Scripts/Core/Utility/Jobs.meta new file mode 100644 index 00000000..359252c7 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Utility/Jobs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: a2f52f64422b8ad49ae673c135e28e9e +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/MagicaCloth2/Scripts/Core/Utility/Jobs/InterlockUtility.cs b/Assets/MagicaCloth2/Scripts/Core/Utility/Jobs/InterlockUtility.cs new file mode 100644 index 00000000..cec2405e --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Utility/Jobs/InterlockUtility.cs @@ -0,0 +1,114 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using System.Runtime.CompilerServices; +using System.Threading; +using Unity.Mathematics; + +namespace MagicaCloth2 +{ + /// + /// Nativeバッファへのインターロック書き込み制御関連 + /// + public static class InterlockUtility + { + /// + /// 固定小数点への変換倍率 + /// + internal const int ToFixed = 1000000; + + /// + /// 少数への復元倍率 + /// + internal const float ToFloat = 0.000001f; + + //========================================================================================= + /// + /// 集計バッファの指定インデックスにfloat3を固定小数点として加算しカウンタをインクリメントする + /// + /// + /// + /// + /// + unsafe internal static void AddFloat3(int index, float3 add, int* cntPt, int* sumPt) + { + Interlocked.Increment(ref cntPt[index]); + int3 iadd = (int3)(add * ToFixed); + //Debug.Log($"InterlockAdd [{index}]:{iadd}"); + index *= 3; + for (int i = 0; i < 3; i++, index++) + { + if (iadd[i] != 0) + Interlocked.Add(ref sumPt[index], iadd[i]); + } + } + + /// + /// 集計バッファの指定インデックスにfloat3を固定小数点として加算する(カウントは操作しない) + /// + /// + /// + /// + unsafe internal static void AddFloat3(int index, float3 add, int* sumPt) + { + int3 iadd = (int3)(add * ToFixed); + index *= 3; + for (int i = 0; i < 3; i++, index++) + { + if (iadd[i] != 0) + Interlocked.Add(ref sumPt[index], iadd[i]); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + unsafe internal static void Max(int index, float value, int* pt) + { + int ival = (int)value * ToFixed; + int now = pt[index]; + int oldNow = now + 1; + + while (ival > now && now != oldNow) + { + oldNow = now; + now = Interlocked.CompareExchange(ref pt[index], ival, now); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + unsafe internal static float3 ReadAverageFloat3(int index, int* cntPt, int* sumPt) + { + int count = cntPt[index]; + if (count == 0) + return 0; + + int dataIndex = index * 3; + + // 集計 + float3 add = new float3(sumPt[dataIndex], sumPt[dataIndex + 1], sumPt[dataIndex + 2]); + add /= count; + + // データは固定小数点なので戻す + add *= ToFloat; + + return add; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + unsafe internal static float3 ReadFloat3(int index, int* vecPt) + { + int dataIndex = index * 3; + float3 v = new float3(vecPt[dataIndex], vecPt[dataIndex + 1], vecPt[dataIndex + 2]); + + // データは固定小数点なので戻す + v *= ToFloat; + + return v; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + unsafe internal static float ReadFloat(int index, int* floatPt) + { + return floatPt[index] * ToFloat; + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/Utility/Jobs/InterlockUtility.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Utility/Jobs/InterlockUtility.cs.meta new file mode 100644 index 00000000..3f7d76f9 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Utility/Jobs/InterlockUtility.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: a2fbf5e2678edef418b3d95dd46af37b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Utility/Jobs/InterlockUtility.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Utility/Jobs/JobUtility.cs b/Assets/MagicaCloth2/Scripts/Core/Utility/Jobs/JobUtility.cs new file mode 100644 index 00000000..68c7ee4b --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Utility/Jobs/JobUtility.cs @@ -0,0 +1,717 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using System; +using Unity.Burst; +using Unity.Collections; +using Unity.Jobs; +using Unity.Mathematics; +using UnityEngine; + +namespace MagicaCloth2 +{ + public static class JobUtility + { + //========================================================================================= + /// + /// 配列をValueで埋めるジョブを発行します + /// ジェネリック型ジョブは明示的に型をで指定する必要があるため型ごとに関数が発生します + /// + /// + /// + /// + /// + /// + /// + public static JobHandle Fill(NativeArray array, int length, int value, JobHandle dependsOn = new JobHandle()) + { + var job = new FillJob() { value = value, array = array, }; + return job.Schedule(length, 32, dependsOn); + } + + public static JobHandle Fill(NativeArray array, int length, Vector4 value, JobHandle dependsOn = new JobHandle()) + { + var job = new FillJob() { value = value, array = array, }; + return job.Schedule(length, 32, dependsOn); + } + + public static JobHandle Fill(NativeArray array, int length, VirtualMeshBoneWeight value, JobHandle dependsOn = new JobHandle()) + { + var job = new FillJob() { value = value, array = array, }; + return job.Schedule(length, 32, dependsOn); + } + + public static JobHandle Fill(NativeArray array, int length, byte value, JobHandle dependsOn = new JobHandle()) + { + var job = new FillJob() { value = value, array = array, }; + return job.Schedule(length, 32, dependsOn); + } + + public static void FillRun(NativeArray array, int length, int value) + { + var job = new FillJob() { value = value, array = array, }; + job.Run(length); + } + + public static void FillRun(NativeArray array, int length, Vector4 value) + { + var job = new FillJob() { value = value, array = array, }; + job.Run(length); + } + + public static void FillRun(NativeArray array, int length, quaternion value) + { + var job = new FillJob() { value = value, array = array, }; + job.Run(length); + } + + public static void FillRun(NativeArray array, int length, VirtualMeshBoneWeight value) + { + var job = new FillJob() { value = value, array = array, }; + job.Run(length); + } + + + [BurstCompile] + struct FillJob : IJobParallelFor where T : unmanaged + { + public T value; + + [Unity.Collections.WriteOnly] + public NativeArray array; + + public void Execute(int index) + { + array[index] = value; + } + } + + /// + /// 配列をValueで埋めるジョブを発行します(startIndexあり) + /// ジェネリック型ジョブは明示的に型をで指定する必要があるため型ごとに関数が発生します + /// + /// + /// + /// + /// + /// + /// + /// + public static JobHandle Fill(NativeArray array, int startIndex, int length, int value, JobHandle dependsOn = new JobHandle()) + { + var job = new FillJob2() { value = value, startIndex = startIndex, array = array, }; + return job.Schedule(length, 32, dependsOn); + } + + [BurstCompile] + struct FillJob2 : IJobParallelFor where T : unmanaged + { + public T value; + public int startIndex; + + [NativeDisableParallelForRestriction] + [Unity.Collections.WriteOnly] + public NativeArray array; + + public void Execute(int index) + { + array[startIndex + index] = value; + } + } + + public static JobHandle Fill(NativeReference reference, int value, JobHandle dependsOn = new JobHandle()) + { + var job = new FillRefJob() { value = value, reference = reference, }; + return job.Schedule(dependsOn); + } + + [BurstCompile] + struct FillRefJob : IJob where T : unmanaged + { + public T value; + + [Unity.Collections.WriteOnly] + public NativeReference reference; + + public void Execute() + { + reference.Value = value; + } + } + + //========================================================================================= + /// + /// 配列に連番を格納するジョブを発行します + /// + /// + /// + /// + /// + public static JobHandle SerialNumber(NativeArray array, int length, JobHandle dependsOn = new JobHandle()) + { + var job = new SerialNumberJob() + { + array = array, + }; + return job.Schedule(length, 32, dependsOn); + } + + public static void SerialNumberRun(NativeArray array, int length) + { + var job = new SerialNumberJob() + { + array = array, + }; + job.Run(length); + + } + + [BurstCompile] + struct SerialNumberJob : IJobParallelFor + { + [Unity.Collections.WriteOnly] + public NativeArray array; + + public void Execute(int index) + { + array[index] = index; + } + } + + //========================================================================================= + /// + /// NativeHashSetのキーをNativeListに変換するジョブを発行します + /// ジェネリック型ジョブは明示的に型をで指定する必要があるため型ごとに関数が発生します + /// + /// + /// + /// + /// + /// + public static JobHandle ConvertHashSetToNativeList(NativeParallelHashSet hashSet, NativeList list, JobHandle dependsOn = new JobHandle()) + { + var job = new ConvertHashSetToListJob() { hashSet = hashSet, list = list, }; + return job.Schedule(dependsOn); + } + + [BurstCompile] + struct ConvertHashSetToListJob : IJob where T : unmanaged, IEquatable + { + [Unity.Collections.ReadOnly] + public NativeParallelHashSet hashSet; + [Unity.Collections.WriteOnly] + public NativeList list; + + public void Execute() + { + foreach (var key in hashSet) + { + list.AddNoResize(key); + } + } + } + + //========================================================================================= +#if false + /// + /// NativeMultiHashMapのキーをNativeListに変換するジョブを発行する + /// ジェネリック型ジョブは明示的に型をで指定する必要があるため型ごとに関数が発生します + /// + /// + /// + /// + /// + /// + /// + public static JobHandle ConvertMultiHashMapKeyToNativeList( + NativeParallelMultiHashMap hashMap, + NativeList keyList, + JobHandle dependsOn = new JobHandle()) + { + // todo:この処理は重い + var job = new ConvertMultiHashMapKeyToListJob() + { + hashMap = hashMap, + list = keyList, + }; + return job.Schedule(dependsOn); + } + + [BurstCompile] + struct ConvertMultiHashMapKeyToListJob : IJob where T : unmanaged, IEquatable where U : unmanaged + { + [Unity.Collections.ReadOnly] + public NativeParallelMultiHashMap hashMap; + [Unity.Collections.WriteOnly] + public NativeList list; + + public void Execute() + { + var keySet = new NativeParallelHashSet(hashMap.Count(), Allocator.Temp); // ここが問題となる可能性がある(unity2023.1.5事件) + var keyArray = hashMap.GetKeyArray(Allocator.Temp); // ここが問題となる可能性がある(unity2023.1.5事件) + // GetKeyArray()の結果はキーが重複しまた順不同なので注意! + for (int i = 0; i < keyArray.Length; i++) + keySet.Add(keyArray[i]); + + foreach (var key in keySet) + list.Add(key); + } + } +#endif + + //========================================================================================= + /// + /// NativeHashSetの内容をNativeListに変換するジョブを発行する + /// ジェネリック型ジョブは明示的に型をで指定する必要があるため型ごとに関数が発生します + /// + /// + /// + /// + /// + public static JobHandle ConvertHashSetKeyToNativeList( + NativeParallelHashSet hashSet, + NativeList keyList, + JobHandle dependsOn = new JobHandle()) + { + var job = new ConvertHashSetKeyToListJob() { hashSet = hashSet, list = keyList, }; + return job.Schedule(dependsOn); + } + + public static JobHandle ConvertHashSetKeyToNativeList( + NativeParallelHashSet hashSet, + NativeList keyList, + JobHandle dependsOn = new JobHandle()) + { + var job = new ConvertHashSetKeyToListJob() { hashSet = hashSet, list = keyList, }; + return job.Schedule(dependsOn); + } + + [BurstCompile] + struct ConvertHashSetKeyToListJob : IJob where T : unmanaged, IEquatable + { + [Unity.Collections.ReadOnly] + public NativeParallelHashSet hashSet; + [Unity.Collections.WriteOnly] + public NativeList list; + + public void Execute() + { + // 順不同なので注意! + foreach (var key in hashSet) + list.Add(key); + } + } + + //========================================================================================= + /// + /// AABBを計算して返すジョブを発行する(NativeArray) + /// + /// + /// + /// + /// + /// + public static JobHandle CalcAABB(NativeArray positions, int length, NativeReference outAABB, JobHandle dependsOn = new JobHandle()) + { + var job = new CalcAABBJob() + { + length = length, + positions = positions, + outAABB = outAABB, + }; + return job.Schedule(dependsOn); + } + + public static void CalcAABBRun(NativeArray positions, int length, NativeReference outAABB) + { + var job = new CalcAABBJob() + { + length = length, + positions = positions, + outAABB = outAABB, + }; + job.Run(); + } + + /// + /// AABBを計算して返すジョブを発行する(NativeList) + /// + /// + /// + /// + /// + public static JobHandle CalcAABB(NativeList positions, NativeReference outAABB, JobHandle dependsOn = new JobHandle()) + { + var job = new CalcAABBDeferJob() + { + positions = positions, + outAABB = outAABB, + }; + return job.Schedule(dependsOn); + } + + public static void CalcAABBRun(NativeList positions, NativeReference outAABB) + { + var job = new CalcAABBDeferJob() + { + positions = positions, + outAABB = outAABB, + }; + job.Run(); + } + + [BurstCompile] + struct CalcAABBJob : IJob + { + public int length; + + [Unity.Collections.ReadOnly] + public NativeArray positions; + + public NativeReference outAABB; + + public void Execute() + { + outAABB.Value = CalcAABBInternal(positions, length); + } + } + + [BurstCompile] + struct CalcAABBDeferJob : IJob + { + [Unity.Collections.ReadOnly] + public NativeList positions; + + public NativeReference outAABB; + + public void Execute() + { + outAABB.Value = CalcAABBInternal(positions.AsArray(), positions.Length); + } + } + + static AABB CalcAABBInternal(in NativeArray positions, int length) + { + if (positions.Length == 0) + { + return new AABB(); + } + + //float3 min = 0; + //float3 max = 0; + float3 min = float.MaxValue; + float3 max = float.MinValue; + + for (int i = 0; i < length; i++) + { + float3 pos = positions[i]; + min = math.min(min, pos); + max = math.max(max, pos); + } + + var aabb = new AABB(min, max); + return aabb; + } + + //========================================================================================= + /// + /// スフィアマッピングを行いUVを算出するジョブを発行する + /// このUVは接線計算用でありテクスチャ用ではないので注意! + /// + /// + /// + /// + /// + /// + /// + public static JobHandle CalcUVWithSphereMapping(NativeArray positions, int length, NativeReference aabb, NativeArray outUVs, JobHandle dependsOn = new JobHandle()) + { + var job = new CalcUVJob() + { + positions = positions, + aabb = aabb, + uvs = outUVs, + }; + return job.Schedule(length, 32, dependsOn); + } + + public static void CalcUVWithSphereMappingRun(NativeArray positions, int length, NativeReference aabb, NativeArray outUVs) + { + var job = new CalcUVJob() + { + positions = positions, + aabb = aabb, + uvs = outUVs, + }; + job.Run(length); + } + + [BurstCompile] + struct CalcUVJob : IJobParallelFor + { + [Unity.Collections.ReadOnly] + public NativeArray positions; + [Unity.Collections.ReadOnly] + public NativeReference aabb; + + [Unity.Collections.WriteOnly] + public NativeArray uvs; + + public void Execute(int index) + { + // 中心位置からのスフィアマッピング + float3 lv = positions[index] - aabb.Value.Center; + lv = math.normalize(lv); + + float u = math.atan2(lv.x, lv.z); + u = math.clamp(math.unlerp(-math.PI, math.PI, u), 0.0f, 1.0f); + + float v = math.dot(math.up(), lv); + v = math.clamp(math.unlerp(1.0f, -1.0f, v), 0.0f, 1.0f); + + //float2 uv = new float2(u, v); // こちらは横方向ベースになる + float2 uv = new float2(v, u); // こちらは縦方向ベースになる + +#if false + float len = math.length(lv); + float add = index * 0.001234f; // UVを微妙にずらすための加算値 + uv += len * 0.01f + add; +#endif +#if false + //float len = math.length(lv); + float add = index * 0.0001234f; // UVを微妙にずらすための加算値 + //uv += len * 0.1f + add; + uv += add; +#endif +#if true + // 方向ベクトル上に同じUVが生成されてしまうのを避けるためUVに距離を加算してずらす + float add = index * 0.0001234f; // UVを微妙にずらすための加算値 + + // 頂点間のUVの間隔を広めに取り、同じUVが発生しないようにインデックスを使い微妙に値をずらす + uv = uv * 10.0f + add; +#endif + + //Debug.Log($"[{index}] {uv}"); + uvs[index] = uv; + } + } + + //========================================================================================= + /// + /// intデータを加算して新しい領域にコピーする + /// + [BurstCompile] + public struct AddIntDataCopyJob : IJobParallelFor + { + public int dstOffset; + public int addData; + + // src + [Unity.Collections.ReadOnly] + public NativeArray srcData; + + // dst + [NativeDisableParallelForRestriction] + [Unity.Collections.WriteOnly] + public NativeArray dstData; + + public void Execute(int index) + { + int dindex = dstOffset + index; + var data = srcData[index]; + data += addData; + dstData[dindex] = data; + } + } + + /// + /// int2データを加算して新しい領域にコピーする + /// + [BurstCompile] + public struct AddInt2DataCopyJob : IJobParallelFor + { + public int dstOffset; + public int2 addData; + + // src + [Unity.Collections.ReadOnly] + public NativeArray srcData; + + // dst + [NativeDisableParallelForRestriction] + [Unity.Collections.WriteOnly] + public NativeArray dstData; + + public void Execute(int index) + { + int dindex = dstOffset + index; + var data = srcData[index]; + data += addData; + dstData[dindex] = data; + } + } + + /// + /// int3データを加算して新しい領域にコピーする + /// + [BurstCompile] + public struct AddInt3DataCopyJob : IJobParallelFor + { + public int dstOffset; + public int3 addData; + + // src + [Unity.Collections.ReadOnly] + public NativeArray srcData; + + // dst + [NativeDisableParallelForRestriction] + [Unity.Collections.WriteOnly] + public NativeArray dstData; + + public void Execute(int index) + { + int dindex = dstOffset + index; + var data = srcData[index]; + data += addData; + dstData[dindex] = data; + } + } + + //========================================================================================= + /// + /// 座標を変換するジョブを発行します + /// + /// + /// + /// + /// + /// + public static JobHandle TransformPosition(NativeArray positions, int length, in float4x4 toM, JobHandle dependsOn = new JobHandle()) + { + var job = new TransformPositionJob() { toM = toM, positions = positions, }; + return job.Schedule(length, 32, dependsOn); + } + + public static void TransformPositionRun(NativeArray positions, int length, in float4x4 toM) + { + var job = new TransformPositionJob() { toM = toM, positions = positions, }; + job.Run(length); + } + + public static JobHandle TransformPosition(NativeArray srcPositions, NativeArray dstPositions, int length, in float4x4 toM, JobHandle dependsOn = new JobHandle()) + { + var job = new TransformPositionJob2() { toM = toM, srcPositions = srcPositions, dstPositions = dstPositions }; + return job.Schedule(length, 32, dependsOn); + } + + public static void TransformPositionRun(NativeArray srcPositions, NativeArray dstPositions, int length, in float4x4 toM) + { + var job = new TransformPositionJob2() { toM = toM, srcPositions = srcPositions, dstPositions = dstPositions }; + job.Run(length); + } + + [BurstCompile] + public struct TransformPositionJob : IJobParallelFor + { + public float4x4 toM; + public NativeArray positions; + + public void Execute(int vindex) + { + positions[vindex] = MathUtility.TransformPoint(positions[vindex], toM); + } + } + + [BurstCompile] + public struct TransformPositionJob2 : IJobParallelFor + { + public float4x4 toM; + [Unity.Collections.ReadOnly] + public NativeArray srcPositions; + [Unity.Collections.WriteOnly] + public NativeArray dstPositions; + + public void Execute(int vindex) + { + dstPositions[vindex] = MathUtility.TransformPoint(srcPositions[vindex], toM); + } + } + + //========================================================================================= + /// + /// スタートインデックス+データ数とデータの2つの配列からHashMapを構築して返す + /// + /// + /// + /// + public static NativeParallelMultiHashMap ToNativeMultiHashMap(in NativeArray indexArray, in NativeArray dataArray) + { + var map = new NativeParallelMultiHashMap(dataArray.Length, Allocator.Persistent); + + var job = new ConvertArrayToMapJob() + { + indexArray = indexArray, + dataArray = dataArray, + map = map, + }; + job.Run(); + + return map; + } + + [BurstCompile] + struct ConvertArrayToMapJob : IJob where TData : unmanaged + { + [Unity.Collections.ReadOnly] + public NativeArray indexArray; + [Unity.Collections.ReadOnly] + public NativeArray dataArray; + + [Unity.Collections.WriteOnly] + public NativeParallelMultiHashMap map; + + public void Execute() + { + int cnt = indexArray.Length; + for (int i = 0; i < cnt; i++) + { + DataUtility.Unpack12_20(indexArray[i], out var dcnt, out var dstart); + + for (int j = 0; j < dcnt; j++) + { + var data = dataArray[dstart + j]; + map.Add(i, data); + } + } + } + } + + //========================================================================================= + /// + /// NativeReferenceをクリアするジョブを発行する + /// + /// + /// + /// + public static JobHandle ClearReference(NativeReference reference, JobHandle jobHandle) + { + var job = new ClearReferenceJob() + { + reference = reference, + }; + return job.Schedule(jobHandle); + } + + [BurstCompile] + struct ClearReferenceJob : IJob + { + public NativeReference reference; + + public void Execute() + { + reference.Value = 0; + } + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/Utility/Jobs/JobUtility.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Utility/Jobs/JobUtility.cs.meta new file mode 100644 index 00000000..eac63c41 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Utility/Jobs/JobUtility.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: d429f1aa0fb37ca4d9eedbec119474ea +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Utility/Jobs/JobUtility.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Utility/Math.meta b/Assets/MagicaCloth2/Scripts/Core/Utility/Math.meta new file mode 100644 index 00000000..2c567a16 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Utility/Math.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 5abf9b52a60ea9843b4f61eee44d06f7 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/MagicaCloth2/Scripts/Core/Utility/Math/AABB.cs b/Assets/MagicaCloth2/Scripts/Core/Utility/Math/AABB.cs new file mode 100644 index 00000000..933517d4 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Utility/Math/AABB.cs @@ -0,0 +1,238 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using System; +using System.Runtime.CompilerServices; +using Unity.Mathematics; + +namespace MagicaCloth2 +{ + /// + /// このAABB構造体はUnity.Mathematics.Geometry.MinMaxAABBを移植したものです。 + /// MinMaxAABBはinternalのため外部から利用することができません。 + /// このコードはすべてMinMaxAABBのコピーとなります。 + /// + [System.Serializable] + public struct AABB : IEquatable + { + /// + /// The minimum point contained by the AABB. + /// + /// + /// If any component of is greater than then this AABB is invalid. + /// + /// + public float3 Min; + + /// + /// The maximum point contained by the AABB. + /// + /// + /// If any component of is less than then this AABB is invalid. + /// + /// + public float3 Max; + + /// + /// Constructs the AABB with the given minimum and maximum. + /// + /// + /// If you have a center and extents, you can call or + /// to create the AABB. + /// + /// Minimum point inside AABB. + /// Maximum point inside AABB. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public AABB(in float3 min, in float3 max) + { + Min = min; + Max = max; + } + + /// + /// Creates the AABB from a center and extents. + /// + /// + /// This function takes full extents. It is the distance between and . + /// If you have half extents, you can call . + /// + /// Center of AABB. + /// Full extents of AABB. + /// AABB created from inputs. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static AABB CreateFromCenterAndExtents(float3 center, float3 extents) + { + return CreateFromCenterAndHalfExtents(center, extents * 0.5f); + } + + /// + /// Creates the AABB from a center and half extents. + /// + /// + /// This function takes half extents. It is half the distance between and . + /// If you have full extents, you can call . + /// + /// Center of AABB. + /// Half extents of AABB. + /// AABB created from inputs. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static AABB CreateFromCenterAndHalfExtents(float3 center, float3 halfExtents) + { + return new AABB(center - halfExtents, center + halfExtents); + } + + /// + /// Computes the extents of the AABB. + /// + /// + /// Extents is the componentwise distance between min and max. + /// + public float3 Extents => Max - Min; + + /// + /// Computes the half extents of the AABB. + /// + /// + /// HalfExtents is half of the componentwise distance between min and max. Subtracting HalfExtents from Center + /// gives Min and adding HalfExtents to Center gives Max. + /// + public float3 HalfExtents => (Max - Min) * 0.5f; + + /// + /// Computes the center of the AABB. + /// + public float3 Center => (Max + Min) * 0.5f; + + /// + /// 最大の辺の長さを返す + /// + public float MaxSideLength + { + get + { + var ext = Extents; + return math.max(math.max(ext.x, ext.y), ext.z); + } + } + + /// + /// Check if the AABB is valid. + /// + /// + /// An AABB is considered valid if is componentwise less than or equal to . + /// + /// True if is componentwise less than or equal to . + public bool IsValid => math.all(Min <= Max); + + /// + /// Computes the surface area for this axis aligned bounding box. + /// + public float SurfaceArea + { + get + { + float3 diff = Max - Min; + return 2 * math.dot(diff, diff.yzx); + } + } + + /// + /// Tests if the input point is contained by the AABB. + /// + /// Point to test. + /// True if AABB contains the input point. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool Contains(in float3 point) => math.all(point >= Min & point <= Max); + + /// + /// Tests if the input AABB is contained entirely by this AABB. + /// + /// AABB to test. + /// True if input AABB is contained entirely by this AABB. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool Contains(in AABB aabb) => math.all((Min <= aabb.Min) & (Max >= aabb.Max)); + + /// + /// Tests if the input AABB overlaps this AABB. + /// + /// AABB to test. + /// True if input AABB overlaps with this AABB. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool Overlaps(in AABB aabb) + { + return math.all(Max >= aabb.Min & Min <= aabb.Max); + } + + /// + /// Expands the AABB by the given signed distance. + /// + /// + /// Positive distance expands the AABB while negative distance shrinks the AABB. + /// + /// Signed distance to expand the AABB with. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Expand(float signedDistance) + { + Min -= signedDistance; + Max += signedDistance; + } + + /// + /// Encapsulates the given AABB. + /// + /// + /// Modifies this AABB so that it contains the given AABB. If the given AABB is already contained by this AABB, + /// then this AABB doesn't change. + /// + /// + /// AABB to encapsulate. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Encapsulate(in AABB aabb) + { + Min = math.min(Min, aabb.Min); + Max = math.max(Max, aabb.Max); + } + + /// + /// Encapsulate the given point. + /// + /// + /// Modifies this AABB so that it contains the given point. If the given point is already contained by this AABB, + /// then this AABB doesn't change. + /// + /// + /// Point to encapsulate. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Encapsulate(in float3 point) + { + Min = math.min(Min, point); + Max = math.max(Max, point); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool Equals(AABB other) + { + return Min.Equals(other.Min) && Max.Equals(other.Max); + } + + /// + /// 変換マトリックスにより座標を変換させる + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Transform(in float4x4 toM) + { + float3 min = math.transform(toM, Min); + float3 max = math.transform(toM, Max); + Min = math.min(min, max); + Max = math.max(min, max); + } + + public override string ToString() + { + //return string.Format("AABB({0}, {1})", Min, Max); + return $"AABB Center:{Center}, HalfExtents:{HalfExtents}, Min:{Min}, Max:{Max}"; + } + } + +} diff --git a/Assets/MagicaCloth2/Scripts/Core/Utility/Math/AABB.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Utility/Math/AABB.cs.meta new file mode 100644 index 00000000..a9c837f7 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Utility/Math/AABB.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: ae15307e07485a447aa84cda0ddb05e1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Utility/Math/AABB.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Utility/Math/IntAABB.cs b/Assets/MagicaCloth2/Scripts/Core/Utility/Math/IntAABB.cs new file mode 100644 index 00000000..dcfcfe5e --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Utility/Math/IntAABB.cs @@ -0,0 +1,158 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using System; +using System.Runtime.CompilerServices; +using Unity.Mathematics; + +namespace MagicaCloth2 +{ + /// + /// int3型のAABB + /// + [System.Serializable] + public struct IntAABB : IEquatable + { + /// + /// The minimum point contained by the AABB. + /// + /// + /// If any component of is greater than then this AABB is invalid. + /// + /// + public int3 Min; + + /// + /// The maximum point contained by the AABB. + /// + /// + /// If any component of is less than then this AABB is invalid. + /// + /// + public int3 Max; + + /// + /// Constructs the AABB with the given minimum and maximum. + /// + /// + /// If you have a center and extents, you can call or + /// to create the AABB. + /// + /// Minimum point inside AABB. + /// Maximum point inside AABB. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public IntAABB(int3 min, int3 max) + { + Min = min; + Max = max; + } + + /// + /// Computes the extents of the AABB. + /// + /// + /// Extents is the componentwise distance between min and max. + /// + public int3 Extents => Max - Min; + + /// + /// Computes the center of the AABB. + /// + public int3 Center => (Max + Min) / 2; + + /// + /// Check if the AABB is valid. + /// + /// + /// An AABB is considered valid if is componentwise less than or equal to . + /// + /// True if is componentwise less than or equal to . + public bool IsValid => math.all(Min <= Max); + + /// + /// Tests if the input point is contained by the AABB. + /// + /// Point to test. + /// True if AABB contains the input point. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool Contains(int3 point) => math.all(point >= Min & point <= Max); + + /// + /// Tests if the input AABB is contained entirely by this AABB. + /// + /// AABB to test. + /// True if input AABB is contained entirely by this AABB. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool Contains(IntAABB aabb) => math.all((Min <= aabb.Min) & (Max >= aabb.Max)); + + /// + /// Tests if the input AABB overlaps this AABB. + /// + /// AABB to test. + /// True if input AABB overlaps with this AABB. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool Overlaps(IntAABB aabb) + { + return math.all(Max >= aabb.Min & Min <= aabb.Max); + } + + /// + /// Expands the AABB by the given signed distance. + /// + /// + /// Positive distance expands the AABB while negative distance shrinks the AABB. + /// + /// Signed distance to expand the AABB with. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Expand(int signedDistance) + { + Min -= signedDistance; + Max += signedDistance; + } + + /// + /// Encapsulates the given AABB. + /// + /// + /// Modifies this AABB so that it contains the given AABB. If the given AABB is already contained by this AABB, + /// then this AABB doesn't change. + /// + /// + /// AABB to encapsulate. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Encapsulate(IntAABB aabb) + { + Min = math.min(Min, aabb.Min); + Max = math.max(Max, aabb.Max); + } + + /// + /// Encapsulate the given point. + /// + /// + /// Modifies this AABB so that it contains the given point. If the given point is already contained by this AABB, + /// then this AABB doesn't change. + /// + /// + /// Point to encapsulate. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Encapsulate(int3 point) + { + Min = math.min(Min, point); + Max = math.max(Max, point); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool Equals(IntAABB other) + { + return Min.Equals(other.Min) && Max.Equals(other.Max); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public override string ToString() + { + return string.Format("AABB({0}, {1})", Min, Max); + } + } + +} diff --git a/Assets/MagicaCloth2/Scripts/Core/Utility/Math/IntAABB.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Utility/Math/IntAABB.cs.meta new file mode 100644 index 00000000..1e0afc14 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Utility/Math/IntAABB.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 93dbd06f10c49dd4b9ae88b2a9c4c099 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Utility/Math/IntAABB.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Utility/Math/MathExtensions.cs b/Assets/MagicaCloth2/Scripts/Core/Utility/Math/MathExtensions.cs new file mode 100644 index 00000000..c328dc43 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Utility/Math/MathExtensions.cs @@ -0,0 +1,61 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using System.Runtime.CompilerServices; +using Unity.Mathematics; + +namespace MagicaCloth2 +{ + public static class MathExtensions + { + /// + /// float4x4を16の配列として扱うための拡張 + /// + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float MC2GetValue(in this float4x4 m, int index) + { + index = math.clamp(index, 0, 15); + return m[index / 4][index % 4]; + } + + /// + /// float4x4を16の配列として扱うための拡張 + /// + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void MC2SetValue(ref this float4x4 m, int index, float value) + { + index = math.clamp(index, 0, 15); + m[index / 4][index % 4] = value; + } + + /// + /// AnimationCurveが格納されたfloat4x4からデータを取得する(0.0 ~ 1.0でクランプ) + /// + /// + /// 0.0 ~ 1.0 + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float MC2EvaluateCurveClamp01(in this float4x4 m, float time) + { + return math.saturate(DataUtility.EvaluateCurve(m, time)); + } + + /// + /// AnimationCurveが格納されたfloat4x4からデータを取得する + /// + /// + /// 0.0 ~ 1.0 + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float MC2EvaluateCurve(in this float4x4 m, float time) + { + return DataUtility.EvaluateCurve(m, time); + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/Utility/Math/MathExtensions.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Utility/Math/MathExtensions.cs.meta new file mode 100644 index 00000000..c8ac2e2b --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Utility/Math/MathExtensions.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: ae8fc4e69ea083a4081671c5eff29606 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Utility/Math/MathExtensions.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Utility/Math/MathUtility.cs b/Assets/MagicaCloth2/Scripts/Core/Utility/Math/MathUtility.cs new file mode 100644 index 00000000..ee98ceae --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Utility/Math/MathUtility.cs @@ -0,0 +1,1814 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using System.Runtime.CompilerServices; +using Unity.Mathematics; +using UnityEngine; + +namespace MagicaCloth2 +{ + public static class MathUtility + { + /// + /// NaN判定 + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool IsNaN(float3 v) + { + return math.any(math.isnan(v)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool IsNaN(float4 v) + { + return math.any(math.isnan(v)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool IsNaN(quaternion q) + { + return math.any(math.isnan(q.value)); + } + + /// + /// ゼロ長さ判定 + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool IsZeroDistance(float3 v) + { + return math.length(v) < 1e-8f; + } + + /// + /// 数値を(-1.0f~1.0f)にクランプする + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float Clamp1(float a) + { + return math.clamp(a, -1.0f, 1.0f); + } + + /// + /// 投影ベクトルを求める + /// + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float3 Project(in float3 v, in float3 n) + { + return math.dot(v, n) * n; + } + + /// + /// ベクトルを平面に投影する + /// + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float3 ProjectOnPlane(in float3 v, in float3 n) + { + return v - math.dot(v, n) * n; + } + + /// + /// 2つのベクトルのなす角を返す(ラジアン) + /// + /// + /// + /// ラジアン + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float Angle(in float3 v1, in float3 v2) + { + float len1 = math.length(v1); + float len2 = math.length(v2); + + Develop.Assert(len1 * len2 > 0.0f); + float cos_sita = math.dot(v1, v2) / (len1 * len2); + + float sita = math.acos(Clamp1(cos_sita)); + + //return degrees(sita); + return sita; + } + + /// + /// ベクトルの長さをクランプする + /// + /// + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float3 ClampVector(float3 v, float minlength, float maxlength) + { + float len = math.length(v); + if (len > 1e-09f) + { + if (len > maxlength) + { + v *= (maxlength / len); + } + else if (len < minlength) + { + v *= (minlength / len); + } + } + + return v; + } + + /// + /// ベクトルの長さをクランプする + /// + /// + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float3 ClampVector(float3 v, float maxlength) + { + float len = math.length(v); + if (len > 1e-09f && len > maxlength) + { + v *= (maxlength / len); + } + + return v; + } + + /// + /// frotmからtoへの移動を最大移動距離でクランプする + /// + /// 基準座標 + /// 目標座標 + /// 最大移動距離 + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float3 ClampDistance(float3 from, float3 to, float maxlength) + { + float len = math.distance(from, to); + if (len <= maxlength) + return to; + + Develop.Assert(len > 0.0f); + float t = maxlength / len; + return math.lerp(from, to, t); + } + + /// + /// ベクトル(dir)を最大角度にクランプする + /// + /// + /// + /// 最大角度(ラジアン) + /// + public static bool ClampAngle(in float3 dir, in float3 basedir, float maxAngle, out float3 outdir) + { + float3 v1 = math.normalize(dir); + float3 v2 = math.normalize(basedir); + + float c = Clamp1(math.dot(v1, v2)); + float angle = math.acos(c); + + //if (c > 0.9995f || angle <= maxAngle) + if (angle <= maxAngle) + { + // クランプの必要なし + outdir = dir; + return false; + } + + // 戻す割合 + Develop.Assert(angle != 0.0f); + float t = (angle - maxAngle) / angle; + + // dirをmaxAngleにクランプするクォータニオンを求める + float3 axis = math.cross(v1, v2); + if (math.abs(1.0f + c) < 1e-06f) + { + angle = (float)math.PI; + + if (v1.x > v1.y && v1.x > v1.z) + { + axis = math.cross(v1, new float3(0, 1, 0)); + } + else + { + axis = math.cross(v1, new float3(1, 0, 0)); + } + } + else if (math.abs(1.0f - c) < 1e-06f) + { + //angle = 0.0f; + //axis = new float3(1, 0, 0); + outdir = dir; + return false; + } + var q = quaternion.AxisAngle(math.normalize(axis), angle * t); + + outdir = math.mul(q, dir); + return true; + } + + /// + /// fromからtoへ回転させるクォータニオンを返します + /// + /// + /// + /// 補間率(0.0-1.0) + /// + public static quaternion FromToRotation(in float3 from, in float3 to, float t = 1.0f) + { + float3 v1 = math.normalize(from); + float3 v2 = math.normalize(to); + + float c = Clamp1(math.dot(v1, v2)); + float angle = math.acos(c); + float3 axis = math.cross(v1, v2); + + if (math.abs(1.0f + c) < 1e-06f) + { + angle = (float)math.PI; + + if (v1.x > v1.y && v1.x > v1.z) + { + axis = math.cross(v1, new float3(0, 1, 0)); + } + else + { + axis = math.cross(v1, new float3(1, 0, 0)); + } + } + else if (math.abs(1.0f - c) < 1e-06f) + { + //angle = 0.0f; + //axis = new float3(1, 0, 0); + return quaternion.identity; + } + + return quaternion.AxisAngle(math.normalize(axis), angle * t); + } + + /// + /// fromからtoへ回転させるクォータニオンを返します(単位化なし) + /// + /// + /// + /// 補間率(0.0-1.0) + /// + public static quaternion FromToRotationWithoutNormalize(in float3 v1, in float3 v2, float t = 1.0f) + { + //float3 v1 = math.normalize(from); + //float3 v2 = math.normalize(to); + + float c = Clamp1(math.dot(v1, v2)); + float angle = math.acos(c); + float3 axis = math.cross(v1, v2); + + if (math.abs(1.0f + c) < 1e-06f) + { + angle = (float)math.PI; + + if (v1.x > v1.y && v1.x > v1.z) + { + axis = math.cross(v1, new float3(0, 1, 0)); + } + else + { + axis = math.cross(v1, new float3(1, 0, 0)); + } + } + else if (math.abs(1.0f - c) < 1e-06f) + { + //angle = 0.0f; + //axis = new float3(1, 0, 0); + return quaternion.identity; + } + + return quaternion.AxisAngle(math.normalize(axis), angle * t); + } + + /// + /// fromからtoへ回転させるクォータニオンを返します + /// + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static quaternion FromToRotation(in quaternion from, in quaternion to) + { + return math.mul(to, math.inverse(from)); + } + + /// + /// 2つのクォータニオンの角度を返します(ラジアン) + /// 不正なクォータニオンでは結果が不定になるので注意!例:(0,0,0,0)など + /// + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float Angle(in quaternion a, in quaternion b) + { + const float PI2 = math.PI * 2.0f; + + float dot = math.dot(a, b); + if (math.abs(dot) < 0.9999f) + { + var ang = math.acos(Clamp1(dot)) * 2.0f; // x2.0が必要 + return ang > math.PI ? PI2 - ang : ang; + } + else + return 0; + } + + /// + /// クォータニオンを最大角度にクランプします + /// + /// 基準回転 + /// 目標回転 + /// 最大角度(ラジアン) + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static quaternion ClampAngle(quaternion from, quaternion to, float maxAngle) + { + var ang = Angle(from, to); + if (ang <= maxAngle) + return to; + + Develop.Assert(ang != 0.0f); + float t = maxAngle / ang; + + return math.slerp(from, to, t); + } + + /// + /// 法線と接線から回転姿勢を求める + /// + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static quaternion ToRotation(in float3 nor, in float3 tan) + { +#if MC2_DEBUG + // 安全性確認 + float ln = math.length(nor); + float lt = math.length(tan); + Develop.Assert(ln > 0.99f && ln < 1.01f); + Develop.Assert(lt > 0.99f && lt < 1.01f); + float dot = math.dot(nor / ln, tan / lt); + Develop.Assert(dot != 1.0f && dot != -1.0f); +#endif + // 2 つの入力ベクトルは単位長であり、同一直線上にないことが前提となります。 + return quaternion.LookRotation(tan, nor); + } + + /// + /// 回転姿勢を法線と接線に分解して返す + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void ToNormalTangent(in quaternion rot, out float3 nor, out float3 tan) + { + nor = math.mul(rot, math.up()); + tan = math.mul(rot, math.forward()); + } + + /// + /// 回転姿勢から法線を取り出す + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float3 ToNormal(in quaternion rot) + { + return math.mul(rot, math.up()); + } + + /// + /// 回転姿勢から接線を取り出す + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float3 ToTangent(in quaternion rot) + { + return math.mul(rot, math.forward()); + } + + /// + /// 回転姿勢から従法線を取り出す + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float3 ToBinormal(in quaternion rot) + { + return math.mul(rot, math.right()); + } + + /// + /// 法線/接線から従法線を求めて返す + /// + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float3 Binormal(in float3 nor, in float3 tan) + { + return math.cross(nor, tan); + } + + /// + /// 方向ベクトルをXY回転角度(ラジアン)に分離する、Z角度は常に0である + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float3 AxisToEuler(in float3 axis) + { + float angy = math.atan2(axis.x, axis.z); + float angx = math.atan2(-axis.y, math.length(axis - new float3(0, axis.y, 0))); + return new float3(angx, angy, 0); + } + + /// + /// 方向ベクトルからクォータニオンを作成して返す + /// ベクトルは一旦オイラー角に分解されてからクォータニオンへ組み立て直される + /// XYの回転軸を安定させるため + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static quaternion AxisQuaternion(float3 dir) + { + return quaternion.Euler(AxisToEuler(dir)); + } + + /// + /// クォータニオンから回転軸と回転角度(rad)を取得する + /// この結果はUnity.Quaternion.ToAngleAxisと同じである(僅かに誤差あり) + /// ただ回転角度が360度を越えると軸が逆転するので注意!(これはUnity.ToAngleAxis()でも同じ) + /// 回転がほぼ0の場合は回転軸として(0, 0, 0)を返す(Unity.ToAngleAxisでは(1, 0, 0)) + /// + /// + /// 回転角度(rad) + /// 回転軸 + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void ToAngleAxis(in quaternion q, out float angle, out float3 axis) + { + float a = math.abs(q.value.w) < 0.9999f ? math.acos(q.value.w) : 0; + angle = 2.0f * a; + + float s = math.sin(a); + if (math.abs(s) < 1e-06f) + axis = 0; // Unity.Quaternion.ToAngleAxisでは(1, 0, 0) + else + axis = q.value.xyz / s; + } + + /// + /// クォータニオンからオイラー角度を計算して返す + /// + /// + /// (Deg)角度 + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float3 ToEuler(in quaternion q) + { + float3 angles = 0; + + // クォータニオンの成分 + float qx = q.value.x; + float qy = q.value.y; + float qz = q.value.z; + float qw = q.value.w; + + // ピッチ (x軸回転) + float sinX = 2f * (qw * qx - qz * qy); + if (math.abs(sinX) >= 0.99999f) // ジンバルロックの検出 + { + angles.x = math.sign(sinX) * 90f; // ±90度(deg) + angles.y = math.atan2(2f * (qw * qy + qx * qz), 1f - 2f * (qx * qx + qy * qy)); + angles.y = math.degrees(angles.y); + angles.z = 0f; // ジンバルロックでロールは不定 + } + else + { + angles.x = math.asin(sinX); + // ヨー (y軸回転) + angles.y = math.atan2(2f * (qw * qy + qx * qz), 1f - 2f * (qx * qx + qy * qy)); + // ロール (z軸回転) + //angles.z = math.atan2(2f * (qw * qz + qx * qy), 1f - 2f * (qy * qy + qz * qz)); + angles.z = math.atan2(2f * (qw * qz + qx * qy), 1f - 2f * (qx * qx + qz * qz)); // どうやらこれっぽい + angles = math.degrees(angles); + } + + return angles; + } + + /// + /// 与えられた線分abおよび点cに対して、ab上の最近接点t(0.0-1.0)を計算して返す + /// + /// + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float ClosestPtPointSegmentRatio(in float3 c, in float3 a, in float3 b) + { + float3 ab = b - a; + // パラメータ化されている位置d(t) = a + t * (b - a) の計算によりabにcを射影 + float dot = math.dot(ab, ab); + // abが同じ座標を考慮 + if (dot == 0.0f) + return 0.0f; + //Develop.Assert(dot != 0.0f); + float t = math.dot(c - a, ab) / dot; + // 線分の外側にある場合、t(従ってd)を最近接点までクランプ + t = math.saturate(t); + return t; + } + + /// + /// 与えられた線分abおよび点cに対して、ab上の最近接点tを計算して返す。tはクランプされない + /// + /// + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float ClosestPtPointSegmentRatioNoClamp(float3 c, float3 a, float3 b) + { + float3 ab = b - a; + // パラメータ化されている位置d(t) = a + t * (b - a) の計算によりabにcを射影 + float dot = math.dot(ab, ab); + Develop.Assert(dot != 0.0f); + float t = math.dot(c - a, ab) / dot; + return t; + } + + /// + /// 与えられた線分abおよび点cに対して、ab上の最近接点座標dを計算して返す + /// + /// + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float3 ClosestPtPointSegment(float3 c, float3 a, float3 b) + { + float3 ab = b - a; + // パラメータ化されている位置d(t) = a + t * (b - a) の計算によりabにcを射影 + float dot = math.dot(ab, ab); + Develop.Assert(dot != 0.0f); + float t = math.dot(c - a, ab) / dot; + // 線分の外側にある場合、t(従ってd)を最近接点までクランプ + t = math.saturate(t); + // クランプされているtからの射影されている位置を計算 + return a + t * ab; + } + + /// + /// 与えられた線分abおよび点cに対して、ab上の最近接点座標dを計算して返す。dはクランプされない + /// + /// + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float3 ClosestPtPointSegmentNoClamp(float3 c, float3 a, float3 b) + { + float3 ab = b - a; + // パラメータ化されている位置d(t) = a + t * (b - a) の計算によりabにcを射影 + float dot = math.dot(ab, ab); + Develop.Assert(dot != 0.0f); + float t = math.dot(c - a, ab) / dot; + // クランプされているtからの射影されている位置を計算 + return a + t * ab; + } + + /// + /// 2つの線分(p1-q1)(p2-q2)の最近接点(c1, c2)を計算する + /// 戻り値として最近接点の距離の平方を返す + /// + /// 線分1の始点 + /// 線分1の終点 + /// 線分2の始点 + /// 線分2の終点 + /// 最近接点1 + /// 最近接点2 + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float ClosestPtSegmentSegment(in float3 p1, in float3 q1, in float3 p2, in float3 q2, out float s, out float t, out float3 c1, out float3 c2) + { + //s = 0.0f; + //t = 0.0f; + float3 d1 = q1 - p1; // 線分s1の方向ベクトル + float3 d2 = q2 - p2; // 線分s2の方向ベクトル + float3 r = p1 - p2; + float a = math.dot(d1, d1); // 線分s1の距離の平方、常に正 + float e = math.dot(d2, d2); // 線分s2の距離の平方、常に正 + float f = math.dot(d2, r); + // 片方あるいは両方の線分が点に縮退しているかどうかチェック + if (a <= 1e-8f && e <= 1e-8f) + { + // 両方の線分が点に縮退 + s = t = 0.0f; + c1 = p1; + c2 = p2; + return math.dot(c1 - c2, c1 - c2); + } + if (a <= 1e-8f) + { + // 最初の線分が点に縮退 + s = 0.0f; + t = math.saturate(f / e); + } + else + { + float c = math.dot(d1, r); + if (e <= 1e-8f) + { + // 2番目の線分が点に縮退 + t = 0.0f; + s = math.saturate(-c / a); + } + else + { + // ここから一般的な縮退の場合を開始 + float b = math.dot(d1, d2); + float denom = a * e - b * b; // 常に正 + // 線分が平行でない場合、L1上のL2に対する最近接点を計算、そして + // 線分s1に対してクランプ。そうでない場合は任意s(ここでは0)を選択 + if (denom != 0.0f) + { + s = math.saturate((b * f - c * e) / denom); + } + else + { + s = 0.0f; + } + // L2上のs1(s)に対する最近接点を以下を用いて計算 + // t = dot((p1 + d1 * s) - p2, d2) / dot(d2, d2) = (b * s + f) / e + t = (b * s + f) / e; + // tが[0,1]の中にあれば終了。 + // そうでなければtをクランプ、sをtの新しい値に対して以下を用いて再計算 + // s = dot((p2 + d2 * t) - p1, d1) / dot(d1, d1) = (t * b - c) / a + // そしてsを[0,1]にクランプ + if (t < 0.0f) + { + t = 0.0f; + s = math.saturate(-c / a); + } + else if (t > 1.0f) + { + t = 1.0f; + s = math.saturate((b - c) / a); + } + } + } + + c1 = p1 + d1 * s; + c2 = p2 + d2 * t; + + return math.dot(c1 - c2, c1 - c2); + } + + /// + /// 2つの線分(p1-q1)(p2-q2)の最近接点(s, t)を計算する + /// この関数ではs/tのみで接点と距離は計算しない + /// + /// 線分1の始点 + /// 線分1の終点 + /// 線分2の始点 + /// 線分2の終点 + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void ClosestPtSegmentSegment2(in float3 p1, in float3 q1, in float3 p2, in float3 q2, out float s, out float t) + { + //s = 0.0f; + //t = 0.0f; + float3 d1 = q1 - p1; // 線分s1の方向ベクトル + float3 d2 = q2 - p2; // 線分s2の方向ベクトル + float3 r = p1 - p2; + float a = math.dot(d1, d1); // 線分s1の距離の平方、常に正 + float e = math.dot(d2, d2); // 線分s2の距離の平方、常に正 + float f = math.dot(d2, r); + // 片方あるいは両方の線分が点に縮退しているかどうかチェック + if (a <= 1e-8f && e <= 1e-8f) + { + // 両方の線分が点に縮退 + s = t = 0.0f; + } + else if (a <= 1e-8f) + { + // 最初の線分が点に縮退 + s = 0.0f; + t = math.saturate(f / e); + } + else + { + float c = math.dot(d1, r); + if (e <= 1e-8f) + { + // 2番目の線分が点に縮退 + t = 0.0f; + s = math.saturate(-c / a); + } + else + { + // ここから一般的な縮退の場合を開始 + float b = math.dot(d1, d2); + float denom = a * e - b * b; // 常に正 + // 線分が平行でない場合、L1上のL2に対する最近接点を計算、そして + // 線分s1に対してクランプ。そうでない場合は任意s(ここでは0)を選択 + if (denom != 0.0f) + { + s = math.saturate((b * f - c * e) / denom); + } + else + { + s = 0.0f; + } + // L2上のs1(s)に対する最近接点を以下を用いて計算 + // t = dot((p1 + d1 * s) - p2, d2) / dot(d2, d2) = (b * s + f) / e + t = (b * s + f) / e; + // tが[0,1]の中にあれば終了。 + // そうでなければtをクランプ、sをtの新しい値に対して以下を用いて再計算 + // s = dot((p2 + d2 * t) - p1, d1) / dot(d1, d1) = (t * b - c) / a + // そしてsを[0,1]にクランプ + if (t < 0.0f) + { + t = 0.0f; + s = math.saturate(-c / a); + } + else if (t > 1.0f) + { + t = 1.0f; + s = math.saturate((b - c) / a); + } + } + } + } + + /// + /// 三角形(abc)から点(p)への最近接点とその重心座標uvwを返す + /// + /// + /// + /// + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float3 ClosestPtPointTriangle(in float3 p, in float3 a, in float3 b, in float3 c, out float3 uvw) + { + uvw = 0; + float v = 0, w = 0; + + // PがAの外側の頂点領域の中にあるかどうかチェック + var ab = b - a; + var ac = c - a; + var ap = p - a; + float d1 = math.dot(ab, ap); + float d2 = math.dot(ac, ap); + if (d1 <= 0.0f && d2 <= 0.0f) + { + uvw.x = 1; // 重心座標(1,0,0) + return a; + } + + // PがBの外側の頂点領域の中にあるかどうかチェック + var bp = p - b; + float d3 = math.dot(ab, bp); + float d4 = math.dot(ac, bp); + if (d3 >= 0.0f && d4 <= d3) + { + uvw.y = 1; // 重心座標(0,1,0) + return b; + } + + // PがABの辺領域の中にあるかどうかチェックし、あればPのAB上に対する射影を返す + float vc = d1 * d4 - d3 * d2; + if (vc <= 0.0f && d1 >= 0.0f && d3 <= 0.0f) + { + Develop.Assert((d1 - d3) != 0.0f); + v = d1 / (d1 - d3); + uvw = new float3(1 - v, v, 0); // 重心座標(1-v,v,0) + return a + v * ab; + } + + // PがCの外側の頂点領域の中にあるかどうかチェック + var cp = p - c; + float d5 = math.dot(ab, cp); + float d6 = math.dot(ac, cp); + if (d6 >= 0.0f && d5 <= d6) + { + uvw.z = 1; // 重心座標(0,0,1) + return c; + } + + // PがACの辺領域の中にあるかどうかチェックし、あればPのAC上に対する射影を返す + float vb = d5 * d2 - d1 * d6; + if (vb <= 0.0f && d2 >= 0.0f && d6 <= 0.0f) + { + Develop.Assert((d2 - d6) != 0.0f); + w = d2 / (d2 - d6); + uvw = new float3(1 - w, 0, w); // 重心座標(1-w,0,w) + return a + w * ac; + } + + // PがBCの辺領域の中にあるかどうかチェックし、あればPのBC上に対する射影を返す + float va = d3 * d6 - d5 * d4; + if (va <= 0.0f && (d4 - d3) >= 0.0f && (d5 - d6) >= 0.0f) + { + float g = (d4 - d3) + (d5 - d6); + Develop.Assert(g != 0.0f); + w = (d4 - d3) / g; + uvw = new float3(0, 1 - w, w); // 重心座標(0,1-w,w) + return b + w * (c - b); + } + + // Pは面領域の中にある。Qをその重心座標(u,v,w)を用いて計算 + float h = va + vb + vc; + Develop.Assert(h != 0.0f); + float denom = 1.0f / h; + v = vb * denom; + w = vc * denom; + uvw = new float3(1 - v - w, v, w); // 重心座標 + return a + ab * v + ac * w; + } + + /// + /// 三角形と点の最近接点重心(uvw)から点が三角形の内部にあるか判定する + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool PointInTriangleUVW(float3 uvw) + { + return math.all(uvw); + } + + + /// + /// トライアングルの重心を返す + /// + /// + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float3 TriangleCenter(in float3 p0, in float3 p1, in float3 p2) + { + return (p0 + p1 + p2) / 3.0f; + } + + /// + /// トライアングルの法線を計算して返す + /// + /// + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float3 TriangleNormal(in float3 p0, in float3 p1, in float3 p2) + { + var c = math.cross(p1 - p0, p2 - p0); +#if MC2_DEBUG + Develop.Assert(math.length(c) > 0.0f); +#endif + return math.normalize(c); + } + + /// + /// トライアングルの面積を求めて返す + /// + /// + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float TriangleArea(in float3 p0, in float3 p1, in float3 p2) + { + var c = math.cross(p1 - p0, p2 - p0); + return math.length(c); + } + + /// + /// 安全なトライアングルか判定する + /// 面積が極端に小さいトライアングルは不正とする + /// + /// + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool IsSafeTriangle(in float3 p0, in float3 p1, in float3 p2) + { + return TriangleArea(p0, p1, p2) > 1e-06f; + } + + /// + /// トライアングルの接線を計算して返す。 + /// 接線は単位化される。ただし、状況により長さ0となるケースがありその場合はベクトル0を返す。 + /// + /// + /// + /// + /// + /// + /// + /// + public static float3 TriangleTangent(in float3 p0, in float3 p1, in float3 p2, in float2 uv0, in float2 uv1, in float2 uv2) + { + // 接線(頂点座標とUVから接線を求める一般的なアルゴリズム) + float3 distBA = p1 - p0; + float3 distCA = p2 - p0; + float2 tdistBA = uv1 - uv0; + float2 tdistCA = uv2 - uv0; + float area = tdistBA.x * tdistCA.y - tdistBA.y * tdistCA.x; + float3 tan = 0; + if (area == 0.0f) + { +#if MC2_DEBUG + Debug.LogWarning($"Calc tangent area = 0!\np0:{p0},p1:{p1},p2:{p2}\nuv0:{uv0},uv1:{uv1},uv2:{uv2}"); +#endif + + // どうしてもまれに発生するので一旦定数で処理を流してみる + area = 1; + } + + //else + { + float delta = 1.0f / area; + tan = new float3( + (distBA.x * tdistCA.y) + (distCA.x * -tdistBA.y), + (distBA.y * tdistCA.y) + (distCA.y * -tdistBA.y), + (distBA.z * tdistCA.y) + (distCA.z * -tdistBA.y) + ) * delta; + // 左手座標系に合わせる + tan = -tan; + } + + // 長さ0はベクトル0となる + tan = math.normalizesafe(tan, 0); + //#if MC2_DEBUG + // Debug.Assert(math.length(tan) > Define.System.Epsilon); + //#endif + // tan = math.normalize(tan); + + return tan; + } + +#if false + /// + /// トライアングルの回転姿勢を返す + /// 法線と(重心-p0)の軸からなるクォータニオン + /// + /// + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static quaternion TriangleRotation(float3 p0, float3 p1, float3 p2) + { + var n = TriangleNormal(p0, p1, p2); + var cen = TriangleCenter(p0, p1, p2); + var tan = math.normalize(p0 - cen); + return quaternion.LookRotation(tan, n); + } + + /// + /// 隣接する2つのトライアングルの回転姿勢を返す + /// 法線の平均と共通エッジからなるクォータニオン + /// + /// + /// + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static quaternion TriangleCenterRotation(float3 p0, float3 p1, float3 p2, float3 p3) + { + var n0 = TriangleNormal(p0, p2, p3); + var n1 = TriangleNormal(p1, p3, p2); + var n = (n0 + n1) * 0.5f; + var tan = math.normalize(p3 - p2); + return quaternion.LookRotation(tan, n); + } +#endif + + /// + /// トライアングルペアのなす角を返す(ラジアン) + /// v2 + + /// / \ + /// v0 +---+ v1 + /// \ / + /// v3 + + /// + /// + /// + /// ラジアン、水平時は0となる + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float TriangleAngle(in float3 v0, in float3 v1, in float3 v2, in float3 v3) + { + var ev = v1 - v0; + var va = v2 - v0; + var vb = v3 - v0; + var na = math.cross(va, ev); + var nb = math.cross(ev, vb); + float ang = Angle(na, nb); + + return ang; + } + + /// + /// トライアングル重心からの距離を返す + /// + /// + /// + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float DistanceTriangleCenter(float3 p, float3 p0, float3 p1, float3 p2) + { + var cen = (p0 + p1 + p2) / 3.0f; + return math.distance(p, cen); + } + + /// + /// 点pがトライアングルの正負どちらの向きにあるか返す(-1/0/+1) + /// + /// + /// + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float DirectionPointTriangle(float3 p, float3 a, float3 b, float3 c) + { + var ab = b - a; + var ac = c - a; + var ap = p - a; + + float3 n = math.cross(ab, ac); + + float d = math.dot(ap, n); + return math.sign(d); + } + + /// + /// 2つのトライアングルと共通するエッジから残りの2つ頂点(対角点)を返す + /// + /// + /// + /// + /// + public static int2 GetRestTriangleVertex(int3 tri1, int3 tri2, int2 edge) + { + int2 r = -1; + + for (int i = 0; i < 3; i++) + { + var val = tri1[i]; + if (val != edge.x && val != edge.x && val != edge.y && val != edge.y) + { + r[0] = val; + break; + } + } + for (int i = 0; i < 3; i++) + { + var val = tri2[i]; + if (val != edge.x && val != edge.x && val != edge.y && val != edge.y) + { + r[1] = val; + break; + } + } + + return r; + } + + /// + /// 2つのトライアングルから共通する辺のインデックスを返す + /// + /// + /// + /// 見つからない場合は(0,0) + public static int2 GetCommonEdgeFromTrianglePair(int3 tri1, int3 tri2) + { + int2 e = 0; + int eindex = 0; + + for (int i = 0; i < 3; i++) + { + if (tri1[i] == tri2.x || tri1[i] == tri2.y || tri1[i] == tri2.z) + { + e[eindex] = tri1[i]; + eindex++; + } + } + if (eindex != 2) + { + Debug.LogError("Common edge nothing!"); + return 0; + } + + if (e.x > e.y) + { + int w = e.x; + e.x = e.y; + e.y = w; + } + + return e; + } + + /// + /// 共通する辺をもつ2つのトライアングルから四角を形成する4つの頂点インデックスを返す + /// 頂点インデックスは[2][3]が共通する辺を示し、[0][1]は各トライアングルの残りのインデックス + /// v2 + + /// /|\ + /// v0 + | + v1 + /// \|/ + /// v3 + + /// + /// + /// + /// + public static int4 GetTrianglePairIndices(int3 tri1, int3 tri2) + { + // 共通の辺 + int2 e = GetCommonEdgeFromTrianglePair(tri1, tri2); + Debug.Assert((e.x > 0 || e.y > 0) && e.x != e.y); + + int4 r = new int4(0, 0, e.x, e.y); + for (int i = 0; i < 3; i++) + { + if (tri1[i] != e.x && tri1[i] != e.y) + r[0] = tri1[i]; + if (tri2[i] != e.x && tri2[i] != e.y) + r[1] = tri2[i]; + } + + return r; + } + + /// + /// トライアングルについて指定エッジ以外の頂点インデックスを返す + /// + /// + /// + /// + public static int GetUnuseTriangleIndex(int3 tri, int2 edge) + { + if (tri.x != edge.x && tri.x != edge.y) + return tri.x; + if (tri.y != edge.x && tri.y != edge.y) + return tri.y; + if (tri.z != edge.x && tri.z != edge.y) + return tri.z; + + return -1; + } + + /// + /// 共通するエッジをもつ2つのトライアングルのなす角を求める(ラジアン) + /// v2 + + /// /|\ + /// v0 + | + v1 + /// \|/ + /// v3 + + /// + /// + /// + /// + /// + /// ラジアン + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float GetTrianglePairAngle(float3 pos0, float3 pos1, float3 pos2, float3 pos3) + { + var va = pos3 - pos2; + var vb = pos0 - pos2; + var vc = pos1 - pos2; + + var n0 = math.cross(va, vb); + var n1 = math.cross(vc, va); + + float ang = Angle(n0, n1); + return ang; + } + + /// + /// トライアングルを反転させる + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int3 FlipTriangle(in int3 tri) + { + return tri.xzy; + } + + /// + /// トライアングルを包む球の中心と半径を求める + /// これは球からトライアングルがはみ出る事はないが完全に正確ではないので注意! + /// あくまで衝突判定のブロードフェーズなどで使用することが目的のもの + /// 正確性よりも速度を重視した実装となっている + /// + /// + /// + /// + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void GetTriangleSphere(float3 pos0, float3 pos1, float3 pos2, out float3 sc, out float sr) + { + float3 max = math.max(math.max(pos0, pos1), pos2); + float3 min = math.min(math.min(pos0, pos1), pos2); + sc = (min + max) * 0.5f; + sr = math.distance(min, max) * 0.5f; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float4x4 LocalToWorldMatrix(in float3 wpos, in quaternion wrot, in float3 wscl) + { + return Matrix4x4.TRS(wpos, wrot, wscl); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float4x4 WorldToLocalMatrix(in float3 wpos, in quaternion wrot, in float3 wscl) + { + return math.inverse(Matrix4x4.TRS(wpos, wrot, wscl)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float3 TransformPoint(in float3 pos, in float3 wpos, in quaternion wrot, in float3 wscl) + { + return math.transform(Matrix4x4.TRS(wpos, wrot, wscl), pos); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float3 TransformPoint(in float3 pos, in float4x4 m) + { + return math.transform(m, pos); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float3 TransformVector(in float3 vec, in float4x4 m) + { + return math.mul(m, new float4(vec, 0)).xyz; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float3 TransformDirection(in float3 dir, in float4x4 m) + { + float len = math.length(dir); + if (len > 0.0f) + return math.normalize(TransformVector(dir, m)) * len; + else + return dir; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float3 TransformNormal(in float3 dir, in float4x4 m, float3 errDir) + { + // 姿勢変換後に単位化する + return math.normalizesafe(TransformVector(dir, m), errDir); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static quaternion TransformRotation(in quaternion rot, in float4x4 m, in float3 normalTangentFlip) + { + ToNormalTangent(rot, out float3 nor, out float3 tan); + nor = math.mul(m, new float4(nor, 0)).xyz * normalTangentFlip.y; + tan = math.mul(m, new float4(tan, 0)).xyz * normalTangentFlip.z; + return quaternion.LookRotation(tan, nor); + } + + /// + /// 距離を空間変換する + /// 非一様スケールを考慮して各軸の平均値を返す + /// + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float TransformDistance(in float dist, in float4x4 localToWorldMatrix) + { + var dist3 = math.mul(localToWorldMatrix, new float4(dist, dist, dist, 0)).xyz; + return math.csum(dist3) / 3; // 平均化 + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void TransformPositionNormalTangent(in float3 tpos, in quaternion trot, in float3 tscl, ref float3 pos, ref float3 nor, ref float3 tan) + { + // position + pos *= tscl; + pos = math.mul(trot, pos); + pos += tpos; + + // normal + nor = math.mul(trot, nor); + + // tangent + tan = math.mul(trot, tan); + } + + /// + /// 長さをマトリックス空間に変換する + /// + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float TransformLength(float length, in float4x4 matrix) + { + return math.length(math.mul(matrix, new float4(length, length, length, 0)).xyz) / 1.73205f; + } + + // !!これはスケールが入るとうまく行かない + //[MethodImpl(MethodImplOptions.AggressiveInlining)] + //public static quaternion TransformRotation(in quaternion rot, in float4x4 localToWorldMatrix) + //{ + // return math.mul(rot, new quaternion(localToWorldMatrix)); + //} + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float3 InverseTransformPoint(in float3 pos, in float4x4 worldToLocalMatrix) + { + return math.transform(worldToLocalMatrix, pos); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float3 InverseTransformPoint(in float3 pos, in float3 wpos, in quaternion wrot, in float3 wscl) + { + return math.transform(math.inverse(Matrix4x4.TRS(wpos, wrot, wscl)), pos); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float3 InverseTransformVector(in float3 vec, in float4x4 worldToLocalMatrix) + { + return math.mul(worldToLocalMatrix, new float4(vec, 0)).xyz; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float3 InverseTransformVector(in float3 vec, in quaternion rot) + { + return math.mul(math.inverse(rot), vec); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float3 InverseTransformDirection(in float3 dir, in float4x4 worldToLocalMatrix) + { + float len = math.length(dir); + if (len > 0.0f) + return math.normalize(InverseTransformVector(dir, worldToLocalMatrix)) * len; + else + return dir; + } + + // !!これはスケールが入るとうまく行かない + //[MethodImpl(MethodImplOptions.AggressiveInlining)] + //public static quaternion InverseTransformRotation(in quaternion rot, in float4x4 worldToLocalMatrix) + //{ + // return math.mul(new quaternion(worldToLocalMatrix), rot); + //} + + /// + /// fromのローカル座標をtoのローカル座標に変換するmatrixを返す + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float4x4 Transform(in float4x4 fromLocalToWorldMatrix, in float4x4 toWorldToLocalMatrix) + { + return math.mul(toWorldToLocalMatrix, fromLocalToWorldMatrix); + } + + /// + /// 2つのマトリックスが等しいか判定する + /// + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool CompareMatrix(in float4x4 m1, in float4x4 m2) + { +#if true + var b4 = m1 == m2; + return math.all(b4.c0) && math.all(b4.c1) && math.all(b4.c2) && math.all(b4.c3); +#else + // ハッシュの方が早いかな + // ★ハッシュではすぐに衝突を起こすのでだめ! + return math.hash(m1) == math.hash(m2); +#endif + } + + /// + /// 2つの座標系が等しいか判定する + /// + /// + /// + /// + /// + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool CompareTransform(in float3 pos1, in quaternion rot1, in float3 scl1, in float3 pos2, in quaternion rot2, in float3 scl2) + { + return pos1.Equals(pos2) && rot1.Equals(rot2) && scl1.Equals(scl2); + } + + /// + /// 線分pqおよび三角形abcに対して、線分が三角形と交差しているかどうかを返す + /// 交差している場合は、交差点の重心(u,v,w)と線分の位置tを返す + /// + /// + /// + /// + /// + /// + /// 両面判定はtrue + /// + /// + /// + /// + /// + public static bool IntersectSegmentTriangle(in float3 p, in float3 q, float3 a, float3 b, float3 c, bool doubleSide, out float u, out float v, out float w, out float t) + { + t = 0.0f; + u = 0.0f; + v = 0.0f; + w = 0.0f; + + var ab = b - a; + var ac = c - a; + var qp = p - q; + + float3 n = math.cross(ab, ac); + + float d = math.dot(qp, n); + + // 水平は無効 + if (math.abs(d) < 1e-09f) + return false; + + if (doubleSide == false) + { + // 法線方向からの侵入のみ(オリジナル) + if (d <= 0.0f) + return false; + } + else if (d < 0.0f) + { + // 三角形の両面からの衝突を許可する + n = -n; + float3 x = b; + b = c; + c = x; + ab = b - a; + ac = c - a; + d = math.dot(qp, n); + } + + var ap = p - a; + t = math.dot(ap, n); + if (t < 0.0f) + return false; + if (t > d) + return false; + + float3 e = math.cross(qp, ap); + v = math.dot(ac, e); + if (v < 0.0f || v > d) + return false; + w = -math.dot(ab, e); + if (w < 0.0f || (v + w) > d) + return false; + + float ood = 1.0f / d; + t *= ood; + v *= ood; + w *= ood; + u = 1.0f - v - w; + + return true; + } + + /// + /// 線分pqおよび三角形abcに対して、線分が三角形と交差しているかどうかを返す + /// 交差している場合は、交差点の重心(u,v,w)と線分の位置tを返す + /// + /// + /// + /// + /// + /// + /// + public static bool IntersectSegmentTriangle(in float3 p, in float3 q, float3 a, float3 b, float3 c) + { + var ab = b - a; + var ac = c - a; + var qp = p - q; + + float3 n = math.cross(ab, ac); + + float d = math.dot(qp, n); + + // 水平は無効 + if (math.abs(d) < 1e-09f) + return false; + + if (d < 0.0f) + { + // 三角形の両面からの衝突を許可する + n = -n; + float3 x = b; + b = c; + c = x; + ab = b - a; + ac = c - a; + d = math.dot(qp, n); + } + + var ap = p - a; + var t = math.dot(ap, n); + if (t < 0.0f) + return false; + if (t > d) + return false; + + float3 e = math.cross(qp, ap); + var v = math.dot(ac, e); + if (v < 0.0f || v > d) + return false; + var w = -math.dot(ab, e); + if (w < 0.0f || (v + w) > d) + return false; + + return true; + } + + /// + /// 点と面の衝突判定 + /// 衝突した場合にその押し出し位置を計算して返す + /// + /// + /// + /// + /// + /// 平面までの距離。押し出された(衝突の)場合は0.0以下(マイナス) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float IntersectPointPlaneDist(in float3 planePos, in float3 planeDir, in float3 pos, out float3 outPos) + { + float3 v = pos - planePos; + + // 押出しベクトル + float3 gv = Project(v, planeDir); + var len = math.length(gv); + + if (math.dot(planeDir, v) < 0.0f) + { + // 押し出し発生 + // 押出し座標 + outPos = pos - gv; + + // 面までの距離をマイナスで返す + return -len; + //return 0.0f; + } + else + { + // 押し出し不要。何もしない + outPos = pos; + + // 面までの距離を返す(+) + return len; + } + } + + + /// + /// 光線と球が交差しているか判定する + /// 交差している場合は交差しているtの値および交差点dを返す + /// + /// 光線の始点 + /// 光線の方向|d|=1 + /// 球の位置 + /// 球の半径 + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool IntersectRaySphere(in float3 p, in float3 d, in float3 sc, in float sr, ref float t, ref float3 q) + { + float3 m = p - sc; + float b = math.dot(m, d); + float c = math.dot(m, m) - sr * sr; + // rの原点がsの外側にあり(c > 0),rがsから離れていく方向を指している場合(b > 0)に終了 + if (c > 0.0f && b > 0.0f) + return false; + float discr = b * b - c; + // 負の判定式は光線が球を外れていることに一致 + if (discr < 0.0f) + return false; + // これで光線は球と交差していることがわかり交差する最小のtを計算 + t = -b - math.sqrt(discr); + // tが負である場合、光線は球の内部から開始しているのでtをゼロにクランプ + if (t < 0.0f) + t = 0.0f; + q = p + t * d; + return true; + } + + /// + /// 点Cと線分abの間の距離の平方を返す + /// + /// + /// + /// + /// + public static float SqDistPointSegment(Vector3 a, Vector3 b, Vector3 c) + { + Vector3 ab = b - a; + Vector3 ac = c - a; + Vector3 bc = c - b; + float e = Vector3.Dot(ac, ab); + + // Cがabの外側に射影される場合を扱う + if (e <= 0) + return Vector3.Dot(ac, ac); + float f = Vector3.Dot(ab, ab); + if (e >= f) + return Vector3.Dot(bc, bc); + + // Cがab上に射影される場合を扱う + Develop.Assert(f != 0.0f); + return Vector3.Dot(ac, ac) - e * e / f; + } + + /// + /// 座標をPivotのローカル姿勢を保ちながらシフトさせる + /// 主に慣性シフト用 + /// + /// 移動前座標 + /// 移動前のシフト中心座標 + /// シフト移動量 + /// シフト回転量 + /// + public static float3 ShiftPosition(in float3 oldPos, in float3 oldPivotPosition, in float3 shiftVector, in quaternion shiftRotation) + { + float3 lpos = oldPos - oldPivotPosition; + lpos = math.mul(shiftRotation, lpos); + lpos += shiftVector; + return oldPivotPosition + lpos; + } + + //========================================================================================= + /// + /// 深さから重量を計算して返す + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float CalcMass(float depth) + { + var a = (1.0f - depth); + return 1.0f + a * a * Define.System.DepthMass; + } + + /// + /// 摩擦係数から逆重量を計算して返す + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float CalcInverseMass(float friction) + { + // 摩擦(0.0 ~ 1.0)により重量が増加する + float mass = 1.0f + friction * Define.System.FrictionMass; + + Develop.Assert(mass > 0.0f); + return 1.0f / mass; + } + + /// + /// 逆重量を計算して返す + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float CalcInverseMass(float friction, float depth) + { + float mass = 1.0f; + + // 摩擦(0.0 ~ 1.0)により重量を増加させる + mass += friction * Define.System.FrictionMass; + + // 深さにより重量を増加させる + //mass += (1.0f - depth) * Define.System.DepthMass; + var a = (1.0f - depth); + mass += a * a * Define.System.DepthMass; + + Develop.Assert(mass > 0.0f); + return 1.0f / mass; + } + + /// + /// 逆重量を計算して返す + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float CalcInverseMass(float friction, float depth, bool fix, float fixMass) + { + //return fix ? (1.0f / 100.0f) : CalcInverseMass(friction, depth); + //return fix ? (1.0f / 30.0f) : CalcInverseMass(friction, depth); + + return fix ? (1.0f / fixMass) : CalcInverseMass(friction, depth); + } + + /// + /// セルフコリジョン用の逆重量を計算して返す + /// 固定パーティクルはほとんど動かなくする + /// + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float CalcSelfCollisionInverseMass(float friction, bool fix, float clothMass) + { + float mass = fix ? Define.System.SelfCollisionFixedMass : 1.0f + friction * Define.System.SelfCollisionFrictionMass; + mass += clothMass * Define.System.SelfCollisionClothMass; + Develop.Assert(mass > 0.0f); + return 1.0f / mass; + } + + /// + /// 数をn分割して、指定インデックスの範囲を返します。 + /// 数は整数のみ。 + /// 例:100(dataLength)を5(divCount)分割した結果 + /// divIndex(0):0~20 + /// divIndex(1):20~40 + /// divIndex(2):40~60 + /// divIndex(3):60~80 + /// divIndex(4):80~100 + /// + /// ただし、数が分割数を下回る場合は範囲外のインデックスは-1となる + /// 例:3(dataLength)を5(divCount)分割した結果 + /// divIndex(0):0~1 + /// divIndex(1):1~2 + /// divIndex(2):2~3 + /// divIndex(3):-1~-1 + /// divIndex(4):-1~-1 + /// + /// + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int2 CalcSplitRange(int dataLength, int divCount, int divIndex) + { + if (dataLength <= 0) + return -1; + + if (dataLength < divCount) + { + if (divIndex < dataLength) + return new int2(divIndex, divIndex + 1); + else + return -1; + } + + float segment = (float)dataLength / divCount; + int start = (int)(segment * divIndex); + int end = (divIndex == divCount - 1) ? dataLength : (int)(segment * (divIndex + 1)); + return new int2(start, end); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static DataChunk GetWorkerChunk(int dataLenght, int workerCount, int workerIndex) + { + int2 range = CalcSplitRange(dataLenght, workerCount, workerIndex); + if (range.x < 0) + return DataChunk.Empty; + else + return new DataChunk(range.x, range.y - range.x); + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/Utility/Math/MathUtility.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Utility/Math/MathUtility.cs.meta new file mode 100644 index 00000000..bfe1bffa --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Utility/Math/MathUtility.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 7ad45eb87d191fb4890da353d511a024 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Utility/Math/MathUtility.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Utility/Math/MinimumData.cs b/Assets/MagicaCloth2/Scripts/Core/Utility/Math/MinimumData.cs new file mode 100644 index 00000000..5e229900 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Utility/Math/MinimumData.cs @@ -0,0 +1,57 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using System.Collections.Generic; + +namespace MagicaCloth2 +{ + /// + /// 最小距離のデータのみを保持するクラス + /// + /// + /// + public class MinimumData where T1 : unmanaged where T2 : unmanaged + { + T1 minDist; + T2 minData; + bool isValid = false; + + /// + /// データの追加。現在のデータより距離が短い場合のみ上書きする + /// + /// + /// + public void Add(T1 distance, T2 data) + { + if (isValid) + { + if (Comparer.Default.Compare(distance, minDist) < 0) + { + minDist = distance; + minData = data; + } + } + else + { + minDist = distance; + minData = data; + isValid = true; + } + } + + public void Clear() + { + isValid = false; + } + + + public bool IsValid => isValid; + public T1 MinDistance => minDist; + public T2 MinData => minData; + + public override string ToString() + { + return $"MinimumData. IsValid:{isValid}, minDist:{minDist}, minData:{minData}"; + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/Utility/Math/MinimumData.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Utility/Math/MinimumData.cs.meta new file mode 100644 index 00000000..28ae4958 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Utility/Math/MinimumData.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 334bdeb060898f14f811bc5b01ac3f19 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Utility/Math/MinimumData.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Utility/Mesh.meta b/Assets/MagicaCloth2/Scripts/Core/Utility/Mesh.meta new file mode 100644 index 00000000..2349209a --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Utility/Mesh.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: e1339b9964cd3cc4db9e724b185506c2 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/MagicaCloth2/Scripts/Core/Utility/Mesh/MeshUtility.cs b/Assets/MagicaCloth2/Scripts/Core/Utility/Mesh/MeshUtility.cs new file mode 100644 index 00000000..d99e041c --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Utility/Mesh/MeshUtility.cs @@ -0,0 +1,99 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using UnityEngine; + +namespace MagicaCloth2 +{ + public static class MeshUtility + { + /// + /// レンダラーからSharedMeshを取得する + /// + /// + /// + public static Mesh GetSharedMesh(Renderer ren) + { + if (ren == null) + return null; + + if (ren is SkinnedMeshRenderer) + { + var sren = ren as SkinnedMeshRenderer; + return sren.sharedMesh; + } + else + { + // mesh filter + if (!ren.TryGetComponent(out var filter)) + { + Debug.LogError("Not found MeshFilter!"); + return null; + } + + return filter.sharedMesh; + } + } + + /// + /// レンダラーにメッシュを設定する + /// + /// + /// + /// + public static bool SetMesh(Renderer ren, Mesh mesh, Transform[] skinBones = null) + { + if (ren is SkinnedMeshRenderer) + { + var sren = ren as SkinnedMeshRenderer; + sren.sharedMesh = mesh; + + if (skinBones != null && skinBones.Length > 0) + sren.bones = skinBones; + } + else + { + // mesh filter + if (!ren.TryGetComponent(out var filter)) + { + Debug.LogError("Not found MeshFilter!"); + return false; + } + + filter.mesh = mesh; + } + + return true; + } + + /// + /// このレンダラーが利用しているTransformの数を返す + /// この数は概算であり正確ではないので注意! + /// + /// + /// + public static int GetTransformCount(Renderer ren) + { + int tcnt = 0; + + if (ren) + { + // renderer + tcnt++; + + if (ren is SkinnedMeshRenderer) + { + var sren = ren as SkinnedMeshRenderer; + + // root bone + tcnt++; + + // skin bones + tcnt += sren.bones?.Length ?? 0; + } + } + + return tcnt; + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/Utility/Mesh/MeshUtility.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Utility/Mesh/MeshUtility.cs.meta new file mode 100644 index 00000000..c9d06bda --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Utility/Mesh/MeshUtility.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: b4de31f1b32056a4d868784716d5ff27 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Utility/Mesh/MeshUtility.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Utility/Misc.meta b/Assets/MagicaCloth2/Scripts/Core/Utility/Misc.meta new file mode 100644 index 00000000..126435d3 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Utility/Misc.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 881419a3fff203d4b9c3bdaa61adf5c7 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/MagicaCloth2/Scripts/Core/Utility/Misc/Develop.cs b/Assets/MagicaCloth2/Scripts/Core/Utility/Misc/Develop.cs new file mode 100644 index 00000000..ad8f7dbb --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Utility/Misc/Develop.cs @@ -0,0 +1,53 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using UnityEngine; + +namespace MagicaCloth2 +{ + /// + /// 開発用ユーティリティ + /// + public static class Develop + { + public static void Log(in object mes) + { + Debug.Log($"[MC2] {mes}"); + } + + public static void LogWarning(in object mes) + { + Debug.LogWarning($"[MC2] {mes}"); + } + + public static void LogError(in object mes) + { + Debug.LogError($"[MC2] {mes}"); + } + + [System.Diagnostics.Conditional("MC2_LOG")] + public static void DebugLog(in object mes) + { + Debug.Log($"[MC2 DEBUG] {mes}"); + } + + [System.Diagnostics.Conditional("MC2_DEBUG")] + public static void DebugLogWarning(in object mes) + { + Debug.LogWarning($"[MC2 DEBUG] {mes}"); + } + + [System.Diagnostics.Conditional("MC2_DEBUG")] + public static void DebugLogError(in object mes) + { + Debug.LogError($"[MC2 DEBUG] {mes}"); + } + + [System.Diagnostics.Conditional("MC2_DEBUG")] + public static void Assert(bool condition) + { + // 何故かメッセージを追加すると機能しない.. + Debug.Assert(condition); + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/Utility/Misc/Develop.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Utility/Misc/Develop.cs.meta new file mode 100644 index 00000000..9976e958 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Utility/Misc/Develop.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: e02e1cb346cdf1d4babc2bf1470dac90 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Utility/Misc/Develop.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Utility/Misc/StaticStringBuilder.cs b/Assets/MagicaCloth2/Scripts/Core/Utility/Misc/StaticStringBuilder.cs new file mode 100644 index 00000000..adbc829c --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Utility/Misc/StaticStringBuilder.cs @@ -0,0 +1,97 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using System.Text; + +namespace MagicaCloth2 +{ + /// + /// 静的StringBuilderクラス + /// + public class StaticStringBuilder + { + private static StringBuilder stringBuilder = new StringBuilder(1024); + + /// + /// StringBuilderのインスタンスを取得する + /// + public static StringBuilder Instance + { + get + { + return stringBuilder; + } + } + + /// + /// 内部をクリアする + /// + public static void Clear() + { + stringBuilder.Length = 0; + } + + /// + /// 与えられた文字を結合する + /// + /// + /// + public static StringBuilder Append(params object[] args) + { + for (int i = 0; i < args.Length; i++) + { + stringBuilder.Append(args[i]); + } + return stringBuilder; + } + + /// + /// 与えられた文字列を結合し、最後に改行コードを挿入する + /// + /// + /// + public static StringBuilder AppendLine(params object[] args) + { + for (int i = 0; i < args.Length; i++) + { + stringBuilder.Append(args[i]); + } + stringBuilder.Append("\n"); + return stringBuilder; + } + + /// + /// 改行を追加する + /// + /// + public static StringBuilder AppendLine() + { + stringBuilder.Append("\n"); + return stringBuilder; + } + + /// + /// 与えられた文字を結合して、結合文字列を返す + /// + /// + /// + public static string AppendToString(params object[] args) + { + stringBuilder.Length = 0; + for (int i = 0; i < args.Length; i++) + { + stringBuilder.Append(args[i]); + } + return stringBuilder.ToString(); + } + + /// + /// 文字列を返す + /// + /// + public static new string ToString() + { + return stringBuilder.ToString(); + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/Utility/Misc/StaticStringBuilder.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Utility/Misc/StaticStringBuilder.cs.meta new file mode 100644 index 00000000..2d12222f --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Utility/Misc/StaticStringBuilder.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 4d925c104701fe242b9f070700e73997 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Utility/Misc/StaticStringBuilder.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection.meta b/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection.meta new file mode 100644 index 00000000..501b18f7 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 05c459b696cc77144b66c9cfc2a404b6 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/DataChunk.cs b/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/DataChunk.cs new file mode 100644 index 00000000..544b0efd --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/DataChunk.cs @@ -0,0 +1,55 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp + +namespace MagicaCloth2 +{ + /// + /// 配列の断片を管理する + /// + public struct DataChunk + { + /// + /// 開始インデックス + /// + public int startIndex; + + /// + /// データ数 + /// + public int dataLength; + + public bool IsValid => dataLength > 0; + + public static DataChunk Empty + { + get + { + return new DataChunk(); + } + } + + public DataChunk(int sindex, int length) + { + startIndex = sindex; + dataLength = length; + } + + public DataChunk(int sindex) + { + startIndex = sindex; + dataLength = 1; + } + + public void Clear() + { + startIndex = 0; + dataLength = 0; + } + + public override string ToString() + { + return $"[startIndex={startIndex}, dataLength={dataLength}]"; + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/DataChunk.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/DataChunk.cs.meta new file mode 100644 index 00000000..e12396b5 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/DataChunk.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 1da73ff56787abd45804252538471bf6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/DataChunk.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/ExBitFlag16.cs b/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/ExBitFlag16.cs new file mode 100644 index 00000000..8bd4e88c --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/ExBitFlag16.cs @@ -0,0 +1,51 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using System.Runtime.CompilerServices; + +namespace MagicaCloth2 +{ + /// + /// 16ビットフラグ + /// + [System.Serializable] + public struct ExBitFlag16 + { + public ushort Value; + + public ExBitFlag16(ushort initialValue = 0) + { + Value = initialValue; + } + + public void Clear() + { + Value = 0; + } + + /// + /// フラグ設定(ビット直指定) + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void SetFlag(ushort flag, bool sw) + { + if (sw) + Value |= flag; + else + Value = (ushort)(Value & ~flag); + } + + /// + /// フラグ判定(ビット直指定) + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool IsSet(ushort flag) + { + return (Value & flag) != 0; + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/ExBitFlag16.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/ExBitFlag16.cs.meta new file mode 100644 index 00000000..1589cbf7 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/ExBitFlag16.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 82468a45671e5e1498d4df5c19611f32 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/ExBitFlag16.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/ExBitFlag8.cs b/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/ExBitFlag8.cs new file mode 100644 index 00000000..be9adb17 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/ExBitFlag8.cs @@ -0,0 +1,52 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using System.Runtime.CompilerServices; + +namespace MagicaCloth2 +{ + /// + /// 8ビットフラグ + /// + [System.Serializable] + public struct ExBitFlag8 + { + public byte Value; + + public ExBitFlag8(byte initialValue = 0) + { + Value = initialValue; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Clear() + { + Value = 0; + } + + /// + /// フラグ設定 + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void SetFlag(byte flag, bool sw) + { + if (sw) + Value |= flag; + else + Value = (byte)(Value & ~flag); + } + + /// + /// フラグ判定 + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool IsSet(byte flag) + { + return (Value & flag) != 0; + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/ExBitFlag8.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/ExBitFlag8.cs.meta new file mode 100644 index 00000000..ba873351 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/ExBitFlag8.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: eb16200a6206d394d9e12963263352b0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/ExBitFlag8.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/ExCostSortedList1.cs b/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/ExCostSortedList1.cs new file mode 100644 index 00000000..ee10fc2e --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/ExCostSortedList1.cs @@ -0,0 +1,73 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using System; +using System.Runtime.CompilerServices; +using UnityEngine; + +namespace MagicaCloth2 +{ + /// + /// 最も低いコストとデータを1つ格納するSortedList + /// コストは0以上でなければならない + /// 必ずコンストラクタでマイナスコストを指定してから利用すること + /// var dlist = new ExCostSortedList1(-1); + /// + public struct ExCostSortedList1 : IComparable + { + internal float cost; + internal int data; + + /// + /// 必ずマイナス距離で初期化すること + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public ExCostSortedList1(float invalidCost) + { + cost = invalidCost; + data = 0; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public ExCostSortedList1(float invalidCost, int initData) + { + cost = invalidCost; + data = initData; + } + + + public bool IsValid => cost >= 0.0f; + + public int Count => IsValid ? 1 : 0; + + public float Cost => cost; + + public int Data => data; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Add(float cost, int item) + { + Debug.Assert(cost >= 0.0f); + if (IsValid == false || cost < this.cost) + { + this.cost = cost; + data = item; + } + } + + public int CompareTo(ExCostSortedList1 other) + { + // コストの昇順 + if (cost != other.cost) + return cost < other.cost ? -1 : 1; + else + return 0; + } + + public override string ToString() + { + return $"({cost} : {data})"; + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/ExCostSortedList1.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/ExCostSortedList1.cs.meta new file mode 100644 index 00000000..2f4afc93 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/ExCostSortedList1.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: b8b3cd069c36d174ea801cadc4d95919 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/ExCostSortedList1.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/ExCostSortedList4.cs b/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/ExCostSortedList4.cs new file mode 100644 index 00000000..f8c1341a --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/ExCostSortedList4.cs @@ -0,0 +1,186 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using System.Runtime.CompilerServices; +using Unity.Collections; +using Unity.Mathematics; +using UnityEngine; + +namespace MagicaCloth2 +{ + /// + /// コストの昇順に4つまでデータを格納できる固定SortedList + /// コストは0以上でなければならない + /// 必ずコンストラクタでマイナスコストを指定してから利用すること + /// var dlist = new ExCostSortedList4(-1); + /// + public struct ExCostSortedList4 + { + internal float4 costs; + internal int4 data; + + /// + /// 必ずマイナス距離で初期化すること + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public ExCostSortedList4(float invalidCost) + { + costs = invalidCost; + data = 0; + } + + public int Count + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get + { + for (int i = 3; i >= 0; i--) + { + if (costs[i] >= 0.0f) + return i + 1; + } + + return 0; + } + } + + public bool IsValid => costs[0] >= 0.0f; + + public bool Add(float cost, int item) + { + Debug.Assert(cost >= 0.0f); + + // すでにデータが一杯で最大コストより上なら入らない + if (costs[3] >= 0.0f && cost > costs[3]) + return false; + + + // 距離の昇順で挿入する、最大数は4 + for (int i = 0; i < 4; i++) + { + float d = costs[i]; + if (d < 0.0f) + { + // 追加 + costs[i] = cost; + data[i] = item; + return true; + } + else if (cost < d) + { + // 挿入 + for (int j = 2; j >= i; j--) + { + costs[j + 1] = costs[j]; + data[j + 1] = data[j]; + } + costs[i] = cost; + data[i] = item; + return true; + } + } + + // 入らない + return false; + } + + //[MethodImpl(MethodImplOptions.AggressiveInlining)] + //public (float, int) Get(int index) + //{ + // return (costs[index], data[index]); + //} + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool Contains(int item) + { + for (int i = 0; i < 4; i++) + { + if (costs[i] >= 0.0f && data[i] == item) + return true; + } + return false; + } + + /// + /// データ内のアイテムを検索してその登録インデックスを返す。(-1=なし) + /// + /// + /// + public int indexOf(int item) + { + for (int i = 0; i < 4; i++) + { + if (costs[i] >= 0.0f && data[i] == item) + return i; + } + + return -1; + } + + /// + /// データ内のアイテムを削除しデータを1つ詰める + /// + /// + public void RemoveItem(int item) + { + int itemIndex = -1; + for (int i = 0; i < 4; i++) + { + if (costs[i] >= 0.0f && data[i] == item) + { + itemIndex = i; + break; + } + } + if (itemIndex < 0) + return; + + for (int j = itemIndex; j < 3; j++) + { + costs[j] = costs[j + 1]; + data[j] = data[j + 1]; + } + costs[3] = -1; + } + + /// + /// データ内の最小のコストを返す + /// + public float MinCost + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get + { + return costs[0]; + } + } + + /// + /// データ内の最大のコストを返す + /// + public float MaxCost + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get + { + for (int i = 3; i >= 0; i--) + { + if (costs[i] >= 0.0f) + return costs[i]; + } + return 0.0f; + } + } + + public override string ToString() + { + var s = new FixedString512Bytes(); + for (int i = 0; i < Count; i++) + { + s.Append($"({costs[i]} : {data[i]}) "); + } + return s.ToString(); + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/ExCostSortedList4.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/ExCostSortedList4.cs.meta new file mode 100644 index 00000000..0890ae7a --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/ExCostSortedList4.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 117c9e1f7003d1b418193a8ee6f8a850 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/ExCostSortedList4.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/ExNativeArray.cs b/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/ExNativeArray.cs new file mode 100644 index 00000000..7ada7e3d --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/ExNativeArray.cs @@ -0,0 +1,709 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using System; +using System.Collections.Generic; +using System.Text; +using Unity.Collections; +using Unity.Collections.LowLevel.Unsafe; +using Unity.Mathematics; +using UnityEngine; + +namespace MagicaCloth2 +{ + /// + /// 拡張可能なNativeArrayクラス + /// 領域が不足すると自動で拡張する + /// データはChankDataにより開始インデックスと長さが管理される + /// データは削除可能で削除された領域は管理され再利用される + /// 領域の管理が必要なためExSimpleNativeArrayに比べてやや重いので注意! + /// + /// + public class ExNativeArray : IDisposable where T : unmanaged + { + NativeArray nativeArray; + + List emptyChunks = new List(); + + int useCount; + + public void Dispose() + { + if (nativeArray.IsCreated) + { + nativeArray.Dispose(); + } + emptyChunks.Clear(); + useCount = 0; + } + + public bool IsValid => nativeArray.IsCreated; + + /// + /// NativeArrayの領域サイズ + /// 実際に利用されているサイズとは異なるので注意! + /// + public int Length => nativeArray.IsCreated ? nativeArray.Length : 0; + + /// + /// 実際に利用されているデータ数(最後のチャンクの最後尾+1) + /// + public int Count => useCount; + + //========================================================================================= + public ExNativeArray() + { + } + + public ExNativeArray(int emptyLength, bool create = false) : this() + { + if (emptyLength > 0) + { + nativeArray = new NativeArray(emptyLength, Allocator.Persistent); + var chunk = new DataChunk(0, emptyLength); + emptyChunks.Add(chunk); + + if (create) + { + // 領域を確保する + AddRange(emptyLength); + } + } + else if (create) + { + // Native配列のみ0で確保(主にジョブでのエラー対策) + nativeArray = new NativeArray(0, Allocator.Persistent); + } + } + + public ExNativeArray(int emptyLength, T fillData) : this(emptyLength) + { + if (emptyLength > 0) + Fill(fillData); + } + + public ExNativeArray(NativeArray dataArray) : this() + { + AddRange(dataArray); + } + + public ExNativeArray(T[] dataArray) : this() + { + AddRange(dataArray); + } + + //========================================================================================= +#if false + /// + /// 使用配列カウントを設定する + /// 有効数を書き換えすべてのデータを1つのチャンクとして使用中とする + /// かなり強力な機能なので扱いには注意すること! + /// + /// + public void SetUseCount(int count) + { + useCount = count; + emptyChunks.Clear(); + if (useCount > Length) + { + // 未使用領域を1つの空チャンクとして登録する + var chunk = new DataChunk(useCount, Length - useCount); + emptyChunks.Add(chunk); + } + } +#endif + + /// + /// 指定サイズの領域を追加しそのチャンクを返す + /// + /// + /// + public DataChunk AddRange(int dataLength) + { + // サイズ0対応 + if (dataLength == 0) + { + // 領域だけは0で確保する + if (nativeArray.IsCreated == false) + nativeArray = new NativeArray(0, Allocator.Persistent); + + return DataChunk.Empty; + } + + var chunk = GetEmptyChunk(dataLength); + + if (chunk.IsValid == false) + { + // 空きを増やす + int nowLength = Length; + int nextLength = Length + math.max(dataLength, nowLength); + if (nowLength == 0) + { + // 新規 + if (nativeArray.IsCreated) + nativeArray.Dispose(); + nativeArray = new NativeArray(nextLength, Allocator.Persistent); + chunk.dataLength = dataLength; + } + else + { + // 拡張 + var newNativeArray = new NativeArray(nextLength, Allocator.Persistent); + + // copy + NativeArray.Copy(nativeArray, newNativeArray, nowLength); + nativeArray.Dispose(); + nativeArray = newNativeArray; + + // data chunk + chunk.startIndex = nowLength; + chunk.dataLength = dataLength; + + int last = nowLength + dataLength; + if (last < nextLength) + { + var emptyChunk = new DataChunk(last, nextLength - last); + AddEmptyChunk(emptyChunk); + } + } + } + + // 使用量 + useCount = math.max(useCount, chunk.startIndex + chunk.dataLength); + + return chunk; + } + + public DataChunk AddRange(int dataLength, T fillData = default(T)) + { + var chunk = AddRange(dataLength); + Fill(chunk, fillData); + return chunk; + } + + public DataChunk AddRange(T[] array) + { + if (array == null || array.Length == 0) + return DataChunk.Empty; + + int dataLength = array.Length; + var chunk = AddRange(dataLength); + + // copy + NativeArray.Copy(array, 0, nativeArray, chunk.startIndex, dataLength); + + return chunk; + } + + public DataChunk AddRange(NativeArray narray, int length = 0) + { + if (narray.IsCreated == false || narray.Length == 0) + return DataChunk.Empty; + + int dataLength = length > 0 ? length : narray.Length; + var chunk = AddRange(dataLength); + // copy + NativeArray.Copy(narray, 0, nativeArray, chunk.startIndex, dataLength); + + return chunk; + } + + public DataChunk AddRange(ExNativeArray exarray) + { + return AddRange(exarray.GetNativeArray(), exarray.Count); + } + + public DataChunk AddRange(ExSimpleNativeArray exarray) + { + return AddRange(exarray.GetNativeArray(), exarray.Count); + } + + /// + /// 型は異なるが型のサイズは同じ配列を追加する。Vector3->float3など。 + /// + /// + /// + /// + public unsafe DataChunk AddRange(U[] array) where U : struct + { + if (array == null || array.Length == 0) + return DataChunk.Empty; + + int dstSize = UnsafeUtility.SizeOf(); + int dataLength = array.Length; + var chunk = AddRange(dataLength); + + ulong src_gcHandle; + void* src_p = UnsafeUtility.PinGCArrayAndGetDataAddress(array, out src_gcHandle); + byte* dst_p = (byte*)nativeArray.GetUnsafePtr(); + + UnsafeUtility.MemCpy(dst_p + chunk.startIndex * dstSize, src_p, dataLength * dstSize); + UnsafeUtility.ReleaseGCObject(src_gcHandle); + + return chunk; + } + + /// + /// 型は異なるが型のサイズは同じNativeArrayを追加する。Vector3->float3など。 + /// + /// + /// + /// + public DataChunk AddRange(NativeArray udata) where U : struct + { + if (udata.IsCreated == false || udata.Length == 0) + return DataChunk.Empty; + + int dataLength = udata.Length; + var chunk = AddRange(dataLength); + + // copy + NativeArray.Copy(udata.Reinterpret(), 0, nativeArray, chunk.startIndex, dataLength); + + return chunk; + } + + /// + /// 型もサイズも異なる配列を追加する。int[] -> int3[]など。 + /// データはそのままメモリコピーされる。例えばint[]からint3[]へ追加すると次のようになる。 + /// int[]{1, 2, 3, 4, 5, 6} => int3[]{{1, 2, 3}, {4, 5, 6}} + /// + /// + /// + /// + public unsafe DataChunk AddRangeTypeChange(U[] array) where U : struct + { + if (array == null || array.Length == 0) + return DataChunk.Empty; + + int srcSize = UnsafeUtility.SizeOf(); + int dstSize = UnsafeUtility.SizeOf(); + + int dataLength = (array.Length * srcSize) / dstSize; + var chunk = AddRange(dataLength); + + ulong src_gcHandle; + void* src_p = UnsafeUtility.PinGCArrayAndGetDataAddress(array, out src_gcHandle); + byte* dst_p = (byte*)nativeArray.GetUnsafePtr(); + + UnsafeUtility.MemCpy(dst_p + chunk.startIndex * dstSize, src_p, dataLength * dstSize); + UnsafeUtility.ReleaseGCObject(src_gcHandle); + + return chunk; + } + + /// + /// 型もサイズも異なる配列を部分的にコピーする。Vector4[] -> float3など。 + /// + /// + /// + /// + public unsafe DataChunk AddRangeStride(U[] array) where U : struct + { + if (array == null || array.Length == 0) + return DataChunk.Empty; + + int srcSize = UnsafeUtility.SizeOf(); + int dstSize = UnsafeUtility.SizeOf(); + int dataLength = array.Length; + var chunk = AddRange(dataLength); + + ulong src_gcHandle; + void* src_p = UnsafeUtility.PinGCArrayAndGetDataAddress(array, out src_gcHandle); + byte* dst_p = (byte*)nativeArray.GetUnsafePtr(); + int elementSize = math.min(srcSize, dstSize); + + UnsafeUtility.MemCpyStride(dst_p + chunk.startIndex * dstSize, dstSize, src_p, srcSize, elementSize, dataLength); + UnsafeUtility.ReleaseGCObject(src_gcHandle); + + return chunk; + } + + public DataChunk Add(T data) + { + var chunk = AddRange(1); + nativeArray[chunk.startIndex] = data; + return chunk; + } + + /// + /// 指定チャンクのデータ数を拡張し新しいチャンクを返す + /// 古いチャンクのデータは新しいチャンクにコピーされる + /// + /// + /// + /// + public DataChunk Expand(DataChunk c, int newDataLength) + { + Develop.Assert(c.IsValid); + if (c.IsValid == false) + return c; + if (newDataLength <= c.dataLength) + return c; + + // 新しい領域を確保する + var nc = AddRange(newDataLength); + + // 古い領域をコピーする + NativeArray.Copy(nativeArray, c.startIndex, nativeArray, nc.startIndex, c.dataLength); + + // 古い領域を開放する + Remove(c); + + return nc; + } + + /// + /// 指定チャンクのデータ数を拡張し新しいチャンクを返す + /// 古いチャンクのデータは新しいチャンクにコピーされる + /// + /// + /// + /// + public DataChunk ExpandAndFill(DataChunk c, int newDataLength, T fillData = default(T), T clearData = default(T)) + { + Develop.Assert(c.IsValid); + if (c.IsValid == false) + return c; + if (newDataLength <= c.dataLength) + return c; + + // 新しい領域を確保する + var nc = AddRange(newDataLength, fillData); + + // 古い領域をコピーする + NativeArray.Copy(nativeArray, c.startIndex, nativeArray, nc.startIndex, c.dataLength); + + // 古い領域を開放する + RemoveAndFill(c, clearData); + + return nc; + } + + public T[] ToArray() + { + return nativeArray.ToArray(); + } + + public void CopyTo(T[] array) + { + NativeArray.Copy(nativeArray, array); + } + + public void CopyTo(T[] array, int startIndex) + { + Debug.Assert(array != null); + NativeArray.Copy(nativeArray, startIndex, array, 0, array.Length); + } + + public void CopyTo(U[] array) where U : struct + { + NativeArray.Copy(nativeArray.Reinterpret(), array); + } + + public void CopyFrom(NativeArray array) + { + NativeArray.Copy(array, nativeArray); + } + + public void CopyFrom(T[] array, int startIndex) + { + Debug.Assert(array != null); + NativeArray.Copy(array, 0, nativeArray, startIndex, array.Length); + } + + public void CopyFrom(NativeArray array) where U : struct + { + NativeArray.Copy(array.Reinterpret(), nativeArray); + } + + public void CopyFrom(NativeArray array, int dstIndex, int length) where U : struct + { + NativeArray.Copy(array.Reinterpret(), 0, nativeArray, dstIndex, length); + } + + /// + /// 型もサイズも異なる配列にデータをコピーする。 + /// int3 -> int[]など + /// + /// + /// + public unsafe void CopyTypeChange(U[] array) where U : struct + { + int srcSize = UnsafeUtility.SizeOf(); + int dstSize = UnsafeUtility.SizeOf(); + int dataLength = (Length * srcSize) / dstSize; + + byte* src_p = (byte*)nativeArray.GetUnsafePtr(); + ulong dst_gcHandle; + void* dst_p = UnsafeUtility.PinGCArrayAndGetDataAddress(array, out dst_gcHandle); + + UnsafeUtility.MemCpy(dst_p, src_p, dataLength * dstSize); + UnsafeUtility.ReleaseGCObject(dst_gcHandle); + } + + /// + /// 型もサイズも異なる配列にデータを断片的にコピーする。 + /// float3 -> Vector4[]など。この場合はVector4にはxyzのみ書き込まれる。 + /// + /// + /// + public unsafe void CopyTypeChangeStride(U[] array) where U : struct + { + int srcSize = UnsafeUtility.SizeOf(); + int dstSize = UnsafeUtility.SizeOf(); + int dataLength = Length; + + byte* src_p = (byte*)nativeArray.GetUnsafePtr(); + ulong dst_gcHandle; + void* dst_p = UnsafeUtility.PinGCArrayAndGetDataAddress(array, out dst_gcHandle); + + int elementSize = srcSize; + + UnsafeUtility.MemCpyStride(dst_p, dstSize, src_p, srcSize, elementSize, dataLength); + UnsafeUtility.ReleaseGCObject(dst_gcHandle); + } + + /// + /// すぐに利用できる空領域のみ追加する + /// + /// + public void AddEmpty(int dataLength) + { + var chunk = AddRange(dataLength); + Remove(chunk); + } + + public void Remove(DataChunk chunk) + { + if (chunk.IsValid == false) + return; + + AddEmptyChunk(chunk); + + // 使用量の再計算 + if ((chunk.startIndex + chunk.dataLength) == useCount) + { + useCount = 0; + foreach (var echunk in emptyChunks) + { + useCount = math.max(useCount, echunk.startIndex); + } + } + } + + public void Remove(int index) + { + Remove(new DataChunk(index)); + } + + public void RemoveAndFill(DataChunk chunk, T clearData = default(T)) + { + Remove(chunk); + + // データクリア + // C# + //Parallel.For(0, chunk.dataLength, i => + //{ + // nativeArray[chunk.startIndex + i] = clearData; + //}); + //FillInternal(chunk.startIndex, chunk.dataLength, clearData); + Fill(chunk, clearData); + } + + public void Fill(T fillData = default(T)) + { + if (IsValid == false) + return; + + // C# + //Parallel.For(0, nativeArray.Length, i => + //{ + // nativeArray[i] = fillData; + //}); + FillInternal(0, nativeArray.Length, fillData); + } + + public void Fill(DataChunk chunk, T fillData = default(T)) + { + if (IsValid == false || chunk.IsValid == false) + return; + + // C# + //Parallel.For(0, chunk.dataLength, i => + //{ + // nativeArray[chunk.startIndex + i] = fillData; + //}); + FillInternal(chunk.startIndex, chunk.dataLength, fillData); + } + + unsafe void FillInternal(int start, int size, T fillData = default(T)) + { + //byte* dst_p = (byte*)nativeArray.GetUnsafePtr(); + void* dst_p = nativeArray.GetUnsafePtr(); + int index = start; + for (int i = 0; i < size; i++, index++) + { + UnsafeUtility.WriteArrayElement(dst_p, index, fillData); + } + } + + + public void Clear() + { + emptyChunks.Clear(); + useCount = 0; + + // empty chunk + if (IsValid && Length > 0) + { + var chunk = new DataChunk(0, Length); + emptyChunks.Add(chunk); + } + } + + public T this[int index] + { + get + { + return nativeArray[index]; + } + set + { + nativeArray[index] = value; + } + } + + public unsafe ref T GetRef(int index) + { + T* p = (T*)nativeArray.GetUnsafePtr(); + return ref *(p + index); + } + + //public unsafe ref T GetRef(int index) + //{ + // var span = new Span(nativeArray.GetUnsafePtr(), nativeArray.Length); + // return ref span[index]; + //} + + /// + /// Jobで利用する場合はこの関数でNativeArrayに変換して受け渡す + /// + /// + public NativeArray GetNativeArray() + { + return nativeArray; + } + + /// + /// Jobで利用する場合はこの関数でNativeArrayに変換して受け渡す(型変更あり) + /// + /// + /// + public NativeArray GetNativeArray() where U : struct + { + return nativeArray.Reinterpret(); + } + + //========================================================================================= + DataChunk GetEmptyChunk(int dataLength) + { + if (dataLength <= 0) + return new DataChunk(); + + for (int i = 0; i < emptyChunks.Count; i++) + { + var c = emptyChunks[i]; + if (dataLength == c.dataLength) + { + // このチャンクをすべて利用する + emptyChunks.RemoveAtSwapBack(i); + return c; + } + else if (dataLength < c.dataLength) + { + // このチャンクを一部利用する + var chunk = new DataChunk(); + chunk.startIndex = c.startIndex; + chunk.dataLength = dataLength; + c.startIndex += dataLength; + c.dataLength -= dataLength; + emptyChunks[i] = c; + return chunk; + } + } + + // 利用できるチャンクはなし + return new DataChunk(); + } + + void AddEmptyChunk(DataChunk chunk) + { + if (chunk.IsValid == false) + return; + + // 後ろに連結できる場所を探す + for (int i = 0; i < emptyChunks.Count; i++) + { + var c = emptyChunks[i]; + if ((c.startIndex + c.dataLength) == chunk.startIndex) + { + // ここに連結する + c.dataLength += chunk.dataLength; + chunk = c; + + // cを削除する + emptyChunks.RemoveAtSwapBack(i); + break; + } + } + + // 前に連結できる場所を探す + for (int i = 0; i < emptyChunks.Count; i++) + { + var c = emptyChunks[i]; + if (c.startIndex == (chunk.startIndex + chunk.dataLength)) + { + // ここに連結する + chunk.dataLength += c.dataLength; + + // cを削除する + emptyChunks.RemoveAtSwapBack(i); + break; + } + } + + // chunkを追加する + emptyChunks.Add(chunk); + } + + public override string ToString() + { + StringBuilder sb = new StringBuilder(); + + sb.AppendLine($"ExNativeArray Length:{Length} Count:{Count} IsValid:{IsValid}"); + sb.AppendLine("---- Datas[100] ----"); + if (IsValid) + { + for (int i = 0; i < Length && i < 100; i++) + { + sb.AppendLine(nativeArray[i].ToString()); + } + } + + sb.AppendLine("---- Empty Chunks ----"); + foreach (var c in emptyChunks) + { + sb.AppendLine(c.ToString()); + } + sb.AppendLine(); + + return sb.ToString(); + } + + public string ToSummary() + { + return $"ExNativeArray Length:{Length} Count:{Count} IsValid:{IsValid}"; + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/ExNativeArray.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/ExNativeArray.cs.meta new file mode 100644 index 00000000..41a0493b --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/ExNativeArray.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 10d8d6da3ac2b13489c729db68ef39ec +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/ExNativeArray.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/ExProcessingList.cs b/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/ExProcessingList.cs new file mode 100644 index 00000000..19b9240e --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/ExProcessingList.cs @@ -0,0 +1,80 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using System; +using Unity.Collections; +using Unity.Collections.LowLevel.Unsafe; + +namespace MagicaCloth2 +{ + /// + /// 1つのバッファに並列にデータを書き込めるようにするための構造。 + /// カウンターをアトミック操作することによりその開始インデックスを管理する。 + /// + /// + public unsafe class ExProcessingList : IDisposable, IValid where T : struct + { + /// + /// バッファの現在のデータ数をカウントするためのカウンター + /// + public NativeReference Counter; + + /// + /// データバッファ + /// + public NativeArray Buffer; + + //========================================================================================= + public void Dispose() + { + if (Counter.IsCreated) + Counter.Dispose(); + if (Buffer.IsCreated) + Buffer.Dispose(); + } + + public bool IsValid() + { + return Counter.IsCreated; + } + + //========================================================================================= + public ExProcessingList() + { + Counter = new NativeReference(Allocator.Persistent); + } + + //========================================================================================= + /// + /// キャパシティが収まるようにバッファを拡張する。 + /// すでに容量が確保できている場合は何もしない。 + /// + /// + public void UpdateBuffer(int capacity) + { + if (Buffer.IsCreated == false || Buffer.Length < capacity) + { + if (Buffer.IsCreated) + Buffer.Dispose(); + Buffer = new NativeArray(capacity, Allocator.Persistent); + } + } + + /// + /// ジョブスケジュール用のカウントintポインターを取得する + /// + /// + /// + public int* GetJobSchedulePtr() + { + return (int*)Counter.GetUnsafePtrWithoutChecks(); + } + + public override string ToString() + { + int counter = Counter.IsCreated ? Counter.Value : 0; + int bufferLength = Buffer.IsCreated ? Buffer.Length : 0; + return $"ExProcessingList BufferLength:{bufferLength} Counter:{counter}"; + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/ExProcessingList.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/ExProcessingList.cs.meta new file mode 100644 index 00000000..906ce0f6 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/ExProcessingList.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 5a3ca7c202548c1439db91f92cc30790 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/ExProcessingList.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/ExSimpleNativeArray.cs b/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/ExSimpleNativeArray.cs new file mode 100644 index 00000000..c675310e --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/ExSimpleNativeArray.cs @@ -0,0 +1,603 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using System; +using System.Text; +using Unity.Collections; +using Unity.Collections.LowLevel.Unsafe; +using Unity.Mathematics; +using UnityEngine; + +namespace MagicaCloth2 +{ + /// + /// サイズ拡張可能なNativeArray管理クラス + /// 領域が不足すると自動でサイズを拡張する + /// ただし領域の拡張のみで削除や領域の再利用はできない + /// + /// + public class ExSimpleNativeArray : IDisposable where T : unmanaged + { + NativeArray nativeArray; + + int count; + int length; + + //========================================================================================= + public ExSimpleNativeArray() + { + count = 0; + length = 0; + } + + /// + /// 領域を確保する + /// + /// + /// true=領域のみで利用カウントを進めない + public ExSimpleNativeArray(int dataLength, bool areaOnly = false) : this() + { + nativeArray = new NativeArray(dataLength, Allocator.Persistent); + length = dataLength; + if (areaOnly == false) + count = length; + } + + public ExSimpleNativeArray(T[] dataArray) : this() + { + Debug.Assert(dataArray != null); + nativeArray = new NativeArray(dataArray, Allocator.Persistent); + length = dataArray.Length; + count = length; + } + + public ExSimpleNativeArray(NativeArray array) : this() + { + Debug.Assert(array.IsCreated); + nativeArray = new NativeArray(array, Allocator.Persistent); + length = array.Length; + count = length; + } + + public ExSimpleNativeArray(NativeList array) : this() + { + Debug.Assert(array.IsCreated); + nativeArray = new NativeArray(array.AsArray(), Allocator.Persistent); + length = array.Length; + count = length; + } + + public ExSimpleNativeArray(SerializationData sdata) + { + Deserialize(sdata); + } + + public void Dispose() + { + if (nativeArray.IsCreated) + { + nativeArray.Dispose(); + } + count = 0; + length = 0; + } + + public bool IsValid + { + get + { + return nativeArray.IsCreated; + } + } + + /// + /// 実際に使用されている要素数 + /// + public int Count => count; + + /// + /// 確保されている配列の要素数 + /// + public int Length => length; + + /// + /// 使用配列カウントを設定する + /// + /// + public void SetCount(int newCount) + { + Debug.Assert(newCount <= length && newCount >= 0); + count = newCount; + } + + //========================================================================================= + /// + /// 領域のみ拡張する + /// すでにその長さの領域が確保されている場合は何もしない + /// + /// + public void SetLength(int newLength) + { + if (newLength > length) + Expand(newLength - length, force: true, copy: true); + } + + /// + /// サイズ分の空データを追加する + /// + /// + public void AddRange(int dataLength) + { + Expand(dataLength); + count += dataLength; + } + + /// + /// 配列データを追加する + /// + /// + public void AddRange(T[] dataArray) + { + Debug.Assert(dataArray != null); + + if (length == 0) + { + if (nativeArray.IsCreated) + nativeArray.Dispose(); + + nativeArray = new NativeArray(dataArray, Allocator.Persistent); + length = dataArray.Length; + count = length; + } + else + { + int dataLength = dataArray.Length; + Expand(dataLength); + // copy + NativeArray.Copy(dataArray, 0, nativeArray, count, dataLength); + count += dataLength; + } + } + + /// + /// 配列データを追加する + /// + /// + public void AddRange(T[] dataArray, int cnt) + { + Debug.Assert(dataArray != null); + + if (length == 0) + { + if (nativeArray.IsCreated) + nativeArray.Dispose(); + + nativeArray = new NativeArray(cnt, Allocator.Persistent); + // copy + NativeArray.Copy(dataArray, 0, nativeArray, 0, cnt); + length = cnt; + count = length; + } + else + { + int dataLength = cnt; + Expand(dataLength); + // copy + NativeArray.Copy(dataArray, 0, nativeArray, count, dataLength); + count += dataLength; + } + } + + /// + /// 領域を確保し設定値で埋める(それなりのコストが発生するので注意!) + /// + /// + /// + public void AddRange(int dataLength, T fillData = default(T)) + { + Expand(dataLength); + Fill(count, dataLength, fillData); + count += dataLength; + } + + public void AddRange(NativeArray narray) + { + Debug.Assert(narray.IsCreated); + + if (length == 0) + { + if (nativeArray.IsCreated) + nativeArray.Dispose(); + + nativeArray = new NativeArray(narray, Allocator.Persistent); + length = narray.Length; + count = length; + } + else + { + int dataLength = narray.Length; + Expand(dataLength); + // copy + NativeArray.Copy(narray, 0, nativeArray, count, dataLength); + count += dataLength; + } + } + + public void AddRange(NativeArray narray, int start, int length) + { + if (length > 0) + { + Expand(length); + NativeArray.Copy(narray, start, nativeArray, count, length); + count += length; + } + } + + public void AddRange(NativeList nlist) + { + Debug.Assert(nlist.IsCreated); + AddRange(nlist.AsArray()); + } + + public void AddRange(ExSimpleNativeArray exarray) + { + AddRange(exarray.GetNativeArray()); + } + + /// + /// 型は異なるが型のサイズは同じ配列を追加する。Vector3->float3など。 + /// + /// + /// + /// + public unsafe void AddRange(U[] array) where U : struct + { + Debug.Assert(array != null); + + int dataLength = array.Length; + Expand(dataLength); + + // copy + int dstSize = UnsafeUtility.SizeOf(); + ulong src_gcHandle; + void* src_p = UnsafeUtility.PinGCArrayAndGetDataAddress(array, out src_gcHandle); + byte* dst_p = (byte*)nativeArray.GetUnsafePtr(); + UnsafeUtility.MemCpy(dst_p + count * dstSize, src_p, dataLength * dstSize); + UnsafeUtility.ReleaseGCObject(src_gcHandle); + count += dataLength; + } + + /// + /// 型もサイズも異なる配列を追加する。int[] -> int3[]など。 + /// データはそのままメモリコピーされる。例えばint[]からint3[]へ追加すると次のようになる。 + /// int[]{1, 2, 3, 4, 5, 6} => int3[]{{1, 2, 3}, {4, 5, 6}} + /// + /// + /// + /// + public unsafe void AddRangeTypeChange(U[] array) where U : struct + { + Debug.Assert(array != null); + + int srcSize = UnsafeUtility.SizeOf(); + int dstSize = UnsafeUtility.SizeOf(); + int dataLength = (array.Length * srcSize) / dstSize; + + Expand(dataLength); + + ulong src_gcHandle; + void* src_p = UnsafeUtility.PinGCArrayAndGetDataAddress(array, out src_gcHandle); + byte* dst_p = (byte*)nativeArray.GetUnsafePtr(); + + UnsafeUtility.MemCpy(dst_p + count * dstSize, src_p, dataLength * dstSize); + UnsafeUtility.ReleaseGCObject(src_gcHandle); + count += dataLength; + } + + public unsafe void AddRangeTypeChange(NativeArray array) where U : struct + { + Debug.Assert(array.IsCreated); + + int srcSize = UnsafeUtility.SizeOf(); + int dstSize = UnsafeUtility.SizeOf(); + int dataLength = (array.Length * srcSize) / dstSize; + + Expand(dataLength); + + byte* src_p = (byte*)array.GetUnsafePtr(); + byte* dst_p = (byte*)nativeArray.GetUnsafePtr(); + + UnsafeUtility.MemCpy(dst_p + count * dstSize, src_p, dataLength * dstSize); + count += dataLength; + } + + /// + /// 型もサイズも異なる配列を部分的にコピーする。Vector4[] -> float3など。 + /// + /// + /// + /// + public unsafe void AddRangeStride(U[] array) where U : struct + { + Debug.Assert(array != null); + int dataLength = array.Length; + Expand(dataLength); + + int srcSize = UnsafeUtility.SizeOf(); + int dstSize = UnsafeUtility.SizeOf(); + + ulong src_gcHandle; + void* src_p = UnsafeUtility.PinGCArrayAndGetDataAddress(array, out src_gcHandle); + byte* dst_p = (byte*)nativeArray.GetUnsafePtr(); + int elementSize = math.min(srcSize, dstSize); + + UnsafeUtility.MemCpyStride(dst_p + count * dstSize, dstSize, src_p, srcSize, elementSize, dataLength); + UnsafeUtility.ReleaseGCObject(src_gcHandle); + count += dataLength; + } + + public void Add(T data) + { + if (Length == 0) + { + // ある程度のバッファを確保 + Expand(16); + } + else if (count == Length) + { + // 倍に拡張する + Expand(Length); + } + + nativeArray[count] = data; + count++; + } + + public T[] ToArray() + { + return nativeArray.ToArray(); + } + + public void CopyTo(T[] array) + { + NativeArray.Copy(nativeArray, array); + } + + public void CopyTo(U[] array) where U : struct + { + NativeArray.Copy(nativeArray.Reinterpret(), array); + } + + /// + /// 型もサイズも異なる配列にデータをコピーする。 + /// int3 -> int[]など + /// + /// + /// + public unsafe void CopyToWithTypeChange(U[] array) where U : struct + { + int srcSize = UnsafeUtility.SizeOf(); + int dstSize = UnsafeUtility.SizeOf(); + int dataLength = (Length * srcSize) / dstSize; + + byte* src_p = (byte*)nativeArray.GetUnsafePtr(); + ulong dst_gcHandle; + void* dst_p = UnsafeUtility.PinGCArrayAndGetDataAddress(array, out dst_gcHandle); + + UnsafeUtility.MemCpy(dst_p, src_p, dataLength * dstSize); + UnsafeUtility.ReleaseGCObject(dst_gcHandle); + } + + /// + /// 型もサイズも異なる配列にデータを断片的にコピーする。 + /// float3 -> Vector4[]など。この場合はVector4にはxyzのみ書き込まれる。 + /// + /// + /// + public unsafe void CopyToWithTypeChangeStride(U[] array) where U : struct + { + int srcSize = UnsafeUtility.SizeOf(); + int dstSize = UnsafeUtility.SizeOf(); + int dataLength = Length; + + byte* src_p = (byte*)nativeArray.GetUnsafePtr(); + ulong dst_gcHandle; + void* dst_p = UnsafeUtility.PinGCArrayAndGetDataAddress(array, out dst_gcHandle); + + int elementSize = srcSize; + + UnsafeUtility.MemCpyStride(dst_p, dstSize, src_p, srcSize, elementSize, dataLength); + UnsafeUtility.ReleaseGCObject(dst_gcHandle); + } + + public void CopyFrom(NativeArray array) + { + NativeArray.Copy(array, nativeArray); + } + + public void CopyFrom(NativeArray array) where U : struct + { + NativeArray.Copy(array.Reinterpret(), nativeArray); + } + + public unsafe void CopyFromWithTypeChangeStride(NativeArray array) where U : struct + { + int srcSize = UnsafeUtility.SizeOf(); + int dstSize = UnsafeUtility.SizeOf(); + int dataLength = array.Length; + + byte* src_p = (byte*)array.GetUnsafePtr(); + byte* dst_p = (byte*)nativeArray.GetUnsafePtr(); + + int elementSize = dstSize; + UnsafeUtility.MemCpyStride(dst_p, dstSize, src_p, srcSize, elementSize, dataLength); + } + + /// + /// 設定値で埋める(それなりのコストが発生するので注意!) + /// + /// + /// + /// + public void Fill(int startIndex, int dataLength, T fillData = default(T)) + { + // C# + //Parallel.For(0, dataLength, i => + //{ + // nativeArray[startIndex + i] = fillData; + //}); + FillInternal(startIndex, dataLength, fillData); + } + + unsafe void FillInternal(int start, int size, T fillData = default(T)) + { + //byte* dst_p = (byte*)nativeArray.GetUnsafePtr(); + void* dst_p = nativeArray.GetUnsafePtr(); + int index = start; + for (int i = 0; i < size; i++, index++) + { + UnsafeUtility.WriteArrayElement(dst_p, index, fillData); + } + } + + + public T this[int index] + { + get + { + return nativeArray[index]; + } + set + { + nativeArray[index] = value; + } + } + + /// + /// Jobで利用する場合はこの関数でNativeArrayに変換して受け渡す + /// + /// + public NativeArray GetNativeArray() + { + return nativeArray; + } + + /// + /// Jobで利用する場合はこの関数でNativeArrayに変換して受け渡す(型変更あり) + /// + /// + /// + public NativeArray GetNativeArray() where U : struct + { + return nativeArray.Reinterpret(); + } + + //========================================================================================= + /// + /// 領域を拡張する(必要がなければ何もしない) + /// + /// + /// 強制的に領域を追加 + /// 古いデータをコピーするかどうか + void Expand(int dataLength, bool force = false, bool copy = true) + { + int newlength = force ? length + dataLength : count + dataLength; + + if (length == 0) + { + if (nativeArray.IsCreated) + nativeArray.Dispose(); + + nativeArray = new NativeArray(dataLength, Allocator.Persistent); + length = dataLength; + } + else if (newlength > Length) + { + // 拡張 + var newNativeArray = new NativeArray(newlength, Allocator.Persistent); + + // copy + if (copy) + { + // コピーは使用分だけ + NativeArray.Copy(nativeArray, newNativeArray, count); + } + + nativeArray.Dispose(); + nativeArray = newNativeArray; + length = newlength; + } + } + + public override string ToString() + { + StringBuilder sb = new StringBuilder(); + + sb.AppendLine($"ExSimpleNativeArray Length:{Length} Count:{Count} IsValid:{IsValid}"); + sb.AppendLine("---- Datas[~100] ----"); + if (IsValid) + { + for (int i = 0; i < Length && i < 100; i++) + { + sb.AppendLine(nativeArray[i].ToString()); + } + } + + return sb.ToString(); + } + + //========================================================================================= + /// + /// シリアライズデータ + /// + [System.Serializable] + public class SerializationData + { + public int count; + public int length; + public byte[] arrayBytes; + } + + /// + /// シリアライズする + /// + /// + public SerializationData Serialize() + { + var data = new SerializationData(); + data.count = count; + data.length = length; + if (nativeArray.IsCreated && nativeArray.Length > 0) + { + data.arrayBytes = nativeArray.MC2ToRawBytes(); + } + + return data; + } + + /// + /// デシリアライズする + /// + /// + /// + public bool Deserialize(SerializationData data) + { + try + { + Dispose(); + count = data.count; + length = data.length; + if (data.length > 0 && data.arrayBytes != null) + { + nativeArray = NativeArrayExtensions.MC2FromRawBytes(data.arrayBytes, Allocator.Persistent); + } + return true; + } + catch (Exception exception) + { + Debug.LogException(exception); + return false; + } + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/ExSimpleNativeArray.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/ExSimpleNativeArray.cs.meta new file mode 100644 index 00000000..f00fdbd3 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/ExSimpleNativeArray.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 5184cf224e308d044a655a8da0580401 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/ExSimpleNativeArray.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/ExTransformAccessArray.cs b/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/ExTransformAccessArray.cs new file mode 100644 index 00000000..19bd0a80 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/ExTransformAccessArray.cs @@ -0,0 +1,210 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using System; +using System.Collections.Generic; +using UnityEngine; +using UnityEngine.Jobs; + +namespace MagicaCloth2 +{ + /// + /// 固定インデックス型の固定インデックスTransformAccessArray管理クラス + /// 一度確保したインデックスはズレない(ここ重要) + /// 同じトランスフォームに関しては参照カウンタでまとめる(TransformAccessArrayは重複を許さないため) + /// + public class ExTransformAccessArray : IDisposable + { + TransformAccessArray transformArray; + + /// + /// ネイティブリストの配列数 + /// ※ジョブでエラーが出ないように事前に確保しておく + /// + int nativeLength; + + /// + /// 空インデックススタック + /// + Queue emptyStack; + + /// + /// 使用インデックス辞書 + /// + Dictionary useIndexDict; + + /// + /// トランスフォームインデックス辞書 + /// + Dictionary indexDict; + + /// + /// トランスフォーム参照カウンタ辞書 + /// + Dictionary referenceDict; + + //========================================================================================= + public ExTransformAccessArray(int capacity, int desiredJobCount = -1) + { + transformArray = new TransformAccessArray(capacity, desiredJobCount); + nativeLength = transformArray.length; + + emptyStack = new Queue(capacity); + useIndexDict = new Dictionary(capacity); + indexDict = new Dictionary(capacity); + referenceDict = new Dictionary(capacity); + } + + public void Dispose() + { + if (transformArray.isCreated) + transformArray.Dispose(); + emptyStack.Clear(); + useIndexDict.Clear(); + indexDict.Clear(); + referenceDict.Clear(); + nativeLength = 0; + } + + /// + /// TransformAccessArrayを取得する + /// + /// + public TransformAccessArray GetTransformAccessArray() + { + return transformArray; + } + + /// データ追加 + /// 追加したインデックスを返す + /// + /// + /// + public int Add(Transform element) + { + int index = 0; + + MagicaObjectId id = element.GetMagicaId(); + + if (referenceDict.ContainsKey(id)) + { + // 参照カウンタ+ + referenceDict[id] = referenceDict[id] + 1; + return indexDict[id]; + } + + if (emptyStack.Count > 0) + { + // 再利用 + index = emptyStack.Dequeue(); + transformArray[index] = element; + } + else + { + // 新規 + index = transformArray.length; + transformArray.Add(element); + } + useIndexDict.Add(index, id); + indexDict.Add(id, index); + referenceDict.Add(id, 1); + nativeLength = transformArray.length; + + return index; + } + + /// + /// データ削除 + /// 削除されたインデックスは再利用される + /// + /// + public void Remove(int index) + { + if (useIndexDict.ContainsKey(index)) + { + MagicaObjectId id = useIndexDict[index]; + int cnt = referenceDict[id] - 1; + if (cnt > 0) + { + // 参照カウンタ- + referenceDict[id] = cnt; + return; + } + + // 削除 + transformArray[index] = null; + emptyStack.Enqueue(index); + useIndexDict.Remove(index); + indexDict.Remove(id); + referenceDict.Remove(id); + nativeLength = transformArray.length; + } + } + + public bool Exist(int index) + { + return useIndexDict.ContainsKey(index); + } + + public bool Exist(Transform element) + { + if (element == null) + return false; + return indexDict.ContainsKey(element.GetMagicaId()); + } + + /// + /// データ使用量 + /// + public int Count + { + get + { + return useIndexDict.Count; + } + } + + /// + /// データ配列数 + /// + public int Length + { + get + { + return nativeLength; + } + } + + public Transform this[int index] + { + get + { + return transformArray[index]; + } + } + + public int GetIndex(Transform element) + { + if (element == null) + return -1; + MagicaObjectId id = element.GetMagicaId(); + if (indexDict.ContainsKey(id)) + return indexDict[id]; + else + return -1; + } + + public void Clear() + { + // 配列数はそのままにクリアする + foreach (var index in useIndexDict.Keys) + emptyStack.Enqueue(index); + useIndexDict.Clear(); + for (int i = 0, cnt = Length; i < cnt; i++) + transformArray[i] = null; + indexDict.Clear(); + referenceDict.Clear(); + nativeLength = 0; + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/ExTransformAccessArray.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/ExTransformAccessArray.cs.meta new file mode 100644 index 00000000..b3db47a1 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/ExTransformAccessArray.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 01fb00afd02fc7f48bfe4f6519f7d358 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/ExTransformAccessArray.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/FixedList128BytesExtensions.cs b/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/FixedList128BytesExtensions.cs new file mode 100644 index 00000000..5faa7ec6 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/FixedList128BytesExtensions.cs @@ -0,0 +1,117 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using System; +using System.Runtime.CompilerServices; +using Unity.Collections; +using UnityEngine; + +namespace MagicaCloth2 +{ + //[BurstCompatible] + public static class FixedList128BytesExtensions + { + //===================================================================== + // Common + //===================================================================== + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool MC2IsCapacity(ref this FixedList128Bytes fixedList) where T : unmanaged, IEquatable + { + return fixedList.Length >= fixedList.Capacity; + } + + //===================================================================== + // Set + //===================================================================== + /// + /// データが存在しない場合のみ追加する + /// + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void MC2Set(ref this FixedList128Bytes fixedList, T item) where T : unmanaged, IEquatable + { + if (fixedList.Contains(item) == false) + { + fixedList.Add(item); + } + } + + /// + /// データが存在しない場合のみ追加する + /// すでに容量が一杯の場合は警告を表示し追加しない。 + /// + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void MC2SetLimit(ref this FixedList128Bytes fixedList, T item) where T : unmanaged, IEquatable + { + if (fixedList.Length >= fixedList.Capacity) + { + Debug.LogWarning($"FixedSet128.Limit!:{fixedList.Capacity}"); + return; + } + if (fixedList.Contains(item) == false) + { + fixedList.Add(item); + } + } + + /// + /// リストからデータを検索して削除する + /// 削除領域にはリストの最後のデータが移動する(SwapBack) + /// + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void MC2RemoveItemAtSwapBack(ref this FixedList128Bytes fixedList, T item) where T : unmanaged, IEquatable + { + for (int i = 0; i < fixedList.Length; i++) + { + if (fixedList.ElementAt(i).Equals(item)) + { + fixedList.RemoveAtSwapBack(i); + break; + } + } + } + + //===================================================================== + // Stack + //===================================================================== + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void MC2Push(ref this FixedList128Bytes fixedList, T item) where T : unmanaged, IEquatable + { + fixedList.Add(item); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static T MC2Pop(ref this FixedList128Bytes fixedList) where T : unmanaged, IEquatable + { + int index = fixedList.Length - 1; + T item = fixedList[index]; + fixedList.RemoveAt(index); + return item; + } + + //===================================================================== + // Queue + //===================================================================== + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void MC2Enqueue(ref this FixedList128Bytes fixedList, T item) where T : unmanaged, IEquatable + { + fixedList.Add(item); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static T MC2Dequque(ref this FixedList128Bytes fixedList) where T : unmanaged, IEquatable + { + T item = fixedList[0]; + fixedList.RemoveAt(0); + return item; + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/FixedList128BytesExtensions.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/FixedList128BytesExtensions.cs.meta new file mode 100644 index 00000000..8d85a3f0 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/FixedList128BytesExtensions.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: a5001a2e03a42e64cade535d198c1e91 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/FixedList128BytesExtensions.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/FixedList32BytesExtensions.cs b/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/FixedList32BytesExtensions.cs new file mode 100644 index 00000000..43707fcb --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/FixedList32BytesExtensions.cs @@ -0,0 +1,117 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using System; +using System.Runtime.CompilerServices; +using Unity.Collections; +using UnityEngine; + +namespace MagicaCloth2 +{ + public static class FixedList32BytesExtensions + { + //===================================================================== + // Common + //===================================================================== + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool MC2IsCapacity(ref this FixedList32Bytes fixedList) where T : unmanaged, IEquatable + { + return fixedList.Length >= fixedList.Capacity; + } + + //===================================================================== + // Set + //===================================================================== + /// + /// データが存在しない場合のみ追加する + /// 容量がオーバーすると例外が発生する + /// + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void MC2Set(ref this FixedList32Bytes fixedList, T item) where T : unmanaged, IEquatable + { + if (fixedList.Contains(item) == false) + { + fixedList.Add(item); + } + } + + /// + /// データが存在しない場合のみ追加する + /// すでに容量が一杯の場合は警告を表示し追加しない。 + /// + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void MC2SetLimit(ref this FixedList32Bytes fixedList, T item) where T : unmanaged, IEquatable + { + if (fixedList.Length >= fixedList.Capacity) + { + Debug.LogWarning($"FixedSet32.Limit!:{fixedList.Capacity}"); + return; + } + if (fixedList.Contains(item) == false) + { + fixedList.Add(item); + } + } + + /// + /// リストからデータを検索して削除する + /// 削除領域にはリストの最後のデータが移動する(SwapBack) + /// + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void MC2RemoveItemAtSwapBack(ref this FixedList32Bytes fixedList, T item) where T : unmanaged, IEquatable + { + for (int i = 0; i < fixedList.Length; i++) + { + if (fixedList.ElementAt(i).Equals(item)) + { + fixedList.RemoveAtSwapBack(i); + break; + } + } + } + + //===================================================================== + // Stack + //===================================================================== + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void MC2Push(ref this FixedList32Bytes fixedList, T item) where T : unmanaged, IEquatable + { + fixedList.Add(item); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static T MC2Pop(ref this FixedList32Bytes fixedList) where T : unmanaged, IEquatable + { + int index = fixedList.Length - 1; + T item = fixedList[index]; + fixedList.RemoveAt(index); + return item; + } + + //===================================================================== + // Queue + //===================================================================== + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void MC2Enqueue(ref this FixedList32Bytes fixedList, T item) where T : unmanaged, IEquatable + { + fixedList.Add(item); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static T MC2Dequque(ref this FixedList32Bytes fixedList) where T : unmanaged, IEquatable + { + T item = fixedList[0]; + fixedList.RemoveAt(0); + return item; + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/FixedList32BytesExtensions.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/FixedList32BytesExtensions.cs.meta new file mode 100644 index 00000000..0afafc60 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/FixedList32BytesExtensions.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 5876be4e9da8a2943b26b98bbeb9cb22 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/FixedList32BytesExtensions.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/FixedList4096BytesExtensions.cs b/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/FixedList4096BytesExtensions.cs new file mode 100644 index 00000000..8e327769 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/FixedList4096BytesExtensions.cs @@ -0,0 +1,117 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using System; +using System.Runtime.CompilerServices; +using Unity.Collections; +using UnityEngine; + +namespace MagicaCloth2 +{ + //[BurstCompatible] + public static class FixedList4096BytesExtensions + { + //===================================================================== + // Common + //===================================================================== + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool MC2IsCapacity(ref this FixedList4096Bytes fixedList) where T : unmanaged, IEquatable + { + return fixedList.Length >= fixedList.Capacity; + } + + //===================================================================== + // Set + //===================================================================== + /// + /// データが存在しない場合のみ追加する + /// + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void MC2Set(ref this FixedList4096Bytes fixedList, T item) where T : unmanaged, IEquatable + { + if (fixedList.Contains(item) == false) + { + fixedList.Add(item); + } + } + + /// + /// データが存在しない場合のみ追加する + /// すでに容量が一杯の場合は警告を表示し追加しない。 + /// + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void MC2SetLimit(ref this FixedList4096Bytes fixedList, T item) where T : unmanaged, IEquatable + { + if (fixedList.Length >= fixedList.Capacity) + { + Debug.LogWarning($"FixedSet4096.Limit!:{fixedList.Capacity}"); + return; + } + if (fixedList.Contains(item) == false) + { + fixedList.Add(item); + } + } + + /// + /// リストからデータを検索して削除する + /// 削除領域にはリストの最後のデータが移動する(SwapBack) + /// + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void MC2RemoveItemAtSwapBack(ref this FixedList4096Bytes fixedList, T item) where T : unmanaged, IEquatable + { + for (int i = 0; i < fixedList.Length; i++) + { + if (fixedList.ElementAt(i).Equals(item)) + { + fixedList.RemoveAtSwapBack(i); + break; + } + } + } + + //===================================================================== + // Stack + //===================================================================== + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void MC2Push(ref this FixedList4096Bytes fixedList, T item) where T : unmanaged, IEquatable + { + fixedList.Add(item); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static T MC2Pop(ref this FixedList4096Bytes fixedList) where T : unmanaged, IEquatable + { + int index = fixedList.Length - 1; + T item = fixedList[index]; + fixedList.RemoveAt(index); + return item; + } + + //===================================================================== + // Queue + //===================================================================== + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void MC2Enqueue(ref this FixedList4096Bytes fixedList, T item) where T : unmanaged, IEquatable + { + fixedList.Add(item); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static T MC2Dequque(ref this FixedList4096Bytes fixedList) where T : unmanaged, IEquatable + { + T item = fixedList[0]; + fixedList.RemoveAt(0); + return item; + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/FixedList4096BytesExtensions.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/FixedList4096BytesExtensions.cs.meta new file mode 100644 index 00000000..17c0dec2 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/FixedList4096BytesExtensions.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: a672a8e0e07ce1344817a15060cd375f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/FixedList4096BytesExtensions.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/FixedList512BytesExtensions.cs b/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/FixedList512BytesExtensions.cs new file mode 100644 index 00000000..e7123739 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/FixedList512BytesExtensions.cs @@ -0,0 +1,117 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using System; +using System.Runtime.CompilerServices; +using Unity.Collections; +using UnityEngine; + +namespace MagicaCloth2 +{ + //[BurstCompatible] + public static class FixedList512BytesExtensions + { + //===================================================================== + // Common + //===================================================================== + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool MC2IsCapacity(ref this FixedList512Bytes fixedList) where T : unmanaged, IEquatable + { + return fixedList.Length >= fixedList.Capacity; + } + + //===================================================================== + // Set + //===================================================================== + /// + /// データが存在しない場合のみ追加する + /// + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void MC2Set(ref this FixedList512Bytes fixedList, T item) where T : unmanaged, IEquatable + { + if (fixedList.Contains(item) == false) + { + fixedList.Add(item); + } + } + + /// + /// データが存在しない場合のみ追加する + /// すでに容量が一杯の場合は警告を表示し追加しない。 + /// + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void MC2SetLimit(ref this FixedList512Bytes fixedList, T item) where T : unmanaged, IEquatable + { + if (fixedList.Length >= fixedList.Capacity) + { + Debug.LogWarning($"FixedSet512.Limit!:{fixedList.Capacity}"); + return; + } + if (fixedList.Contains(item) == false) + { + fixedList.Add(item); + } + } + + /// + /// リストからデータを検索して削除する + /// 削除領域にはリストの最後のデータが移動する(SwapBack) + /// + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void MC2RemoveItemAtSwapBack(ref this FixedList512Bytes fixedList, T item) where T : unmanaged, IEquatable + { + for (int i = 0; i < fixedList.Length; i++) + { + if (fixedList.ElementAt(i).Equals(item)) + { + fixedList.RemoveAtSwapBack(i); + break; + } + } + } + + //===================================================================== + // Stack + //===================================================================== + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void MC2Push(ref this FixedList512Bytes fixedList, T item) where T : unmanaged, IEquatable + { + fixedList.Add(item); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static T MC2Pop(ref this FixedList512Bytes fixedList) where T : unmanaged, IEquatable + { + int index = fixedList.Length - 1; + T item = fixedList[index]; + fixedList.RemoveAt(index); + return item; + } + + //===================================================================== + // Queue + //===================================================================== + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void MC2Enqueue(ref this FixedList512Bytes fixedList, T item) where T : unmanaged, IEquatable + { + fixedList.Add(item); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static T MC2Dequque(ref this FixedList512Bytes fixedList) where T : unmanaged, IEquatable + { + T item = fixedList[0]; + fixedList.RemoveAt(0); + return item; + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/FixedList512BytesExtensions.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/FixedList512BytesExtensions.cs.meta new file mode 100644 index 00000000..9070f279 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/FixedList512BytesExtensions.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 844ad8e2dd5bec94c8684bd46b5ae53b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/FixedList512BytesExtensions.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/FixedList64BytesExtensions.cs b/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/FixedList64BytesExtensions.cs new file mode 100644 index 00000000..7aad0bce --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/FixedList64BytesExtensions.cs @@ -0,0 +1,117 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using System; +using System.Runtime.CompilerServices; +using Unity.Collections; +using UnityEngine; + +namespace MagicaCloth2 +{ + //[BurstCompatible] + public static class FixedList64BytesExtensions + { + //===================================================================== + // Common + //===================================================================== + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool MC2IsCapacity(ref this FixedList64Bytes fixedList) where T : unmanaged, IEquatable + { + return fixedList.Length >= fixedList.Capacity; + } + + //===================================================================== + // Set + //===================================================================== + /// + /// データが存在しない場合のみ追加する + /// + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void MC2Set(ref this FixedList64Bytes fixedList, T item) where T : unmanaged, IEquatable + { + if (fixedList.Contains(item) == false) + { + fixedList.Add(item); + } + } + + /// + /// データが存在しない場合のみ追加する + /// すでに容量が一杯の場合は警告を表示し追加しない。 + /// + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void MC2SetLimit(ref this FixedList64Bytes fixedList, T item) where T : unmanaged, IEquatable + { + if (fixedList.Length >= fixedList.Capacity) + { + Debug.LogWarning($"FixedSet64.Limit!:{fixedList.Capacity}"); + return; + } + if (fixedList.Contains(item) == false) + { + fixedList.Add(item); + } + } + + /// + /// リストからデータを検索して削除する + /// 削除領域にはリストの最後のデータが移動する(SwapBack) + /// + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void MC2RemoveItemAtSwapBack(ref this FixedList64Bytes fixedList, T item) where T : unmanaged, IEquatable + { + for (int i = 0; i < fixedList.Length; i++) + { + if (fixedList.ElementAt(i).Equals(item)) + { + fixedList.RemoveAtSwapBack(i); + break; + } + } + } + + //===================================================================== + // Stack + //===================================================================== + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void MC2Push(ref this FixedList64Bytes fixedList, T item) where T : unmanaged, IEquatable + { + fixedList.Add(item); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static T MC2Pop(ref this FixedList64Bytes fixedList) where T : unmanaged, IEquatable + { + int index = fixedList.Length - 1; + T item = fixedList[index]; + fixedList.RemoveAt(index); + return item; + } + + //===================================================================== + // Queue + //===================================================================== + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void MC2Enqueue(ref this FixedList64Bytes fixedList, T item) where T : unmanaged, IEquatable + { + fixedList.Add(item); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static T MC2Dequque(ref this FixedList64Bytes fixedList) where T : unmanaged, IEquatable + { + T item = fixedList[0]; + fixedList.RemoveAt(0); + return item; + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/FixedList64BytesExtensions.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/FixedList64BytesExtensions.cs.meta new file mode 100644 index 00000000..2548d416 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/FixedList64BytesExtensions.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 29fde9f6ce7d36a449d5ed4e3d952f35 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/FixedList64BytesExtensions.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/NativeArrayExtensions.cs b/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/NativeArrayExtensions.cs new file mode 100644 index 00000000..2abce8c1 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/NativeArrayExtensions.cs @@ -0,0 +1,85 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using Unity.Collections; + +namespace MagicaCloth2 +{ + /// + /// NativeArrayの拡張メソッド + /// + public static class NativeArrayExtensions + { + /// + /// NativeArrayが確保されている場合のみDispose()する + /// + /// + /// + public static void MC2DisposeSafe(ref this NativeArray array) where T : unmanaged + { + if (array.IsCreated) + array.Dispose(); + } + + /// + /// NativeArrayをリサイズする + /// 指定サイズ未満の場合にメモリを解放して新しいサイズで確保し直す + /// リサイズ時に内容はコピーしない + /// + /// + /// + /// + /// + /// + public static void MC2Resize(ref this NativeArray array, int size, Allocator allocator = Allocator.Persistent, NativeArrayOptions options = NativeArrayOptions.ClearMemory) where T : unmanaged + { + if (array.IsCreated == false || array.Length < size) + { + array.MC2DisposeSafe(); + array = new NativeArray(size, allocator, options); + } + } + + /// + /// NativeArrayをbyte[]に変換する + /// + /// + /// + /// + public static byte[] MC2ToRawBytes(ref this NativeArray array) where T : unmanaged + { + if (array.IsCreated == false || array.Length == 0) + return null; + var slice = new NativeSlice(array).SliceConvert(); + var bytes = new byte[slice.Length]; + slice.CopyTo(bytes); + return bytes; + } + + /// + /// byte[]からNativeArrayを作成する + /// + /// + /// + /// + /// + public static NativeArray MC2FromRawBytes(byte[] bytes, Allocator allocator = Allocator.Persistent) where T : unmanaged + { + if (bytes == null) + return new NativeArray(); + + int structSize = Unity.Collections.LowLevel.Unsafe.UnsafeUtility.SizeOf(); + + int length = bytes.Length / structSize; + var array = new NativeArray(length, allocator); + if (length > 0) + { + using var byteArray = new NativeArray(bytes, Allocator.Temp); + //using var byteArray = new NativeArray(bytes, Allocator.Persistent); + var slice = new NativeSlice(byteArray).SliceConvert(); + slice.CopyTo(array); + } + return array; + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/NativeArrayExtensions.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/NativeArrayExtensions.cs.meta new file mode 100644 index 00000000..ed09b68d --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/NativeArrayExtensions.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 93d2b52144a75c64b91e75d4f974d74a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/NativeArrayExtensions.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/NativeMultiHashMapExtensions.cs b/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/NativeMultiHashMapExtensions.cs new file mode 100644 index 00000000..c78fd383 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/NativeMultiHashMapExtensions.cs @@ -0,0 +1,227 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using System; +using Unity.Burst; +using Unity.Collections; +using Unity.Jobs; +using Unity.Mathematics; +using UnityEngine; + +namespace MagicaCloth2 +{ + /// + /// NativeMultiHashMapの拡張メソッド + /// + public static class NativeMultiHashMapExtensions + { + /// + /// NativeParallelMultiHashMapのキーに指定データが存在するか判定する + /// + /// + /// + /// + /// + /// + /// +#if MC2_COLLECTIONS_200 + public static bool MC2Contains(ref this NativeParallelMultiHashMap map, TKey key, TValue value) where TKey : unmanaged, IEquatable where TValue : unmanaged, IEquatable +#else + public static bool MC2Contains(ref this NativeParallelMultiHashMap map, TKey key, TValue value) where TKey : struct, IEquatable where TValue : struct, IEquatable +#endif + { + foreach (TValue val in map.GetValuesForKey(key)) + { + if (val.Equals(value)) + return true; + } + return false; + } + + /// + /// NativeParallelMultiHashMapキーに対して重複なしのデータを追加する + /// すでにキーに同じデータが存在する場合は追加しない。 + /// + /// + /// + /// + /// + /// +#if MC2_COLLECTIONS_200 + public static void MC2UniqueAdd(ref this NativeParallelMultiHashMap map, TKey key, TValue value) where TKey : unmanaged, IEquatable where TValue : unmanaged, IEquatable +#else + public static void MC2UniqueAdd(ref this NativeParallelMultiHashMap map, TKey key, TValue value) where TKey : struct, IEquatable where TValue : struct, IEquatable +#endif + { + if (map.MC2Contains(key, value) == false) + { + map.Add(key, value); + } + } + + /// + /// NativeMultiHashMapのキーに存在するデータを削除する + /// + /// + /// + /// + /// + /// + /// +#if MC2_COLLECTIONS_200 + public static bool MC2RemoveValue(ref this NativeParallelMultiHashMap map, TKey key, TValue value) where TKey : unmanaged, IEquatable where TValue : unmanaged, IEquatable +#else + public static bool MC2RemoveValue(ref this NativeParallelMultiHashMap map, TKey key, TValue value) where TKey : struct, IEquatable where TValue : struct, IEquatable +#endif + { + NativeParallelMultiHashMapIterator it; + TValue item; + if (map.TryGetFirstValue(key, out item, out it)) + { + do + { + if (item.Equals(value)) + { + map.Remove(it); + return true; + } + } + while (map.TryGetNextValue(out item, ref it)); + } + + return false; + } + + /// + /// 現在のキーのデータをFixedList512Bytesに変換して返す + /// + /// + /// +#if MC2_COLLECTIONS_200 + public static FixedList512Bytes MC2ToFixedList512Bytes(ref this NativeParallelMultiHashMap map, TKey key) where TKey : unmanaged, IEquatable where TValue : unmanaged, IEquatable +#else + public static FixedList512Bytes MC2ToFixedList512Bytes(ref this NativeParallelMultiHashMap map, TKey key) where TKey : struct, IEquatable where TValue : unmanaged, IEquatable +#endif + { + var fixlist = new FixedList512Bytes(); + if (map.ContainsKey(key)) + { + foreach (var data in map.GetValuesForKey(key)) + { + fixlist.Add(data); + } + } + + return fixlist; + } + + /// + /// 現在のキーのデータをFixedList128Bytesに変換して返す + /// + /// + /// +#if MC2_COLLECTIONS_200 + public static FixedList128Bytes MC2ToFixedList128Bytes(ref this NativeParallelMultiHashMap map, TKey key) where TKey : unmanaged, IEquatable where TValue : unmanaged, IEquatable +#else + public static FixedList128Bytes MC2ToFixedList128Bytes(ref this NativeParallelMultiHashMap map, TKey key) where TKey : struct, IEquatable where TValue : unmanaged, IEquatable +#endif + { + var fixlist = new FixedList128Bytes(); + if (map.ContainsKey(key)) + { + foreach (var data in map.GetValuesForKey(key)) + { + fixlist.Add(data); + } + } + + return fixlist; + } + + /// + /// NativeParallelMultiHashMapをKeyとValueの配列に変換します + /// + /// + /// + /// + /// +#if MC2_COLLECTIONS_200 + public static (TKey[], TValue[]) MC2Serialize(ref this NativeParallelMultiHashMap map) where TKey : unmanaged, IEquatable where TValue : unmanaged +#else + public static (TKey[], TValue[]) MC2Serialize(ref this NativeParallelMultiHashMap map) where TKey : struct, IEquatable where TValue : struct +#endif + { + if (map.IsCreated == false || map.Count() == 0 || map.IsEmpty) + return (null, null); + + using var keyNativeArray = map.GetKeyArray(Allocator.Persistent); + using var valueNativeArray = map.GetValueArray(Allocator.Persistent); + + return (keyNativeArray.ToArray(), valueNativeArray.ToArray()); + } + + /// + /// KeyとValueの配列からNativeParallelMultiHashMapを復元します + /// 高速化のためBurstを利用 + /// ジェネリック型ジョブは明示的に型を指定する必要があるため型ごとに関数が発生します + /// + /// + /// + /// + public static NativeParallelMultiHashMap MC2Deserialize(int2[] keyArray, ushort[] valueArray) + { + int keyCount = keyArray?.Length ?? 0; + int valueCount = valueArray?.Length ?? 0; + Debug.Assert(keyCount == valueCount); + var map = new NativeParallelMultiHashMap(keyCount, Allocator.Persistent); + if (keyCount > 0 && valueCount > 0) + { + using var keyNativeArray = new NativeArray(keyArray, Allocator.Persistent); + using var valueNativeArray = new NativeArray(valueArray, Allocator.Persistent); + var job = new SetParallelMultiHashMapJob() { map = map, keyArray = keyNativeArray, valueArray = valueNativeArray }; + job.Run(); + } + + return map; + } + + [BurstCompile] +#if MC2_COLLECTIONS_200 + struct SetParallelMultiHashMapJob : IJob where TKey : unmanaged, IEquatable where TValue : unmanaged +#else + struct SetParallelMultiHashMapJob : IJob where TKey : struct, IEquatable where TValue : struct +#endif + { + public NativeParallelMultiHashMap map; + [Unity.Collections.ReadOnly] + public NativeArray keyArray; + [Unity.Collections.ReadOnly] + public NativeArray valueArray; + + public void Execute() + { + int cnt = keyArray.Length; + for (int i = 0; i < cnt; i++) + { + map.Add(keyArray[i], valueArray[i]); + } + } + } + + /// + /// NativeParallelMultiHashMapが確保されている場合のみDispose()する + /// + /// + /// + /// +#if MC2_COLLECTIONS_200 + public static void MC2DisposeSafe(ref this NativeParallelMultiHashMap map) where TKey : unmanaged, IEquatable where TValue : unmanaged, IEquatable +#else + public static void MC2DisposeSafe(ref this NativeParallelMultiHashMap map) where TKey : struct, IEquatable where TValue : struct, IEquatable +#endif + { + if (map.IsCreated) + map.Dispose(); + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/NativeMultiHashMapExtensions.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/NativeMultiHashMapExtensions.cs.meta new file mode 100644 index 00000000..a3f2ed87 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/NativeMultiHashMapExtensions.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: b133d9becc3f7ce46b4504e63586056b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/NativeMultiHashMapExtensions.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/NativeParallelHashMapExtensions.cs b/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/NativeParallelHashMapExtensions.cs new file mode 100644 index 00000000..2ca0e18a --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/NativeParallelHashMapExtensions.cs @@ -0,0 +1,30 @@ +// Magica Cloth 2. +// Copyright (c) 2024 MagicaSoft. +// https://magicasoft.jp +using System; +using Unity.Collections; + +namespace MagicaCloth2 +{ + /// + /// NativeParallelHashMapの拡張メソッド + /// + public static class NativeParallelHashMap + { + /// + /// NativeParallelMultiHashMapが確保されている場合のみDispose()する + /// + /// + /// + /// +#if MC2_COLLECTIONS_200 + public static void MC2DisposeSafe(ref this NativeParallelHashMap map) where TKey : unmanaged, IEquatable where TValue : unmanaged, IEquatable +#else + public static void MC2DisposeSafe(ref this NativeParallelHashMap map) where TKey : struct, IEquatable where TValue : struct, IEquatable +#endif + { + if (map.IsCreated) + map.Dispose(); + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/NativeParallelHashMapExtensions.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/NativeParallelHashMapExtensions.cs.meta new file mode 100644 index 00000000..a643bf41 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/NativeParallelHashMapExtensions.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: f6dcd839c56f63b42af8231ec3cb1841 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/NativeParallelHashMapExtensions.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/NativeReferenceExtensions.cs b/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/NativeReferenceExtensions.cs new file mode 100644 index 00000000..34013474 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/NativeReferenceExtensions.cs @@ -0,0 +1,28 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using System.Runtime.CompilerServices; +using System.Threading; +using Unity.Collections; +using Unity.Collections.LowLevel.Unsafe; + +namespace MagicaCloth2 +{ + static class NativeReferenceExtensions + { + /// + /// カウンターにデータ数を追加してその追加前の開始インデックスを返す + /// この関数はスレッドセーフである + /// + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + unsafe public static int MC2InterlockedStartIndex(ref this NativeReference counter, int dataCount) + { + int* cntPt = (int*)counter.GetUnsafePtr(); + int start = Interlocked.Add(ref *cntPt, dataCount) - dataCount; + return start; + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/NativeReferenceExtensions.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/NativeReferenceExtensions.cs.meta new file mode 100644 index 00000000..0fa599cf --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/NativeReferenceExtensions.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: a86bf182de69e9b4b8b212407378a96a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Utility/NativeCollection/NativeReferenceExtensions.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Utility/ResultCode.meta b/Assets/MagicaCloth2/Scripts/Core/Utility/ResultCode.meta new file mode 100644 index 00000000..7ef9c71a --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Utility/ResultCode.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: d7a14441047ec414c86b093b4a7940ed +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/MagicaCloth2/Scripts/Core/Utility/ResultCode/Exception.cs b/Assets/MagicaCloth2/Scripts/Core/Utility/ResultCode/Exception.cs new file mode 100644 index 00000000..3afa60cc --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Utility/ResultCode/Exception.cs @@ -0,0 +1,31 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using System; + +namespace MagicaCloth2 +{ + /// + /// 処理例外 + /// これは予期されたエラーにより処理を中断する場合に用いる + /// + [Serializable] + public class MagicaClothProcessingException : Exception + { + public MagicaClothProcessingException() : base() { } + public MagicaClothProcessingException(string message) : base(message) { } + public MagicaClothProcessingException(string message, Exception inner) : base(message, inner) { } + } + + /// + /// キャンセル例外 + /// これはエラー無しに処理を打ち切る場合に用いる + /// + [Serializable] + public class MagicaClothCanceledException : Exception + { + public MagicaClothCanceledException() : base() { } + public MagicaClothCanceledException(string message) : base(message) { } + public MagicaClothCanceledException(string message, Exception inner) : base(message, inner) { } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/Utility/ResultCode/Exception.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Utility/ResultCode/Exception.cs.meta new file mode 100644 index 00000000..1a0ddde3 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Utility/ResultCode/Exception.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: ab191ee61f2d8e14598d1adc5359890d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Utility/ResultCode/Exception.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Utility/ResultCode/ResultCode.cs b/Assets/MagicaCloth2/Scripts/Core/Utility/ResultCode/ResultCode.cs new file mode 100644 index 00000000..71bcac95 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Utility/ResultCode/ResultCode.cs @@ -0,0 +1,165 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using System.Diagnostics; +using UnityEngine; + +namespace MagicaCloth2 +{ + /// + /// 様々な処理の結果 + /// + [System.Serializable] + public struct ResultCode + { + [SerializeField] + volatile Define.Result result; + + /// + /// 警告:警告は1つのみ保持 + /// + [SerializeField] + volatile Define.Result warning; + + public Define.Result Result => result; + + public static ResultCode None => new ResultCode(Define.Result.None); + public static ResultCode Empty => new ResultCode(Define.Result.Empty); + public static ResultCode Success => new ResultCode(Define.Result.Success); + public static ResultCode Error => new ResultCode(Define.Result.Error); + + public ResultCode(Define.Result initResult) + { + result = initResult; + warning = Define.Result.None; + } + + public void Clear() + { + result = Define.Result.None; + warning = Define.Result.None; + } + + public void SetResult(Define.Result code) + { + result = code; + } + + public void SetSuccess() + { + SetResult(Define.Result.Success); + } + + public void SetCancel() + { + SetResult(Define.Result.Cancel); + } + + public void SetError(Define.Result code = Define.Result.Error) + { + result = code; +#if MC2_DEBUG + Develop.DebugLogError(GetResultString()); +#endif + } + + public void SetWarning(Define.Result code = Define.Result.Warning) + { + if (code == Define.Result.None) + return; + + warning = code; +#if MC2_DEBUG + Develop.DebugLogWarning(GetWarningString()); +#endif + } + + public void Merge(ResultCode src) + { + if (src.IsError()) + result = src.result; + if (src.IsWarning()) + warning = src.warning; + } + + public void SetProcess() + { + SetResult(Define.Result.Process); + } + + public bool IsResult(Define.Result code) + { + return result == code; + } + + public bool IsNone() => result == Define.Result.None; + public bool IsSuccess() => result == Define.Result.Success; + public bool IsFaild() => !IsSuccess(); + public bool IsCancel() => result == Define.Result.Cancel; + public bool IsNormal() => result < Define.Result.Warning; + public bool IsError() => result >= Define.Result.Error; + public bool IsProcess() => result == Define.Result.Process; + public bool IsWarning() => warning != Define.Result.None; + + public string GetResultString() + { + if (IsNormal()) + return result.ToString(); + else + return $"({(int)result}) {result}"; + } + + public string GetWarningString() + { + return $"({(int)warning}) {warning}"; + } + + /// + /// 結果コードに対する追加情報を取得する。ない場合はnullが返る。 + /// + /// + public string GetResultInformation() + { + switch (result) + { + case Define.Result.RenderSetup_Unreadable: + return "It is necessary to turn on [Read/Write] in the model import settings."; + case Define.Result.RenderSetup_Over65535vertices: + return "Original mesh must have no more than 65,535 vertices."; + case Define.Result.SerializeData_Over31Renderers: + return $"There are {Define.System.MaxRendererCount} renderers that can be set."; + case Define.Result.Init_ScaleIsZero: + return "Component scale values is 0."; + case Define.Result.Init_NegativeScale: + return "Component has negative scale."; + default: + return null; + } + } + + public string GetWarningInformation() + { + switch (warning) + { + case Define.Result.RenderMesh_VertexWeightIs5BonesOrMore: + return "The source renderer mesh contains vertex weights that utilize more than 5 bones.\nA weight of 5 or more is invalid."; + case Define.Result.Init_NonUniformScale: + return "Component scale values ​​should be uniform.\nIf the scale is not uniform, there is a risk that it will not work properly."; + default: + return null; + } + } + + [Conditional("MC2_DEBUG")] + public void DebugLog(bool error = true, bool warning = true, bool normal = true) + { + if (IsError() && error) + Develop.DebugLogError(GetResultString()); + else if (normal) + Develop.DebugLog(GetResultString()); + + if (IsWarning() && warning) + Develop.DebugLogWarning(GetWarningString()); + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/Utility/ResultCode/ResultCode.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Utility/ResultCode/ResultCode.cs.meta new file mode 100644 index 00000000..afb13b81 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Utility/ResultCode/ResultCode.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: f7830dff664b1ff409e8ae3d8456371a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Utility/ResultCode/ResultCode.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Utility/Time.meta b/Assets/MagicaCloth2/Scripts/Core/Utility/Time.meta new file mode 100644 index 00000000..2ce74c1d --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Utility/Time.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 87fbdda2219d11649892645df5504b0d +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/MagicaCloth2/Scripts/Core/Utility/Time/TimeSpan.cs b/Assets/MagicaCloth2/Scripts/Core/Utility/Time/TimeSpan.cs new file mode 100644 index 00000000..b2fcd618 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Utility/Time/TimeSpan.cs @@ -0,0 +1,71 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using System; + +namespace MagicaCloth2 +{ + /// + /// 時間計測クラス + /// + public class TimeSpan + { + string name = string.Empty; + DateTime stime; + DateTime etime; + bool isFinish; + + public TimeSpan() { } + + public TimeSpan(string name) + { + this.name = name; + stime = DateTime.Now; + isFinish = false; + } + + public void Start() + { + stime = DateTime.Now; + isFinish = false; + } + + public void Finish() + { + //etime = DateTime.Now; + if (isFinish == false) + { + etime = DateTime.Now; + isFinish = true; + } + } + + public double TotalSeconds() + { + Finish(); + return (etime - stime).TotalSeconds; + } + + public double TotalMilliSeconds() + { + Finish(); + return (etime - stime).TotalMilliseconds; + } + + public override string ToString() + { + //return $"TimeSpan [{name}] : {TotalSeconds()}(s)"; + return $"TimeSpan [{name}] : {TotalMilliSeconds()}(ms)"; + } + + public void DebugLog() + { + Develop.DebugLog(this); + } + + public void Log() + { + Develop.Log(this); + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/Utility/Time/TimeSpan.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Utility/Time/TimeSpan.cs.meta new file mode 100644 index 00000000..21829a88 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Utility/Time/TimeSpan.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 37c049d9587e21243b12c35054b5582b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Utility/Time/TimeSpan.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/Utility/Time/UnityTimeSpan.cs b/Assets/MagicaCloth2/Scripts/Core/Utility/Time/UnityTimeSpan.cs new file mode 100644 index 00000000..0ad1bbd7 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Utility/Time/UnityTimeSpan.cs @@ -0,0 +1,56 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using UnityEngine; + +namespace MagicaCloth2 +{ + /// + /// 時間計測クラス(UnityEngine.Timeを使用する) + /// + public class UnityTimeSpan + { + string name = string.Empty; + float stime; + float etime; + bool isFinish; + + public UnityTimeSpan(string name) + { + this.name = name; + stime = Time.realtimeSinceStartup; + } + + public void Finish() + { + if (isFinish == false) + { + etime = Time.realtimeSinceStartup; + isFinish = true; + } + } + + public float TotalSeconds() + { + Finish(); + return (etime - stime); + } + + public float TotalMilliSeconds() + { + Finish(); + return (etime - stime) * 1000.0f; + } + + public override string ToString() + { + //return $"TimeSpan [{name}] : {TotalSeconds()}(s)"; + return $"UnityTimeSpan [{name}] : {TotalMilliSeconds()}(ms)"; + } + + public void DebugLog() + { + Debug.Log(this); + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/Utility/Time/UnityTimeSpan.cs.meta b/Assets/MagicaCloth2/Scripts/Core/Utility/Time/UnityTimeSpan.cs.meta new file mode 100644 index 00000000..ce7e6d43 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/Utility/Time/UnityTimeSpan.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 60bc0f15f2991074f9db6ecacf0eb4bd +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/Utility/Time/UnityTimeSpan.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/VirtualMesh.meta b/Assets/MagicaCloth2/Scripts/Core/VirtualMesh.meta new file mode 100644 index 00000000..a4bab0ac --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/VirtualMesh.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: e445d9f5e13ea1b4dbbec70883e9ef2c +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/MagicaCloth2/Scripts/Core/VirtualMesh/Function.meta b/Assets/MagicaCloth2/Scripts/Core/VirtualMesh/Function.meta new file mode 100644 index 00000000..a2abfd19 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/VirtualMesh/Function.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 50f98a3f39e39d24fbd368941ed7dc51 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/MagicaCloth2/Scripts/Core/VirtualMesh/Function/VirtualMeshInputOutput.cs b/Assets/MagicaCloth2/Scripts/Core/VirtualMesh/Function/VirtualMeshInputOutput.cs new file mode 100644 index 00000000..01b44bde --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/VirtualMesh/Function/VirtualMeshInputOutput.cs @@ -0,0 +1,1910 @@ +// Magica Cloth 2. +// Copyright (c) 2023 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 +{ + public partial class VirtualMesh + { + /// + /// レンダー情報からインポートする(スレッド可) + /// + /// + /// + /// + public void ImportFrom(RenderSetupData rsetup, int uvChannel) + { + try + { + // ★基本的に一連の作業が完了するまでキャンセルはさせない(安全性のため) + if (rsetup == null) + { + result.SetError(Define.Result.VirtualMesh_InvalidSetup); + throw new MagicaClothProcessingException(); + } + if (rsetup.IsFaild()) + { + result.SetError(Define.Result.VirtualMesh_InvalidSetup); + throw new MagicaClothProcessingException(); + } + + // ========== Transform ========= + // セットアップ情報からトランスフォームを登録する + if (transformData == null) + transformData = new TransformData(rsetup.TransformCount); + int[] indices = transformData.AddTransformRange( + rsetup.transformList, + rsetup.transformIdList, + rsetup.transformParentIdList, + rsetup.rootTransformIdList, + rsetup.transformLocalPositions, + rsetup.transformLocalRotations, + rsetup.transformPositions, + rsetup.transformRotations, + rsetup.transformScales, + rsetup.transformInverseRotations + ); + + // center + centerTransformIndex = indices[rsetup.renderTransformIndex]; + + // 初期化時のマトリックスを記録 + initLocalToWorld = rsetup.initRenderLocalToWorld; + initWorldToLocal = rsetup.initRenderWorldtoLocal; + initRotation = rsetup.initRenderRotation; + initInverseRotation = math.inverse(initRotation); + initScale = rsetup.initRenderScale; + + // ========== ここからMesh/Boneで分岐 ========== + if (rsetup.setupType == RenderSetupData.SetupType.MeshCloth) + { + // メッシュタイプ + meshType = MeshType.NormalMesh; + isBoneCloth = false; + ImportMeshType(rsetup, indices, uvChannel); + + // スキニングメッシュでは1回スキニングを行いクロスローカル空間に姿勢を変換する + if (rsetup.hasBoneWeight) + { + ImportMeshSkinning(); + } + } + else if (rsetup.setupType == RenderSetupData.SetupType.BoneCloth || rsetup.setupType == RenderSetupData.SetupType.BoneSpring) + { + // ボーンタイプ + meshType = MeshType.NormalBoneMesh; + isBoneCloth = true; + ImportBoneType(rsetup, indices); + } + else + { + result.SetError(Define.Result.RenderSetup_InvalidType); + throw new IndexOutOfRangeException(); + } + + // AABB + boundingBox = new NativeReference(Allocator.Persistent); + JobUtility.CalcAABBRun(localPositions.GetNativeArray(), VertexCount, boundingBox); + + // UV + switch (rsetup.setupType) + { + case RenderSetupData.SetupType.BoneCloth: + case RenderSetupData.SetupType.BoneSpring: + if (TriangleCount > 0) + { + // ボーンタイプでトライアングルを含む場合 + JobUtility.CalcUVWithSphereMappingRun( + localPositions.GetNativeArray(), + VertexCount, + boundingBox, + uv.GetNativeArray() + ); + } + break; + } + + // 頂点平均接続距離算出 + CalcAverageAndMaxVertexDistanceRun(); + } + catch (Exception) + { + if (result.IsNone()) result.SetError(Define.Result.VirtualMesh_ImportError); + throw; + } + finally + { + } + } + + /// + /// Meshタイプのインポート + /// + /// + /// + void ImportMeshType(RenderSetupData rsetup, int[] transformIndices, int uvChannel) + { + // root bone + skinRootIndex = transformIndices[rsetup.skinRootBoneIndex]; + + // skin bones + skinBoneTransformIndices.AddRange(transformIndices, rsetup.skinBoneCount); + + // bind pose + skinBoneBindPoses.AddRange(rsetup.bindPoseList.ToArray()); + + // ========== MeshData ========= + var meshData = rsetup.meshDataArray[0]; + int vcnt = meshData.vertexCount; + //flags.AddRange(vcnt); + localPositions.AddRange(vcnt); + localNormals.AddRange(vcnt); + localTangents.AddRange(vcnt); + uv.AddRange(vcnt); + boneWeights.AddRange(vcnt); + + + meshData.GetVertices(localPositions.GetNativeArray()); + meshData.GetNormals(localNormals.GetNativeArray()); + if (meshData.HasVertexAttribute(UnityEngine.Rendering.VertexAttribute.Tangent)) + { + // 接線情報がメッシュに存在する + using var tangents = new NativeArray(vcnt, Allocator.TempJob); + meshData.GetTangents(tangents); + // tangent変換(Vector4->float3) + localTangents.CopyFromWithTypeChangeStride(tangents); + } + else + { + // 接線情報がメッシュに存在しない + Develop.DebugLogWarning($"[{name}] Tangents not found!"); + // tangentを生成する + // このtangentは描画用では無く姿勢制御用なのである意味適当でも大丈夫 + var job = new Import_GenerateTangentJob() + { + localNormals = localNormals.GetNativeArray(), + localTangents = localTangents.GetNativeArray(), + }; + job.Run(vcnt); + } + if (meshData.HasVertexAttribute(UnityEngine.Rendering.VertexAttribute.TexCoord0)) + { + uvChannel = Mathf.Clamp(uvChannel, 0, 7); + UnityEngine.Rendering.VertexAttribute useTexCoord = UnityEngine.Rendering.VertexAttribute.TexCoord0 + uvChannel; + if (meshData.HasVertexAttribute(useTexCoord) == false) + { + Develop.LogWarning($"[{name}] UV{uvChannel} not found! => Use UV0."); + uvChannel = 0; + } + //Debug.Log($"Fetch UV:{uvChannel}"); + meshData.GetUVs(uvChannel, uv.GetNativeArray()); + } + else + { + Develop.LogWarning($"[{name}] UV0 not found!"); + } + + // 属性 + attributes.AddRange(vcnt); + + // 参照インデックス + referenceIndices.AddRange(vcnt); + + // bone weights + using var startBoneWeightIndices = new NativeArray(vcnt, Allocator.TempJob); + + // 参照インデックスに連番を振る + JobUtility.SerialNumberRun(referenceIndices.GetNativeArray(), vcnt); + + // bone weights + if (rsetup.hasBoneWeight) + { + // bonesPerVertexArrayから頂点ごとのデータ開始インデックスを算出する + var importBoneWeightJob1 = new Import_BoneWeightJob1() + { + vcnt = vcnt, + bonesPerVertexArray = rsetup.bonesPerVertexArray, + startBoneWeightIndices = startBoneWeightIndices, + }; + importBoneWeightJob1.Run(); + + // 頂点ごとのボーンウエイトをVirtualMeshBoneWeights構造体として格納する + // ただし最大ウエイト数は4で打ち切る + var importBoneWeightJob2 = new Import_BoneWeightJob2() + { + startBoneWeightIndices = startBoneWeightIndices, + boneWeightArray = rsetup.boneWeightArray, + bonesPerVertexArray = rsetup.bonesPerVertexArray, + boneWeights = boneWeights.GetNativeArray(), + }; + importBoneWeightJob2.Run(vcnt); + } + else + { + // 通常メッシュはセンタートランスフォーム100%でウエイトを付ける + JobUtility.FillRun(boneWeights.GetNativeArray(), vcnt, new VirtualMeshBoneWeight(0, new float4(1, 0, 0, 0))); + } + + // triangle + for (int i = 0; i < meshData.subMeshCount; i++) + { + var submeshData = meshData.GetSubMesh(i); + using var triangleIndices = new NativeArray(submeshData.indexCount, Allocator.Persistent); + meshData.GetIndices(triangleIndices, i); + + // 追加 + triangles.AddRangeTypeChange(triangleIndices); + } + } + + /// + /// tangentを擬似生成する + /// このtangentは描画用では無く姿勢制御用なのである意味適当でも大丈夫 + /// + [BurstCompile] + struct Import_GenerateTangentJob : IJobParallelFor + { + [Unity.Collections.ReadOnly] + public NativeArray localNormals; + [Unity.Collections.WriteOnly] + public NativeArray localTangents; + + public void Execute(int vindex) + { + var nor = localNormals[vindex]; + float3 tan = math.up(); + if (math.dot(nor, tan) < 0.9) + { + tan = math.normalize(math.cross(nor, tan)); + } + else + { + tan = math.normalize(math.cross(nor, math.right())); + } + localTangents[vindex] = tan; + } + } + + + /// + /// スキニングメッシュの頂点をスキニングして元のローカル空間に変換する + /// + void ImportMeshSkinning() + { + var job = new Import_CalcSkinningJob() + { + localPositions = localPositions.GetNativeArray(), + localNormals = localNormals.GetNativeArray(), + localTangents = localTangents.GetNativeArray(), + boneWeights = boneWeights.GetNativeArray(), + skinBoneTransformIndices = skinBoneTransformIndices.GetNativeArray(), + bindPoses = skinBoneBindPoses.GetNativeArray(), + + transformPositionArray = transformData.positionArray.GetNativeArray(), + transformRotationArray = transformData.rotationArray.GetNativeArray(), + transformScaleArray = transformData.scaleArray.GetNativeArray(), + + toM = initWorldToLocal, + }; + job.Run(VertexCount); + } + + /// + /// 頂点スキニングを行いワールド座標・法線・接線を求める + /// + [BurstCompile] + struct Import_CalcSkinningJob : IJobParallelFor + { + //[Unity.Collections.ReadOnly] + public NativeArray localPositions; + //[Unity.Collections.ReadOnly] + public NativeArray localNormals; + //[Unity.Collections.ReadOnly] + public NativeArray localTangents; + [Unity.Collections.ReadOnly] + public NativeArray boneWeights; + [Unity.Collections.ReadOnly] + public NativeArray skinBoneTransformIndices; + [Unity.Collections.ReadOnly] + public NativeArray bindPoses; + [Unity.Collections.ReadOnly] + public NativeArray transformPositionArray; + [Unity.Collections.ReadOnly] + public NativeArray transformRotationArray; + [Unity.Collections.ReadOnly] + public NativeArray transformScaleArray; + + public float4x4 toM; + + public void Execute(int vindex) + { + var bw = boneWeights[vindex]; + int wcnt = bw.Count; + float3 wpos = 0; + float3 wnor = 0; + float3 wtan = 0; + for (int i = 0; i < wcnt; i++) + { + float w = bw.weights[i]; + + int boneIndex = bw.boneIndices[i]; + float4x4 bp = bindPoses[boneIndex]; + float4 lpos = new float4(localPositions[vindex], 1); + float4 lnor = new float4(localNormals[vindex], 0); + float4 ltan = new float4(localTangents[vindex], 0); + + float3 pos = math.mul(bp, lpos).xyz; + float3 nor = math.mul(bp, lnor).xyz; + float3 tan = math.mul(bp, ltan).xyz; + + int tindex = skinBoneTransformIndices[boneIndex]; + var tpos = transformPositionArray[tindex]; + var trot = transformRotationArray[tindex]; + var tscl = transformScaleArray[tindex]; + MathUtility.TransformPositionNormalTangent(tpos, trot, tscl, ref pos, ref nor, ref tan); + + wpos += pos * w; + wnor += nor * w; + wtan += tan * w; + } + + // 再びローカル空間に変換する + localPositions[vindex] = MathUtility.TransformPoint(wpos, toM); + //localNormals[vindex] = MathUtility.TransformDirection(wnor, toM); + //localTangents[vindex] = MathUtility.TransformDirection(wtan, toM); + localNormals[vindex] = MathUtility.TransformNormal(wnor, toM, math.up()); + localTangents[vindex] = MathUtility.TransformNormal(wtan, toM, math.right()); + } + } + + + [BurstCompile] + struct Import_BoneWeightJob1 : IJob + { + public int vcnt; + + [Unity.Collections.ReadOnly] + public NativeArray bonesPerVertexArray; + + [Unity.Collections.WriteOnly] + public NativeArray startBoneWeightIndices; + + public void Execute() + { + int sindex = 0; + for (int i = 0; i < vcnt; i++) + { + startBoneWeightIndices[i] = sindex; + sindex += bonesPerVertexArray[i]; + } + } + } + + [BurstCompile] + struct Import_BoneWeightJob2 : IJobParallelFor + { + [Unity.Collections.ReadOnly] + public NativeArray startBoneWeightIndices; + [Unity.Collections.ReadOnly] + public NativeArray boneWeightArray; + [Unity.Collections.ReadOnly] + public NativeArray bonesPerVertexArray; + + [Unity.Collections.WriteOnly] + public NativeArray boneWeights; + + public void Execute(int vindex) + { + int sindex = startBoneWeightIndices[vindex]; + int wcnt = bonesPerVertexArray[vindex]; + var bw = new VirtualMeshBoneWeight(); + + // 最大ウエイト数は4まで + int index = 0; + for (int i = 0; i < wcnt && i < 4; i++) + { + var bw1 = boneWeightArray[sindex + i]; + if (bw1.weight > 0.0f) + { + bw.weights[index] = bw1.weight; + bw.boneIndices[index] = bw1.boneIndex; + index++; + } + } + + // ウエイト数が5以上あった場合はウエイト値を単位化する + if (wcnt > 4) + { + bw.AdjustWeight(); + } + + boneWeights[vindex] = bw; + } + } + + /// + /// Boneタイプのインポート + /// + /// + /// + void ImportBoneType(RenderSetupData rsetup, int[] transformIndices) + { + // Transform情報からメッシュを構築する + int vcnt = rsetup.TransformCount - 1; + //flags.AddRange(vcnt); + localPositions.AddRange(vcnt); + localNormals.AddRange(vcnt); + localTangents.AddRange(vcnt); + uv.AddRange(vcnt); + boneWeights.AddRange(vcnt); + attributes.AddRange(vcnt); + referenceIndices.AddRange(vcnt); + + // BoneClothもスキニング処理に統一するためスキニング用ボーンを登録 + skinBoneTransformIndices.AddRange(transformIndices, rsetup.skinBoneCount); + skinBoneBindPoses.AddRange(vcnt); + + // Transformの情報をクロスローカル空間に変換し頂点情報に割り当てる + // およびバインドポーズの算出 + var WtoL = rsetup.initRenderWorldtoLocal; + var LtoW = rsetup.initRenderLocalToWorld; + var boneVertexJob = new Import_BoneVertexJob() + { + WtoL = WtoL, + LtoW = LtoW, + + transformPositions = rsetup.transformPositions, + transformRotations = rsetup.transformRotations, + transformScales = rsetup.transformScales, + + localPositions = localPositions.GetNativeArray(), + localNormals = localNormals.GetNativeArray(), + localTangents = localTangents.GetNativeArray(), + boneWeights = boneWeights.GetNativeArray(), + skinBoneBindPoses = skinBoneBindPoses.GetNativeArray(), + }; + boneVertexJob.Run(vcnt); + + // 参照インデックスに連番を振る + JobUtility.SerialNumberRun(referenceIndices.GetNativeArray(), vcnt); + + // Line/Triangleの形成 + // ★ここは数も少なくあまりBurstの恩恵を受けられないので普通にC#で構成する + if (rsetup.boneConnectionMode == RenderSetupData.BoneConnectionMode.Line) + { + // Line接続 + var lineList = new List(vcnt); + for (int i = 0; i < vcnt; i++) + { + // 親に接続させる + int pindex = rsetup.GetParentTransformIndex(i, true); // センタートランスフォームは除外 + if (pindex >= 0) + { + int2 line = DataUtility.PackInt2(pindex, i); + lineList.Add(line); + } + } + + // BoneSpringでの設定 + if (rsetup.setupType == RenderSetupData.SetupType.BoneSpring) + { + // スプリングではコリジョン無効で初期化 + attributes.Fill(0, vcnt, VertexAttribute.DisableCollision); + + // コリジョンとして指定されたボーンのみ衝突判定を有効化する + if (rsetup.collisionBoneIndexList != null) + { + foreach (int index in rsetup.collisionBoneIndexList) + { + if (index >= 0) + { + attributes[index] = VertexAttribute.Invalid; + } + } + } + } + + if (lineList.Count > 0) + lines = new ExSimpleNativeArray(lineList.ToArray()); + } + else + { + // Mesh接続 + // トランスフォームIDからインデックスへの辞書を作成 + var idToIndexDict = new Dictionary(vcnt); + for (int i = 0; i < vcnt; i++) + { + if (idToIndexDict.ContainsKey(rsetup.transformIdList[i]) == false) + idToIndexDict.Add(rsetup.transformIdList[i], i); + } + + // ループ接続フラグ + bool loopConnection = rsetup.boneConnectionMode == RenderSetupData.BoneConnectionMode.SequentialLoopMesh; + + // 順次接続フラグ + bool sequentialConnection = rsetup.boneConnectionMode == RenderSetupData.BoneConnectionMode.SequentialLoopMesh + || rsetup.boneConnectionMode == RenderSetupData.BoneConnectionMode.SequentialNonLoopMesh; + + // ルートリスト + var rootTransformIdList = new List(rsetup.rootTransformIdList); // copy + int rootCnt = rootTransformIdList.Count; + const int firstRootIndex = 0; + int lastRootIndex = rootCnt - 1; + + // オート接続の場合はルート同士が最近接点になるように並べ替える + if (rsetup.boneConnectionMode == RenderSetupData.BoneConnectionMode.AutomaticMesh) + { + var tempRootIdList = new List(rootTransformIdList); + + rootTransformIdList.Clear(); + rootTransformIdList.Add(tempRootIdList[0]); + float lastDist = 0; + while (tempRootIdList.Count > 0) + { + MagicaObjectId rootId = rootTransformIdList[rootTransformIdList.Count - 1]; + tempRootIdList.Remove(rootId); + int vindex = idToIndexDict[rootId]; + var pos = localPositions[vindex]; + + // next connection + float minDist = float.MaxValue; + MagicaObjectId minId = MagicaObjectId.Invalid; + for (int i = 0; i < tempRootIdList.Count; i++) + { + MagicaObjectId rootId2 = tempRootIdList[i]; + int vindex2 = idToIndexDict[rootId2]; + var pos2 = localPositions[vindex2]; + + float dist = math.distance(pos, pos2); + if (dist < minDist) + { + minDist = dist; + minId = rootId2; + } + + } + if (minId.IsValid()) + { + if (lastDist == 0 || minDist < lastDist * 1.5f) + { + rootTransformIdList.Add(minId); + lastDist = lastDist == 0 ? minDist : (lastDist + minDist) * 0.5f; + } + else + { + // reverse + rootTransformIdList.Reverse(); + lastDist = 0; + } + } + } + + // 最初と最後のルート距離が平均以下ならばループ接続にする + if (rootTransformIdList.Count >= 3) + { + MagicaObjectId rootId1 = rootTransformIdList[0]; + MagicaObjectId rootId2 = rootTransformIdList[rootTransformIdList.Count - 1]; + int vindex1 = idToIndexDict[rootId1]; + int vindex2 = idToIndexDict[rootId2]; + var pos1 = localPositions[vindex1]; + var pos2 = localPositions[vindex2]; + float dist = math.distance(pos1, pos2); + if (dist < lastDist * 1.5f) + { + loopConnection = true; + } + } + + + // debug + //Debug.Log($"rootTransformIdList.Count:{rootTransformIdList.Count}"); + //foreach (var rid in rootTransformIdList) + //{ + // Debug.Log($"[{rid}]"); + //} + } + + // 頂点ごとの接続情報の作成 + var linkList = new FixedList128Bytes[vcnt]; + var vertexLvList = new int[vcnt]; + var vertexRootIndex = new int[vcnt]; + var lvIndexList = new List>(); // レベルごとのリスト + var mainEdgeSet = new HashSet(); // メインエッジ + + // まずトランスフォームの親子関係に接続 + var stack = new Stack(vcnt); + var lvstack = new Stack(vcnt); + for (int i = 0; i < rootCnt; i++) + { + stack.Clear(); + stack.Push(rootTransformIdList[i]); // root id + lvstack.Clear(); + lvstack.Push(0); + + while (stack.Count > 0) + { + MagicaObjectId id = stack.Pop(); + int lv = lvstack.Pop(); + int vindex = idToIndexDict[id]; + var pos = localPositions[vindex]; + + if (lvIndexList.Count <= lv) + lvIndexList.Add(new FixedList512Bytes()); + var indexList = lvIndexList[lv]; + indexList.Add(vindex); + lvIndexList[lv] = indexList; + + var link = new FixedList128Bytes(); + + // parent + MagicaObjectId pid = rsetup.transformParentIdList[vindex]; + if (idToIndexDict.ContainsKey(pid)) + { + int vindex2 = idToIndexDict[pid]; + link.Add(vindex2); + + // main edge + uint mainEdge = DataUtility.Pack32Sort(vindex, vindex2); + mainEdgeSet.Add(mainEdge); + } + + // child + var clist = rsetup.transformChildIdList[vindex]; + if (clist.Length > 0) + { + for (int j = 0; j < clist.Length; j++) + { + MagicaObjectId cid = clist[j]; + stack.Push(cid); + lvstack.Push(lv + 1); + + int vindex2 = idToIndexDict[cid]; + link.Add(vindex2); + + // main edge + uint mainEdge = DataUtility.Pack32Sort(vindex, vindex2); + mainEdgeSet.Add(mainEdge); + } + } + + linkList[vindex] = link; + vertexLvList[vindex] = lv; + vertexRootIndex[vindex] = i; + } + } + + // debug + //foreach (var mainEdge in mainEdgeSet) + // Debug.Log($"mainEdge:{DataUtility.Unpack32Hi(mainEdge)} - {DataUtility.Unpack32Low(mainEdge)}"); + + // 次に同レベルの横を接続する + uint startEndRootIndexPack = DataUtility.Pack32Sort(firstRootIndex, lastRootIndex); + for (int i = 0; i < vcnt; i++) + { + int lv = vertexLvList[i]; + var lvList = lvIndexList[lv]; + var pos = localPositions[i]; + var link = linkList[i]; + var rootIndex = vertexRootIndex[i]; + + // まず最近点をつなげる + float firstDist = float.MaxValue; + int firstIndex = -1; + foreach (var vindex in lvList) + { + if (vindex == i) + continue; + + // 非ループならば始点と終点のルートラインは接続しない + var rootIndex2 = vertexRootIndex[vindex]; + bool firstLast = startEndRootIndexPack == DataUtility.Pack32Sort(rootIndex, rootIndex2) && startEndRootIndexPack > 0; + if (loopConnection == false && firstLast) + continue; + + // 順次接続なら自身の前後のルートラインのみ接続 + if (sequentialConnection && !(loopConnection && firstLast)) + { + + if (math.abs(rootIndex - rootIndex2) > 1) + continue; + } + + var pos2 = localPositions[vindex]; + float dist = math.distance(pos, pos2); + if (dist < firstDist) + { + firstDist = dist; + firstIndex = vindex; + } + } + if (firstIndex >= 0) + { + link.Add(firstIndex); + + // 次に最初に接続した距離の少し大きめの範囲にあるすべての頂点をつなげる + // ただし順次接続の場合は距離は無視する + firstDist = sequentialConnection ? float.MaxValue : firstDist * 1.5f; // 1.5f? + foreach (var vindex in lvList) + { + if (vindex == i || vindex == firstIndex) + continue; + + // 非ループならば始点と終点のルートラインは接続しない + var rootIndex2 = vertexRootIndex[vindex]; + bool firstLast = startEndRootIndexPack == DataUtility.Pack32Sort(rootIndex, rootIndex2) && startEndRootIndexPack > 0; + if (loopConnection == false && firstLast) + continue; + + // 順次接続なら自身の前後のルートラインのみ接続 + if (sequentialConnection && !(loopConnection && firstLast)) + { + if (math.abs(rootIndex - rootIndex2) > 1) + continue; + } + + var pos2 = localPositions[vindex]; + float dist = math.distance(pos, pos2); + if (dist <= firstDist) + { + link.Add(vindex); + } + } + } + + linkList[i] = link; + + // debug + //Debug.Log($"vindex:{i}, root:{vertexRootIndex[i]}, lv:{lv}, linkCount:{link.Length}"); + //for (int l = 0; l < link.Length; l++) + // Debug.Log($"->{link[l]}"); + } + + // 頂点の接続情報からトライアングルを形成する + var edgeSet = new HashSet(); + var triangleEdgeSet = new HashSet(); + var triangleSet = new HashSet(); + for (int i = 0; i < vcnt; i++) + { + var link = linkList[i]; + if (link.Length == 0) + { + Debug.LogError($"Connection 0! [{i}]"); + continue; + } + if (link.Length == 1) + { + // lineのみ + edgeSet.Add(DataUtility.PackInt2(i, link[0])); + } + else + { + // まずエッジとしてすべて登録 + for (int j = 0; j < link.Length; j++) + { + int vindex1 = link[j]; + edgeSet.Add(DataUtility.PackInt2(i, vindex1)); + } + + int rootIndex = vertexRootIndex[i]; + + // トライアングルの形成 + var pos = localPositions[i]; + for (int j = 0; j < link.Length - 1; j++) + { + int vindex1 = link[j]; + var pos1 = localPositions[vindex1]; + var v1 = pos1 - pos; + for (int k = j + 1; k < link.Length; k++) + { + int vindex2 = link[k]; + var pos2 = localPositions[vindex2]; + var v2 = pos2 - pos; + + // 頂点位置が同じ座標を考慮 + if (math.lengthsq(v1) < 1e-06f || math.lengthsq(v2) < 1e-06f) + continue; + + // ペアの角度が一定以上ならばスキップする + var ang = math.degrees(MathUtility.Angle(v1, v2)); + if (ang >= Define.System.ProxyMeshBoneClothTriangleAngle) + continue; + + // 3つのルートラインにまたがる接続は行わない + int rootIndex1 = vertexRootIndex[vindex1]; + int rootIndex2 = vertexRootIndex[vindex2]; + if (rootIndex1 != rootIndex && rootIndex2 != rootIndex && rootIndex1 != rootIndex2) + continue; + + // トライアングルは1つ以上のメインエッジを含んでいなければならない + int mainEdgeCount = 0; + mainEdgeCount += mainEdgeSet.Contains(DataUtility.Pack32Sort(i, vindex1)) ? 1 : 0; + mainEdgeCount += mainEdgeSet.Contains(DataUtility.Pack32Sort(i, vindex2)) ? 1 : 0; + mainEdgeCount += mainEdgeSet.Contains(DataUtility.Pack32Sort(vindex1, vindex2)) ? 1 : 0; + if (mainEdgeCount == 0) + continue; + + // トライアングル生成 + int3 tri = DataUtility.PackInt3(i, vindex1, vindex2); + + if (triangleSet.Contains(tri) == false) + { + //Debug.Log($"v:{i}, Tri:{tri}"); + triangleSet.Add(tri); + + // このトライアングルで利用されたエッジを記録 + triangleEdgeSet.Add(DataUtility.PackInt2(i, vindex1)); + triangleEdgeSet.Add(DataUtility.PackInt2(i, vindex2)); + } + } + } + } + } + + // トライアングル登録 + if (triangleSet.Count > 0) + { + triangles = new ExSimpleNativeArray(triangleSet.Count); + int index = 0; + foreach (int3 tri in triangleSet) + { + //Debug.Log($"Tri:{tri}"); + triangles[index] = tri; + index++; + } + } + + // ライン登録 + // トライアングルに利用されなかったエッジのみ登録 + foreach (int2 edge in triangleEdgeSet) + { + edgeSet.Remove(edge); + } + if (edgeSet.Count > 0) + { + lines = new ExSimpleNativeArray(edgeSet.Count); + int index = 0; + foreach (int2 line in edgeSet) + { + //Debug.Log($"Line:{line}"); + lines[index] = line; + index++; + } + } + } + } + + [BurstCompile] + struct Import_BoneVertexJob : IJobParallelFor + { + public float4x4 WtoL; + public float4x4 LtoW; + + [Unity.Collections.ReadOnly] + public NativeArray transformPositions; + [Unity.Collections.ReadOnly] + public NativeArray transformRotations; + [Unity.Collections.ReadOnly] + public NativeArray transformScales; + + [Unity.Collections.WriteOnly] + public NativeArray localPositions; + [Unity.Collections.WriteOnly] + public NativeArray localNormals; + [Unity.Collections.WriteOnly] + public NativeArray localTangents; + [Unity.Collections.WriteOnly] + public NativeArray boneWeights; + [Unity.Collections.WriteOnly] + public NativeArray skinBoneBindPoses; + + public void Execute(int vindex) + { + // トランスフォーム姿勢 + float3 pos = transformPositions[vindex]; + quaternion rot = transformRotations[vindex]; + float3 scl = transformScales[vindex]; + + // トランスフォーム姿勢をクロスローカル空間に変換する + // オリジナル +#if true + float3 lpos = MathUtility.InverseTransformPoint(pos, WtoL); + float3 lnor, ltan; + lnor = math.mul(rot, math.up()); + ltan = math.mul(rot, math.forward()); + lnor = MathUtility.InverseTransformDirection(lnor, WtoL); + ltan = MathUtility.InverseTransformDirection(ltan, WtoL); +#endif + //Debug.Log($"Import [{vindex}] lpos:{lpos}, lnor:{lnor}, ltan:{ltan}"); + + localPositions[vindex] = lpos; + localNormals[vindex] = lnor; + localTangents[vindex] = ltan; + + // bone weight + var bw = new VirtualMeshBoneWeight(new int4(vindex, 0, 0, 0), new float4(1, 0, 0, 0)); + boneWeights[vindex] = bw; + + // bind pose + var ltow = float4x4.TRS(pos, rot, scl); + var wtol = math.inverse(ltow); + var bindPose = math.mul(wtol, LtoW); + skinBoneBindPoses[vindex] = bindPose; + } + } + + + /// + /// レンダーデータからインポートする + /// + /// + public void ImportFrom(RenderData renderData, int uvChannel) + { + try + { + if (renderData == null) + { + result.SetError(Define.Result.VirtualMesh_InvalidRenderData); + throw new MagicaClothProcessingException(); + } + + ImportFrom(renderData.setupData, uvChannel); + } + catch (MagicaClothProcessingException) + { + if (result.IsError() == false) + result.SetError(Define.Result.VirtualMesh_ImportError); + throw; + } + catch (Exception) + { + //Debug.LogException(e); + result.SetError(Define.Result.VirtualMesh_ImportError); + throw; + } + } + + //========================================================================================= + /// + /// セレクションデータをもとにメッシュを切り取る(スレッド可) + /// セレクションデータの移動属性に影響するトライアングルのみを摘出する + /// 結果的にメッシュの頂点/トライアングル数が0になる場合もあるので注意! + /// + /// + /// セレクションデータの基準姿勢 + /// 検索距離 + public void SelectionMesh( + SelectionData selectionData, + float4x4 selectionLocalToWorldMatrix, + float mergin + ) + { + try + { + if (selectionData == null || selectionData.IsValid() == false) + { + result.SetError(Define.Result.VirtualMesh_InvalidSelection); + throw new MagicaClothProcessingException(); + } + + // ジョブ作業用 + int selectionCount = selectionData.Count; + using var selectionPositions = selectionData.GetPositionNativeArray(); + using var selectionAttribues = selectionData.GetAttributeNativeArray(); + + // 座標空間が異なる場合はセレクションデータをメッシュ空間に合わせる + bool sameSpace = MathUtility.CompareMatrix(selectionLocalToWorldMatrix, initLocalToWorld); + if (sameSpace == false) + { + // 座標変換 + var toM = MathUtility.Transform(selectionLocalToWorldMatrix, initWorldToLocal); + JobUtility.TransformPositionRun(selectionPositions, selectionCount, toM); + } + + //Develop.DebugLog($"sameSpace:{sameSpace}"); + Develop.DebugLog($"Selection.mergin:{mergin}"); + + // セレクションデータを配置したグリッドマップを作成する + float gridSize = mergin * 1.0f; + using var gridMap = SelectionData.CreateGridMapRun(gridSize, selectionPositions, selectionAttribues, move: true, fix: true, ignore: true, invalid: false); + + // 移動ポイントから利用するトライアングルと頂点情報を選別する + using var newTriangleList = new NativeList(TriangleCount, Allocator.Persistent); + using var newVertexRemapIndices = new NativeArray(VertexCount, Allocator.Persistent); + using var newVertexCount = new NativeReference(Allocator.Persistent); + var selectGridJob = new Select_GridJob() + { + gridSize = gridSize, + gridMap = gridMap.GetMultiHashMap(), + + selectionCount = selectionCount, + selectionPositions = selectionPositions, + selectionAttributes = selectionAttribues, + + vertexCount = VertexCount, + triangleCount = TriangleCount, + searchRadius = mergin, + meshPositions = localPositions.GetNativeArray(), + meshTriangles = triangles.GetNativeArray(), + + newTriangles = newTriangleList, + newVertexRemapIndices = newVertexRemapIndices, + newVertexCount = newVertexCount, + }; + selectGridJob.Run(); + + // 結果的に有効な頂点が減った場合は頂点およびトライアングル情報を再構築する + if (newVertexCount.Value < VertexCount) + { + // 頂点情報を入れ替える + int nvcnt = newVertexCount.Value; + var newReferenceIndices = new ExSimpleNativeArray(nvcnt); + var newAttributes = new ExSimpleNativeArray(nvcnt); + var newLocalPositions = new ExSimpleNativeArray(nvcnt); + var newLocalNormals = new ExSimpleNativeArray(nvcnt); + var newLocalTangents = new ExSimpleNativeArray(nvcnt); + var newUv = new ExSimpleNativeArray(nvcnt); + var newBoneWeights = new ExSimpleNativeArray(nvcnt); + + var packVertexJob = new Select_PackVertexJob() + { + vertexCount = VertexCount, + newVertexRemapIndices = newVertexRemapIndices, + + attributes = attributes.GetNativeArray(), + localPositions = localPositions.GetNativeArray(), + localNormals = localNormals.GetNativeArray(), + localTangents = localTangents.GetNativeArray(), + uv = uv.GetNativeArray(), + boneWeights = boneWeights.GetNativeArray(), + + newReferenceIndices = newReferenceIndices.GetNativeArray(), + newAttributes = newAttributes.GetNativeArray(), + newLocalPositions = newLocalPositions.GetNativeArray(), + newLocalNormals = newLocalNormals.GetNativeArray(), + newLocalTangents = newLocalTangents.GetNativeArray(), + newUv = newUv.GetNativeArray(), + newBoneWeights = newBoneWeights.GetNativeArray(), + + }; + packVertexJob.Run(); + + referenceIndices.Dispose(); + attributes.Dispose(); + localPositions.Dispose(); + localNormals.Dispose(); + localTangents.Dispose(); + uv.Dispose(); + boneWeights.Dispose(); + + referenceIndices = newReferenceIndices; + attributes = newAttributes; + localPositions = newLocalPositions; + localNormals = newLocalNormals; + localTangents = newLocalTangents; + uv = newUv; + boneWeights = newBoneWeights; + + // トライアングル情報を入れ替える + var newTriangles = new ExSimpleNativeArray(newTriangleList); + triangles.Dispose(); + triangles = newTriangles; + } + } + catch (MagicaClothProcessingException) + { + if (result.IsError() == false) + result.SetError(Define.Result.VirtualMesh_SelectionUnknownError); + result.DebugLog(); + } + catch (Exception exception) + { + Debug.LogException(exception); + result.SetError(Define.Result.VirtualMesh_SelectionException); + } + finally + { + } + } + + [BurstCompile] + struct Select_PackVertexJob : IJob + { + public int vertexCount; + [Unity.Collections.ReadOnly] + public NativeArray newVertexRemapIndices; + + [Unity.Collections.ReadOnly] + public NativeArray attributes; + [Unity.Collections.ReadOnly] + public NativeArray localPositions; + [Unity.Collections.ReadOnly] + public NativeArray localNormals; + [Unity.Collections.ReadOnly] + public NativeArray localTangents; + [Unity.Collections.ReadOnly] + public NativeArray uv; + [Unity.Collections.ReadOnly] + public NativeArray boneWeights; + + [Unity.Collections.WriteOnly] + public NativeArray newReferenceIndices; + [Unity.Collections.WriteOnly] + public NativeArray newAttributes; + [Unity.Collections.WriteOnly] + public NativeArray newLocalPositions; + [Unity.Collections.WriteOnly] + public NativeArray newLocalNormals; + [Unity.Collections.WriteOnly] + public NativeArray newLocalTangents; + [Unity.Collections.WriteOnly] + public NativeArray newUv; + [Unity.Collections.WriteOnly] + public NativeArray newBoneWeights; + + public void Execute() + { + // 頂点パッキング + for (int i = 0; i < vertexCount; i++) + { + int remapIndex = newVertexRemapIndices[i]; + if (remapIndex >= 0) + { + newReferenceIndices[remapIndex] = i; // 元のインデックス + newAttributes[remapIndex] = attributes[i]; + newLocalPositions[remapIndex] = localPositions[i]; + newLocalNormals[remapIndex] = localNormals[i]; + newLocalTangents[remapIndex] = localTangents[i]; + newUv[remapIndex] = uv[i]; + newBoneWeights[remapIndex] = boneWeights[i]; + } + } + } + } + + [BurstCompile] + struct Select_GridJob : IJob + { + public float gridSize; + [Unity.Collections.ReadOnly] + public NativeParallelMultiHashMap gridMap; + + public int selectionCount; + [Unity.Collections.ReadOnly] + public NativeArray selectionPositions; + [Unity.Collections.ReadOnly] + public NativeArray selectionAttributes; + + public int vertexCount; + public int triangleCount; + public float searchRadius; + [Unity.Collections.ReadOnly] + public NativeArray meshPositions; + [Unity.Collections.ReadOnly] + public NativeArray meshTriangles; + + public NativeList newTriangles; + public NativeArray newVertexRemapIndices; + [Unity.Collections.WriteOnly] + public NativeReference newVertexCount; + + public void Execute() + { + // (1)移動ポイントの一定距離にあるメッシュ頂点をマークする + for (int vindex = 0; vindex < vertexCount; vindex++) + { + var pos = meshPositions[vindex]; + var remapIndex = -1; + +#if true + // 範囲グリッド走査 + // 範囲内に無効以外のポイントがある場合は有効になる + foreach (int3 grid in GridMap.GetArea(pos, searchRadius, gridMap, gridSize)) + { + if (gridMap.ContainsKey(grid) == false) + continue; + + // このグリッドを検索する + foreach (int sindex in gridMap.GetValuesForKey(grid)) + { + // 距離判定 + float3 spos = selectionPositions[sindex]; + float dist = math.distance(pos, spos); + if (dist > searchRadius) + continue; + + // この頂点は利用する + remapIndex = 1; + break; + } + + if (remapIndex >= 0) + break; + } +#endif +#if false + // 頂点に最も近いセレクション属性を調べる + // (1)一定範囲内にmove/fixed/ignoreがある場合は利用する + var nearAttr = VertexAttribute.Invalid; + float nearDist = float.MaxValue; + bool nearMove = false; // 一定範囲内に移動頂点が存在するかどうか + // 範囲グリッド走査 + foreach (int3 grid in GridMap.GetArea(pos, searchRadius, gridMap, gridSize)) + { + if (gridMap.ContainsKey(grid) == false) + continue; + + // このグリッドを検索する + foreach (int sindex in gridMap.GetValuesForKey(grid)) + { + // 距離判定 + float3 spos = selectionPositions[sindex]; + float dist = math.distance(pos, spos); + var attr = selectionAttributes[sindex]; + + // 最も近い属性 + if (dist < nearDist) + { + nearDist = dist; + nearAttr = attr; + } + + // 特定範囲内に移動属性が存在するかどうか + if (dist <= searchRadius && attr.IsMove()) + { + nearMove = true; + } + } + } + // 最も近い属性により利用判定する + if (nearAttr.IsInvalid() == false) + { + // move/fixed/ignoreは利用する + remapIndex = 1; + } + else + { + // 無効頂点の場合は一定範囲内に移動頂点がある場合のみ固定として利用する + if (nearMove) + remapIndex = 1; + } +#endif + + newVertexRemapIndices[vindex] = remapIndex; + } + + // (2)有効な頂点を含むトライアングルを摘出する + for (int tindex = 0; tindex < triangleCount; tindex++) + { + int3 tri = meshTriangles[tindex]; + if (newVertexRemapIndices[tri.x] >= 0 || newVertexRemapIndices[tri.y] >= 0 || newVertexRemapIndices[tri.z] >= 0) + { + // このトライアングルは利用する + newTriangles.Add(tri); + } + } + + // (3)有効トライアングルを利用する頂点に使用フラグをつける + int ntcnt = newTriangles.Length; + for (int i = 0; i < ntcnt; i++) + { + int3 tri = newTriangles[i]; + + // 頂点利用マーク + newVertexRemapIndices[tri.x] = 1; + newVertexRemapIndices[tri.y] = 1; + newVertexRemapIndices[tri.z] = 1; + } + + // (4)使用頂点のリマップインデックスを作成する + int newIndex = 0; + for (int i = 0; i < vertexCount; i++) + { + int remapIndex = newVertexRemapIndices[i]; + if (remapIndex >= 0) + { + // この頂点は使用する + newVertexRemapIndices[i] = newIndex; + newIndex++; + } + } + // 残った利用頂点数 + newVertexCount.Value = newIndex; + + // (5)トライアングル頂点をリマップする + int newTriCount = newTriangles.Length; + for (int i = 0; i < newTriCount; i++) + { + int3 tri = newTriangles[i]; + tri.x = newVertexRemapIndices[tri.x]; + tri.y = newVertexRemapIndices[tri.y]; + tri.z = newVertexRemapIndices[tri.z]; + newTriangles[i] = tri; + } + } + } + + /// + /// 現在のメッシュに対して最適なセレクションの余白距離を算出する + /// + /// + /// + /// + public float CalcSelectionMergin(ReductionSettings settings) + { + float aveDist = averageVertexDistance.Value; + float reductionDist = 0; + if (settings != null && settings.IsEnabled) + { + reductionDist = boundingBox.Value.MaxSideLength * settings.GetMaxConnectionDistance(); + } + + // 大きい方を採用 + float mergin = math.max(aveDist, reductionDist); + + // 大きめにする + //mergin *= 2.0f; + mergin *= 1.5f; + + // 少し小さくする + //mergin *= 0.7f; + + return mergin; + } + + + //========================================================================================= + /// + /// メッシュを追加する(スレッド可) + /// + /// + public void AddMesh(VirtualMesh cmesh) + { + try + { + if (IsError) + throw new InvalidOperationException(); + + if (cmesh == null || cmesh.IsSuccess == false || cmesh.IsError) + throw new InvalidOperationException(); + + // 実行前状態 + int skinBoneStart = SkinBoneCount; + int vertexStart = VertexCount; + int triangleStart = TriangleCount; + int lineStart = LineCount; + int transformStart = transformData.Count; + + // 追加メッシュの座標空間を変換するマトリックス + float4x4 toM = cmesh.CenterTransformTo(this); + + // スキンボーンのトランスフォームを登録する + int skinBoneCount = cmesh.SkinBoneCount; + skinBoneTransformIndices.AddRange(skinBoneCount); + for (int i = 0; i < skinBoneCount; i++) + { + int stindex = cmesh.skinBoneTransformIndices[i]; + // 重複を弾いて追加する + int tindex = transformData.AddTransform(cmesh.transformData, stindex, checkDuplicate: true); + skinBoneTransformIndices[skinBoneStart + i] = tindex; + } + + // 結合範囲 + int vcnt = cmesh.VertexCount; + cmesh.mergeChunk = new DataChunk(VertexCount, vcnt); + + // 領域確保 + attributes.AddRange(vcnt); + localPositions.AddRange(vcnt); + localNormals.AddRange(vcnt); + localTangents.AddRange(vcnt); + uv.AddRange(vcnt); + boneWeights.AddRange(vcnt); + + // 追加メッシュの座標を追加先のローカル空間に変換してコピーする + var copyVerticesJob = new Add_CopyVerticesJob() + { + vertexOffset = vertexStart, + skinBoneOffset = skinBoneStart, + + toM = toM, + + // 追加メッシュ + srcAttributes = cmesh.attributes.GetNativeArray(), + srclocalPositions = cmesh.localPositions.GetNativeArray(), + srclocalNormals = cmesh.localNormals.GetNativeArray(), + srclocalTangents = cmesh.localTangents.GetNativeArray(), + srcUV = cmesh.uv.GetNativeArray(), + srcBoneWeights = cmesh.boneWeights.GetNativeArray(), + + // 追加先 + dstAttributes = attributes.GetNativeArray(), + dstlocalPositions = localPositions.GetNativeArray(), + dstlocalNormals = localNormals.GetNativeArray(), + dstlocalTangents = localTangents.GetNativeArray(), + dstUV = uv.GetNativeArray(), + dstBoneWeights = boneWeights.GetNativeArray(), + dstSkinBoneIndices = skinBoneTransformIndices.GetNativeArray(), + }; + copyVerticesJob.Run(cmesh.VertexCount); + + + // skin bone bindpose + { + // このメッシュの座標空間に合わせてバインドポーズを再計算する + skinBoneBindPoses.AddRange(skinBoneCount); + var job = new Add_CalcBindPoseJob() + { + skinBoneOffset = skinBoneStart, + srcSkinBoneTransformIndices = cmesh.skinBoneTransformIndices.GetNativeArray(), + srcTransformPositionArray = cmesh.transformData.positionArray.GetNativeArray(), + srcTransformRotationArray = cmesh.transformData.rotationArray.GetNativeArray(), + srcTransformScaleArray = cmesh.transformData.scaleArray.GetNativeArray(), + dstCenterLocalToWorldMatrix = initLocalToWorld, + dstSkinBoneBindPoses = skinBoneBindPoses.GetNativeArray(), + }; + job.Run(skinBoneCount); + } + + // triangle + if (cmesh.TriangleCount > 0) + { + // add copy + triangles.AddRange(cmesh.TriangleCount); + var copyTriangleJob = new JobUtility.AddInt3DataCopyJob() + { + dstOffset = triangleStart, + addData = vertexStart, + srcData = cmesh.triangles.GetNativeArray(), + dstData = triangles.GetNativeArray(), + }; + copyTriangleJob.Run(cmesh.TriangleCount); + } + + // line + if (cmesh.LineCount > 0) + { + // add copy + lines.AddRange(cmesh.LineCount); + var copyLineJob = new JobUtility.AddInt2DataCopyJob() + { + dstOffset = lineStart, + addData = vertexStart, + srcData = cmesh.lines.GetNativeArray(), + dstData = lines.GetNativeArray(), + }; + copyLineJob.Run(cmesh.LineCount); + } + + // bounding box + // プロキシメッシュ空間に変換して追加 + float3 bmin = cmesh.boundingBox.Value.Min; + float3 bmax = cmesh.boundingBox.Value.Max; + bmin = math.transform(toM, bmin); + bmax = math.transform(toM, bmax); + var aabb = new AABB(bmin, bmax); + if (boundingBox.IsCreated) + { + var bounds = boundingBox.Value; + bounds.Encapsulate(aabb); + boundingBox.Value = bounds; + } + else + boundingBox = new NativeReference(aabb, Allocator.Persistent); + //Develop.DebugLog($"merge boundingBox:{boundingBox.Value}"); + + // 頂点間距離 + // プロキシメッシュ空間に変換し大きい方を採用する + float scaleRatio = math.length(cmesh.initScale) / math.length(initScale); + //Debug.Log($"cmesh.initScale:{cmesh.initScale}, proxyMesh.initScale:{initScale}, scaleRatio:{scaleRatio}"); + averageVertexDistance.Value = math.max(averageVertexDistance.Value, cmesh.averageVertexDistance.Value * scaleRatio); + maxVertexDistance.Value = math.max(maxVertexDistance.Value, cmesh.maxVertexDistance.Value * scaleRatio); + + +#if false + // test + int maxBoneIndex = 0; + for (int i = 0; i < VertexCount; i++) + { + var bw = boneWeights[i]; + for (int j = 0; j < 4; j++) + { + if (bw.weights[j] > 0.0f) + maxBoneIndex = math.max(maxBoneIndex, bw.boneIndices[j]); + } + } + Debug.Log($"MaxBoneIndex:{maxBoneIndex}"); +#endif + } + catch (Exception e) + { + Debug.LogException(e); + result.SetError(); + throw; + } + finally + { + } + } + + /// + /// 空間が変更された場合はバインドポーズを再計算する + /// + [BurstCompile] + struct Add_CalcBindPoseJob : IJobParallelFor + { + public int skinBoneOffset; + + [Unity.Collections.ReadOnly] + public NativeArray srcSkinBoneTransformIndices; + [Unity.Collections.ReadOnly] + public NativeArray srcTransformPositionArray; + [Unity.Collections.ReadOnly] + public NativeArray srcTransformRotationArray; + [Unity.Collections.ReadOnly] + public NativeArray srcTransformScaleArray; + + public float4x4 dstCenterLocalToWorldMatrix; + + [NativeDisableParallelForRestriction] + [Unity.Collections.WriteOnly] + public NativeArray dstSkinBoneBindPoses; + + public void Execute(int boneIndex) + { + // 空間が変更された場合はバインドポーズを再計算する必要がある + int srcIndex = srcSkinBoneTransformIndices[boneIndex]; + var tpos = srcTransformPositionArray[srcIndex]; + var trot = srcTransformRotationArray[srcIndex]; + var tscl = srcTransformScaleArray[srcIndex]; + + var ltow = float4x4.TRS(tpos, trot, tscl); + var wtol = math.inverse(ltow); + + var bindPose = math.mul(wtol, dstCenterLocalToWorldMatrix); + dstSkinBoneBindPoses[skinBoneOffset + boneIndex] = bindPose; + } + } + + /// + /// 頂点データを新しい領域にコピーする + /// + [BurstCompile] + struct Add_CopyVerticesJob : IJobParallelFor + { + public int vertexOffset; + public int skinBoneOffset; + + // 座標空間変換 + //public int same; // 追加先と同じ空間なら(1) + public float4x4 toM; + + // src + //[Unity.Collections.ReadOnly] + //public NativeArray srcFlags; + [Unity.Collections.ReadOnly] + public NativeArray srcAttributes; + //[Unity.Collections.ReadOnly] + //public NativeArray srcWorldPositions; + //[Unity.Collections.ReadOnly] + //public NativeArray srcWorldRotations; + [Unity.Collections.ReadOnly] + public NativeArray srclocalPositions; + [Unity.Collections.ReadOnly] + public NativeArray srclocalNormals; + [Unity.Collections.ReadOnly] + public NativeArray srclocalTangents; + [Unity.Collections.ReadOnly] + public NativeArray srcUV; + [Unity.Collections.ReadOnly] + public NativeArray srcBoneWeights; + + // dst + //[NativeDisableParallelForRestriction] + //[Unity.Collections.WriteOnly] + //public NativeArray dstFlags; + [NativeDisableParallelForRestriction] + [Unity.Collections.WriteOnly] + public NativeArray dstAttributes; + [NativeDisableParallelForRestriction] + [Unity.Collections.WriteOnly] + public NativeArray dstlocalPositions; + [NativeDisableParallelForRestriction] + [Unity.Collections.WriteOnly] + public NativeArray dstlocalNormals; + [NativeDisableParallelForRestriction] + [Unity.Collections.WriteOnly] + public NativeArray dstlocalTangents; + [NativeDisableParallelForRestriction] + [Unity.Collections.WriteOnly] + public NativeArray dstUV; + [NativeDisableParallelForRestriction] + [Unity.Collections.WriteOnly] + public NativeArray dstBoneWeights; + [Unity.Collections.ReadOnly] + public NativeArray dstSkinBoneIndices; + + public void Execute(int vindex) + { + int dindex = vertexOffset + vindex; + + // positin / normal + //float3 wpos = srcWorldPositions[vindex]; + //quaternion wrot = srcWorldRotations[vindex]; + //float3 wnor = MathUtility.ToNormal(wrot); + //float3 wtan = MathUtility.ToTangent(wrot); + float3 lpos = srclocalPositions[vindex]; + float3 lnor = srclocalNormals[vindex]; + float3 ltan = srclocalTangents[vindex]; + //if (same == 0) + //{ + // // 座標空間が異なるのでコンバートする + // lpos = MathUtility.TransformPoint(lpos, toM); + // lnor = MathUtility.TransformDirection(lnor, toM); + // ltan = MathUtility.TransformDirection(ltan, toM); + //} + + // ローカル変換 + //float3 lpos = MathUtility.TransformPoint(wpos, toM); + //float3 lnor = MathUtility.TransformDirection(wnor, toM); + //float3 ltan = MathUtility.TransformDirection(wtan, toM); + + // 座標空間の変換 + lpos = MathUtility.TransformPoint(lpos, toM); + lnor = MathUtility.TransformDirection(lnor, toM); + ltan = MathUtility.TransformDirection(ltan, toM); + + dstlocalPositions[dindex] = lpos; + dstlocalNormals[dindex] = lnor; + dstlocalTangents[dindex] = ltan; + dstUV[dindex] = srcUV[vindex]; + + // boneWeights + if (vindex < srcBoneWeights.Length) + { + var bw = srcBoneWeights[vindex]; + bw.boneIndices += skinBoneOffset; + + // boneIndexの重複がないようにより若いインデックスに組み替える + for (int i = 0; i < 4; i++) + { + if (bw.weights[i] < 1e-06f) + continue; + + int bindex = bw.boneIndices[i]; + int tindex = dstSkinBoneIndices[bindex]; + for (int j = 0; j < bindex; j++) + { + if (dstSkinBoneIndices[j] == tindex) + { + // 組み換え + bw.boneIndices[i] = j; + break; + } + } + } + + dstBoneWeights[dindex] = bw; + } + + // attribute + dstAttributes[dindex] = srcAttributes[vindex]; + + // flag + //dstFlags[dindex] = srcFlags[vindex]; + } + } + + //========================================================================================= + /// + /// メッシュの基準トランスフォームを設定する(メインスレッドのみ) + /// + /// + /// 不要ならnull + /// 不要ならInvalid + /// 不要ならInvalid + //public void SetTransform(Transform center, Transform skinRoot = null, int centerId = 0, int skinRootId = 0) + public void SetTransform(Transform center, Transform skinRoot, MagicaObjectId centerId, MagicaObjectId skinRootId) + { + SetCenterTransform(center, centerId); + if (skinRoot != null) + SetSkinRoot(skinRoot, skinRootId); + else + SetSkinRoot(center, centerId); + + // 基準トランスフォーム情報を記録 + initLocalToWorld = center.localToWorldMatrix; + initWorldToLocal = math.inverse(initLocalToWorld); + initRotation = center.rotation; + initInverseRotation = math.inverse(initRotation); + initScale = center.lossyScale; + } + + /// + /// レコード情報からメッシュの基準トランスフォームを設定する(スレッド可) + /// + /// + public void SetTransform(TransformRecord centerRecord, TransformRecord skinRootRecord = null) + { + centerTransformIndex = transformData.AddTransform(centerRecord, MagicaObjectId.Invalid); + if (skinRootRecord != null) + skinRootIndex = transformData.AddTransform(skinRootRecord, MagicaObjectId.Invalid); + else + skinRootIndex = centerTransformIndex; + + // 基準トランスフォーム情報を記録 + initLocalToWorld = centerRecord.localToWorldMatrix; + initWorldToLocal = centerRecord.worldToLocalMatrix; + initRotation = centerRecord.rotation; + initInverseRotation = math.inverse(initRotation); + initScale = centerRecord.scale; + } + + //public void SetCenterTransform(Transform t, int tid = 0) + public void SetCenterTransform(Transform t, MagicaObjectId tid) + { + if (t) + { + // すでに存在する場合は入れ替え + if (centerTransformIndex >= 0) + { + transformData.ReplaceTransform(centerTransformIndex, t, tid, MagicaObjectId.Invalid); + } + else + { + centerTransformIndex = transformData.AddTransform(t, tid, MagicaObjectId.Invalid); + } + } + } + + //public void SetSkinRoot(Transform t, int tid = 0) + public void SetSkinRoot(Transform t, MagicaObjectId tid) + { + if (t) + { + // すでに存在する場合は入れ替え + if (skinRootIndex >= 0) + { + transformData.ReplaceTransform(skinRootIndex, t, tid, MagicaObjectId.Invalid); + } + else + { + skinRootIndex = transformData.AddTransform(t, tid, MagicaObjectId.Invalid); + } + } + } + + public Transform GetCenterTransform() + { + return transformData.GetTransformFromIndex(centerTransformIndex); + } + + /// + /// カスタムスキニング用ボーンを登録する + /// + /// + public void SetCustomSkinningBones(TransformRecord clothTransformRecord, List bones) + { + if (bones == null || bones.Count == 0) + return; + + customSkinningBoneIndices = new int[bones.Count]; + for (int i = 0; i < bones.Count; i++) + { + var rd = bones[i]; + int index = -1; + if (rd.IsValid()) + { + // クロストランスフォームのローカル空間に変換して登録する + rd.localPosition = clothTransformRecord.worldToLocalMatrix.MultiplyPoint(rd.position); + + // ボーンの登録。スキニング用ボーンとしても登録。 + index = skinBoneTransformIndices.Count; + int tindex = transformData.AddTransform(rd, pid: MagicaObjectId.Invalid, checkDuplicate: false); // 重複ありで最後に追加する + skinBoneTransformIndices.Add(tindex); + var bindPose = math.mul(rd.worldToLocalMatrix, initLocalToWorld); // bind pose + skinBoneBindPoses.Add(bindPose); + } + customSkinningBoneIndices[i] = index; + } + } + + /// + /// このメッシュと対象メッシュの座標空間が同じか判定する + /// これはそれぞれ初期化時のマトリックスで比較される + /// + /// + /// + public bool CompareSpace(VirtualMesh target) + { + return MathUtility.CompareMatrix(initLocalToWorld, target.initLocalToWorld); + } + + /// + /// このメッシュの座標空間をtoメッシュの座標空間に変換するマトリックスを返す + /// これはそれぞれ初期化時のマトリックスで計算される + /// + /// + /// + public float4x4 CenterTransformTo(VirtualMesh to) + { + bool sameSpace = CompareSpace(to); + return sameSpace ? float4x4.identity : MathUtility.Transform(initLocalToWorld, to.initWorldToLocal); + } + + //========================================================================================= +#if false + /// + /// UnityMeshに出力する(メインスレッドのみ) + /// ※ほぼデバッグ用 + /// + /// + public Mesh ExportToMesh(bool buildSkinning = false, bool recalculationNormals = false, bool recalculationBounds = true) + { + Debug.Assert(IsSuccess); + + var mesh = new Mesh(); + mesh.MarkDynamic(); + + // vertices + var newVertices = new Vector3[VertexCount]; + var newNormals = new Vector3[VertexCount]; + localPositions.CopyTo(newVertices); + localNormals.CopyTo(newNormals); + + // 接線はwを(-1)にして書き込む + using var tangentArray = new NativeArray(VertexCount, Allocator.TempJob); + JobUtility.FillRun(tangentArray, VertexCount, new Vector4(0, 0, 0, -1)); + var newTangents = tangentArray.ToArray(); + localTangents.CopyToWithTypeChangeStride(newTangents); // float3[] -> Vector4[]コピー + + mesh.vertices = newVertices; + if (recalculationNormals == false) + mesh.normals = newNormals; + mesh.tangents = newTangents; + + // dymmy uv + var newUvs = new Vector2[VertexCount]; + uv.CopyTo(newUvs); // 一応コピー(VirtualMeshのUVはTangent計算用、テクスチャマッピング用ではない) + mesh.uv = newUvs; + + // triangle + if (TriangleCount > 0) + { + var newTriangles = new int[TriangleCount * 3]; + triangles.CopyToWithTypeChange(newTriangles); + mesh.triangles = newTriangles; + } + + // skinning + if (buildSkinning) + { + // bone weight + var newBoneWeights = new BoneWeight[VertexCount]; + boneWeights.CopyTo(newBoneWeights); + mesh.boneWeights = newBoneWeights; + + // bind poses + var newBindPoses = new Matrix4x4[SkinBoneCount]; + skinBoneBindPoses.CopyTo(newBindPoses); + mesh.bindposes = newBindPoses; + } + + if (recalculationNormals) + mesh.RecalculateNormals(); + //mesh.RecalculateTangents(); + if (recalculationBounds) + mesh.RecalculateBounds(); + + + return mesh; + } +#endif + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/VirtualMesh/Function/VirtualMeshInputOutput.cs.meta b/Assets/MagicaCloth2/Scripts/Core/VirtualMesh/Function/VirtualMeshInputOutput.cs.meta new file mode 100644 index 00000000..7ff557e7 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/VirtualMesh/Function/VirtualMeshInputOutput.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 3acc8678caf149b42977b7b3d3e8079b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/VirtualMesh/Function/VirtualMeshInputOutput.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/VirtualMesh/Function/VirtualMeshMapping.cs b/Assets/MagicaCloth2/Scripts/Core/VirtualMesh/Function/VirtualMeshMapping.cs new file mode 100644 index 00000000..9b069fb6 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/VirtualMesh/Function/VirtualMeshMapping.cs @@ -0,0 +1,710 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using System; +using Unity.Burst; +using Unity.Collections; +using Unity.Jobs; +using Unity.Mathematics; +using UnityEngine; + +namespace MagicaCloth2 +{ + public partial class VirtualMesh + { + struct MappingWorkData + { + public float3 position; + public int vertexIndex; + public int proxyVertexIndex; + public float proxyVertexDistance; + } + + /// + /// メッシュをプロキシメッシュにマッピングする(スレッド可) + /// + /// + public void Mapping(VirtualMesh proxyMesh) + { + try + { + if (IsError) + { + throw new MagicaClothProcessingException(); + } + + if (proxyMesh == null || proxyMesh.IsSuccess == false) + { + result.SetError(Define.Result.MappingMesh_ProxyError); + throw new MagicaClothProcessingException(); + } + + // 処理中に切り替え + result.SetProcess(); + + // このマッピングメッシュのローカル座標をプロキシメッシュ空間に変換するマトリックスを求める + var toP = CenterTransformTo(proxyMesh); + + // 頂点をプロキシメッシュのどの頂点にマッピングすべきかの情報 + using var mappingWorkData = new NativeArray(VertexCount, Allocator.Persistent); + + if (mergeChunk.IsValid) + { + // ■ダイレクトマッピング(プロキシメッシュに利用されたメッシュの場合) + // リダクション結果から接続するので確実で速い! + Develop.DebugLog($"Direct Mapping!"); + var directConnectionJob = new Mapping_DirectConnectionVertexDataJob() + { + toP = toP, + vcnt = VertexCount, + mergeChunk = mergeChunk, + localPositions = localPositions.GetNativeArray(), + attributes = attributes.GetNativeArray(), + + joinIndices = proxyMesh.joinIndices, + proxyAttributes = proxyMesh.attributes.GetNativeArray(), + proxyLocalPositions = proxyMesh.localPositions.GetNativeArray(), + + mappingWorkData = mappingWorkData, + }; + directConnectionJob.Run(); + + // 頂点マッピング + // 平均接続距離 + var avgDist = proxyMesh.averageVertexDistance.Value; + float weightLength = avgDist * 1.5f; + //Debug.Log($"avgDist:{avgDist}, weightLength:{weightLength}"); + using var useSet = new NativeParallelHashSet(1024, Allocator.Persistent); // Unity2023.1.5対応 + var calcDirectWeightJob = new Mapping_CalcDirectWeightJob() + { + vcnt = mappingWorkData.Length, + weightLength = weightLength, + mappingWorkData = mappingWorkData, + + attributes = attributes.GetNativeArray(), + boneWeights = boneWeights.GetNativeArray(), + + proxyLocalPositions = proxyMesh.localPositions.GetNativeArray(), + proxyVertexToVertexIndexArray = proxyMesh.vertexToVertexIndexArray, + proxyVertexToVertexDataArray = proxyMesh.vertexToVertexDataArray, + + useSet = useSet, // Unity2023.1.5対応 + }; + calcDirectWeightJob.Run(); + } + else + { + // ■ 検索マッピング。これは精度が悪いので注意! + // 検索半径 + // これはプロキシメッシュ座標空間での長さとなる + float averageDistance = MathUtility.TransformLength(averageVertexDistance.Value, toP); + averageDistance = math.max(averageDistance, Define.System.MinimumGridSize); + float searchRadius = averageDistance * 2.5f; // test(2.0?) + Develop.DebugLog($"Search Mapping! searchRadius:{searchRadius}"); + + // プロキシ頂点インデックスを格納したグリッドマップを作成する + float gridSize = averageDistance * 1.5f; + using var gridMap = proxyMesh.CreateVertexIndexGridMapRun(gridSize); + + // 頂点をプロキシメッシュのどの頂点にマッピングすべきか判定する + var calcVertexDataJob = new Mapping_CalcConnectionVertexDataJob() + { + gridSize = gridSize, + searchRadius = searchRadius, + + toP = toP, + vcnt = VertexCount, + localPositions = localPositions.GetNativeArray(), + boneWeights = boneWeights.GetNativeArray(), + transformIds = transformData.idArray.GetNativeArray(), + attributes = attributes.GetNativeArray(), + + gridMap = gridMap.GetMultiHashMap(), + proxyAttributes = proxyMesh.attributes.GetNativeArray(), + proxyLocalPositions = proxyMesh.localPositions.GetNativeArray(), + proxyBoneWeights = proxyMesh.boneWeights.GetNativeArray(), + proxyTransformIds = proxyMesh.transformData.idArray.GetNativeArray(), + + mappingWorkData = mappingWorkData, + }; + calcVertexDataJob.Run(); + + // 頂点をマッピングする + if (mappingWorkData.Length > 0) + { + var calcWeightJob = new Mapping_CalcWeightJob() + { + mappingWorkData = mappingWorkData, + attributes = attributes.GetNativeArray(), + boneWeights = boneWeights.GetNativeArray(), + + proxyAttributes = proxyMesh.attributes.GetNativeArray(), + proxyLocalPositions = proxyMesh.localPositions.GetNativeArray(), + proxyLocalNormals = proxyMesh.localNormals.GetNativeArray(), + proxyVertexToVertexIndexArray = proxyMesh.vertexToVertexIndexArray, + proxyVertexToVertexDataArray = proxyMesh.vertexToVertexDataArray, + }; + calcWeightJob.Run(mappingWorkData.Length); + } + } + + // 接続プロキシメッシュ + mappingProxyMesh = proxyMesh; + + // プロキシメッシュへの変換マトリックスを記録 + toProxyMatrix = toP; + toProxyRotation = math.mul(proxyMesh.initInverseRotation, initRotation); + + // メッシュタイプ + meshType = MeshType.Mapping; + + // 完了 + result.SetSuccess(); + } + catch (MagicaClothProcessingException) + { + if (result.IsError() == false) + result.SetError(Define.Result.MappingMesh_UnknownError); + result.DebugLog(); + } + catch (Exception exception) + { + Debug.LogException(exception); + result.SetError(Define.Result.MappingMesh_Exception); + } + } + + [BurstCompile] + struct Mapping_DirectConnectionVertexDataJob : IJob + { + // render meshの座標をproxyのローカル空間に変換するTransform + public float4x4 toP; + + // render mesh + public int vcnt; + public DataChunk mergeChunk; + [Unity.Collections.ReadOnly] + public NativeArray localPositions; + [Unity.Collections.WriteOnly] + public NativeArray attributes; + + // proxy mesh + [Unity.Collections.ReadOnly] + public NativeArray joinIndices; + [Unity.Collections.ReadOnly] + public NativeArray proxyAttributes; + [Unity.Collections.ReadOnly] + public NativeArray proxyLocalPositions; + + // out + [Unity.Collections.WriteOnly] + public NativeArray mappingWorkData; + + public void Execute() + { + for (int vindex = 0; vindex < vcnt; vindex++) + { + // 接続プロキシメッシュ頂点インデックス + int proxyVertexIndex = joinIndices[mergeChunk.startIndex + vindex]; + + // プロキシ頂点の属性 + var proxyAttr = proxyAttributes[proxyVertexIndex]; + + // プロキシ頂点が無効ならばマッピングしない + if (proxyAttr.IsInvalid()) + { + // 頂点属性を無効としてマークする + attributes[vindex] = VertexAttribute.Invalid; + continue; + } + + // 頂点を記録 + // プロキシメッシュの座標空間に変換する + float3 pos = MathUtility.TransformPoint(localPositions[vindex], toP); + + float3 proxyPos = proxyLocalPositions[proxyVertexIndex]; + + var wdata = new MappingWorkData() + { + position = pos, + vertexIndex = vindex, + proxyVertexIndex = proxyVertexIndex, + proxyVertexDistance = math.distance(pos, proxyPos), + }; + mappingWorkData[vindex] = wdata; + attributes[vindex] = proxyAttr; + } + } + } + + [BurstCompile] + struct Mapping_CalcDirectWeightJob : IJob + { + // data + public int vcnt; + public float weightLength; + [Unity.Collections.ReadOnly] + public NativeArray mappingWorkData; + + // render mesh + [Unity.Collections.ReadOnly] + public NativeArray attributes; + [Unity.Collections.WriteOnly] + public NativeArray boneWeights; + + // proxy + [Unity.Collections.ReadOnly] + public NativeArray proxyLocalPositions; + [Unity.Collections.ReadOnly] + public NativeArray proxyVertexToVertexIndexArray; + [Unity.Collections.ReadOnly] + public NativeArray proxyVertexToVertexDataArray; + + public NativeParallelHashSet useSet; // Unity2023.1.5対応 + + public void Execute() + { + // 処理済みセット + //var useSet = new NativeParallelHashSet(1024, Allocator.Temp); // Unity2023.1.5対応 + var stack = new FixedList4096Bytes(); + + for (int vindex = 0; vindex < vcnt; vindex++) + { + // すでにInvalidなら無効 + if (attributes[vindex].IsInvalid()) + continue; + + var wdata = mappingWorkData[vindex]; + ushort pindex = (ushort)wdata.proxyVertexIndex; + + useSet.Clear(); + stack.Clear(); + + // ウエイトバッファ + var weights = new ExCostSortedList4(-1); + + stack.MC2Push(pindex); + while (stack.IsEmpty == false) + { + pindex = stack.MC2Pop(); + + if (useSet.Contains(pindex)) + continue; + useSet.Add(pindex); + + // 距離チェック + float dist = math.distance(wdata.position, proxyLocalPositions[pindex]); + if (dist > weightLength) + continue; + + // ウエイト算出 + const float weightPow = 3.0f; + //float w = Mathf.Clamp01((1.0f - dist / weightLength) + 0.001f); + float w = Mathf.Clamp01(1.0f - dist / weightLength); + w = Mathf.Pow(w, weightPow); // powのデフォルトは(3.0) + weights.Add(1.0f - w, pindex); // ExCostSortedList4は昇順格納なので一旦1.0から引く + + // 次の接続 + DataUtility.Unpack12_20(proxyVertexToVertexIndexArray[pindex], out var dcnt, out var dstart); + for (int i = 0; i < dcnt && stack.MC2IsCapacity() == false; i++) + { + ushort tindex = proxyVertexToVertexDataArray[dstart + i]; + + if (useSet.Contains(tindex)) + continue; + + // 距離チェック + dist = math.distance(wdata.position, proxyLocalPositions[tindex]); + if (dist > weightLength) + continue; + + stack.MC2Push(tindex); + } + } + + if (weights.Count == 0) + { + // 何も接続出来ない場合はデフォルトのプロキシメッシュ頂点をウエイト100%で接続させる + weights.Add(1.0f, pindex); + } + else + { + // ウエイトを合計1に調整する + int wcnt = weights.Count; + for (int i = 0; i < 4; i++) + { + if (i < wcnt) + { + // ExCostSortedList4は昇順格納なのでもとに戻す + weights.costs[i] = 1.0f - weights.costs[i]; + } + else + { + weights.costs[i] = 0; + weights.data[i] = 0; + } + } + float total = math.csum(weights.costs); + + // すべての頂点がweightLengthの場合は合計ウエイト0があり得るので特別に平均化する + if (total == 0.0f) + { + float w = 1.0f / wcnt; + for (int i = 0; i < wcnt; i++) + weights.costs[i] = w; + } + else + weights.costs = math.saturate(weights.costs / total); + } + + // ウエイト格納 + boneWeights[vindex] = new VirtualMeshBoneWeight(weights.data, weights.costs); + } + } + } + + /// + /// 頂点ごとにproxy頂点を検索しウエイト算出しboneWeightsに格納する + /// + [BurstCompile] + struct Mapping_CalcConnectionVertexDataJob : IJob + { + public float gridSize; + public float searchRadius; + + // vmeshの座標をproxyのローカル空間に変換するTransform + public float4x4 toP; + + // vmesh + public int vcnt; + [Unity.Collections.ReadOnly] + public NativeArray localPositions; + [Unity.Collections.ReadOnly] + public NativeArray boneWeights; + [Unity.Collections.ReadOnly] + public NativeArray transformIds; + [Unity.Collections.WriteOnly] + public NativeArray attributes; + + // proxy vmesh + [Unity.Collections.ReadOnly] + public NativeParallelMultiHashMap gridMap; + [Unity.Collections.ReadOnly] + public NativeArray proxyAttributes; + [Unity.Collections.ReadOnly] + public NativeArray proxyLocalPositions; + [Unity.Collections.ReadOnly] + public NativeArray proxyBoneWeights; + [Unity.Collections.ReadOnly] + public NativeArray proxyTransformIds; + + // out + [Unity.Collections.WriteOnly] + public NativeArray mappingWorkData; + + public void Execute() + { + for (int vindex = 0; vindex < vcnt; vindex++) + { + // posはproxyの座標空間に変換する + float3 pos = MathUtility.TransformPoint(localPositions[vindex], toP); + + // オリジナルのボーンウエイト + VirtualMeshBoneWeight bw = boneWeights[vindex]; + Debug.Assert(bw.IsValid); + + // もっともウエイトが重いボーンのハッシュ + MagicaObjectId boneId = transformIds[bw.boneIndices[0]]; + + + // グリッド範囲を検索する + // 同じボーンを含む最も近い頂点を1つ選択する + var nearVertex = new ExCostSortedList1(-1); + var weightVertex = new ExCostSortedList1(-1); + foreach (int3 grid in GridMap.GetArea(pos, searchRadius, gridMap, gridSize)) + { + if (gridMap.ContainsKey(grid) == false) + continue; + + foreach (int tindex in gridMap.GetValuesForKey(grid)) + { + var tpos = proxyLocalPositions[tindex]; + + // 検索距離チェック + float dist = math.distance(pos, tpos); + if (dist > searchRadius) + continue; + + // 対象頂点のウエイトにマッピング頂点のボーンが含まれているかチェックする + var tbw = proxyBoneWeights[tindex]; + Debug.Assert(tbw.IsValid); + bool hasBone = false; + for (int j = 0; j < tbw.Count && hasBone == false; j++) + { + MagicaObjectId tboneId = proxyTransformIds[tbw.boneIndices[j]]; + if (tboneId == boneId) + hasBone = true; + } + + if (hasBone) + { + // 最も近い距離のみ記録する + weightVertex.Add(dist, tindex); + } + //else + { + // ウエイト頂点が見つからない場合は最も近い頂点を記録する + nearVertex.Add(dist, tindex); + } + } + } + +#if false + // 同じボーンを含む近傍頂点を優先、見つからない場合は最も近い頂点にマッピング + var connectionVertex = weightVertex.IsValid ? weightVertex : nearVertex; +#else + // 同じボーンを含む近傍頂点を優先、見つからない場合は最も近い頂点にマッピング + // ただし距離が大きく離れる場合は近い方を優先する + ExCostSortedList1 connectionVertex = nearVertex; + if (weightVertex.IsValid && weightVertex.Cost < nearVertex.Cost * 3.0f) + { + connectionVertex = weightVertex; + } +#endif + + // 検索範囲内にまったく頂点がない場合はマッピングしない + // つまり未接続頂点となる + if (connectionVertex.IsValid == false) + { + // 頂点属性を無効としてマークする + attributes[vindex] = VertexAttribute.Invalid; + continue; + } + + // 見つかった近傍頂点の属性 + var connectionAttr = proxyAttributes[connectionVertex.Data]; + + // 近傍頂点が無効ならばマッピングしない + if (connectionAttr.IsInvalid()) + { + // 頂点属性を無効としてマークする + attributes[vindex] = VertexAttribute.Invalid; + continue; + } + + // 見つかった近傍頂点を記録 + var wdata = new MappingWorkData() + { + position = pos, + vertexIndex = vindex, + proxyVertexIndex = connectionVertex.Data, + proxyVertexDistance = connectionVertex.Cost, + }; + mappingWorkData[vindex] = wdata; + attributes[vindex] = connectionAttr; + } + } + } + + /// + /// 近傍プロキシメッシュ頂点を基準に頂点ウエイトを算出する + /// + [BurstCompile] + struct Mapping_CalcWeightJob : IJobParallelFor + { + [Unity.Collections.ReadOnly] + public NativeArray mappingWorkData; + + public NativeArray attributes; + [Unity.Collections.WriteOnly] + public NativeArray boneWeights; + + [Unity.Collections.ReadOnly] + public NativeArray proxyAttributes; + [Unity.Collections.ReadOnly] + public NativeArray proxyLocalPositions; + [Unity.Collections.ReadOnly] + public NativeArray proxyLocalNormals; + [Unity.Collections.ReadOnly] + public NativeArray proxyVertexToVertexIndexArray; + [Unity.Collections.ReadOnly] + public NativeArray proxyVertexToVertexDataArray; + + public void Execute(int vindex) + { + // すでにInvalidなら無効 + if (attributes[vindex].IsInvalid()) + return; + + var wdata = mappingWorkData[vindex]; + int pindex = wdata.proxyVertexIndex; + +#if false + // まず近傍頂点の平面にマッピング頂点を投影する + // これは異なる形状のメッシュをマッピングするときに頂点が多く離れている場合への対処 + var pos = wdata.position; + var ppos = proxyLocalPositions[pindex]; + var pnor = proxyLocalNormals[pindex]; + var v = pos - ppos; + var vlen = math.length(v); + if (vlen > 1e-06f) + { + var pv = math.project(v, pnor); + //var nlen = math.dot(v, pnor) * 0.5f; + var nlen = math.length(pv) * 0.5f; + pos = ppos + v * (vlen - nlen) / vlen; + } + float vertexDistance = math.distance(pos, ppos); +#endif +#if true + // まず近傍頂点の平面にマッピング頂点を投影する + // これは異なる形状のメッシュをマッピングするときに頂点が多く離れている場合への対処 + var pos = wdata.position; + var ppos = proxyLocalPositions[pindex]; + var pnor = proxyLocalNormals[pindex]; + var v = pos - ppos; + pos = pos - math.project(v, pnor); + float vertexDistance = math.distance(pos, ppos); +#endif +#if false + float vertexDistance = wdata.proxyVertexDistance; + var pos = wdata.position; +#endif + + + // 頂点ウエイトの計算 + // 見つかった近傍頂点から接続頂点を調べて距離の昇順に4つまで選択する + //float wradius = wdata.proxyVertexDistance * 4.0f; // 検索範囲は近傍頂点距離のxNまで + float wradius = vertexDistance * 4.0f; // 検索範囲は近傍頂点距離のxNまで + var vertexDist = new ExCostSortedList4(-1); + + // チェックは近傍頂点の接続2レベルのみとする + // ★結果:良い。最初のバージョンと結果が同じで負荷は激減した。 + vertexDist.Add(vertexDistance, pindex); + DataUtility.Unpack12_20(proxyVertexToVertexIndexArray[pindex], out var dcnt, out var dstart); + // レベル1の接続 + for (int i = 0; i < dcnt; i++) + { + int index2 = proxyVertexToVertexDataArray[dstart + i]; + if (vertexDist.Contains(index2)) + continue; + + float3 tpos = proxyLocalPositions[index2]; + + // 直線距離 + float dist = math.distance(pos, tpos); + + // 距離が範囲内なら記録 + if (dist <= wradius) + { + vertexDist.Add(dist, index2); + } + + // レベル2の接続 + DataUtility.Unpack12_20(proxyVertexToVertexIndexArray[index2], out var dcnt2, out var dstart2); + for (int j = 0; j < dcnt2; j++) + { + int index3 = proxyVertexToVertexDataArray[dstart2 + j]; + if (index3 == pindex || index3 == index2) + continue; + if (vertexDist.Contains(index3)) + continue; + + // 距離 + tpos = proxyLocalPositions[index3]; + dist = math.distance(pos, tpos); + + // 距離が範囲内なら記録 + if (dist <= wradius) + { + vertexDist.Add(dist, index3); + } + } + } + Debug.Assert(vertexDist.IsValid); + + // 近傍頂点の距離をウエイトに変換する + float4 weights = CalcVertexWeights(vertexDist.costs); + Debug.Assert(weights[0] > 0.0f); + + // ウエイトを格納する + var bw = new VirtualMeshBoneWeight(vertexDist.data, weights); + boneWeights[vindex] = bw; + + // 頂点属性 + // 近傍のプロキシ頂点の属性を受け継ぐ + //attributes[vindex] = proxyAttributes[pindex]; + // 近傍のプロキシ頂点属性にウエイトを掛けて算出する + // 移動と固定の影響力が高い方を採用する + float fixedValue = 0; + float moveValue = 0; + int wcnt = bw.Count; + for (int i = 0; i < wcnt; i++) + { + pindex = bw.boneIndices[i]; + var attr = proxyAttributes[pindex]; + if (attr.IsMove()) + moveValue += bw.weights[i]; + else if (attr.IsFixed()) + fixedValue += bw.weights[i]; + } + attributes[vindex] = moveValue > fixedValue ? VertexAttribute.Move : VertexAttribute.Fixed; + } + } + + /// + /// 距離リストからウエイト値を算出して返す + /// + /// + /// + static float4 CalcVertexWeights(float4 distances) + { + Debug.Assert(distances[0] >= 0.0f); + +#if false + // 最大距離のn%を減算する + // 最近接のウエイトを強くするため + const float lengthCut = 0.5f; + float cutdist = distances[0] * lengthCut; + distances = distances - cutdist; +#endif + + // マイナス(無効値)は0にする + distances = math.max(distances, 0); + +#if true + // 距離をn乗する + // 距離によるウエイトの減衰 + const float pow = 4.0f; // 2.0? + distances = math.pow(distances, pow); +#endif + + // 最小値の逆数にする + float min = distances[0]; + for (int i = 0; i < 4; i++) + distances[i] = distances[i] > 0.0f ? min / distances[i] : 0.0f; + + // 単位化する(1.0) + float sum = math.csum(distances); + if (sum <= 0.0f) + { + // この時点で0ならば0距離なので[0]=100%で返す + return new float4(1, 0, 0, 0); + } + distances /= sum; + + // 極小のウエイトは削除する + const float removeWeight = 0.01f; + for (int i = 3; i >= 1; i--) + { + if (distances[i] < removeWeight) + distances[i] = 0; + } + + // 再度単位化(1.0) + distances /= math.csum(distances); + + return distances; + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/VirtualMesh/Function/VirtualMeshMapping.cs.meta b/Assets/MagicaCloth2/Scripts/Core/VirtualMesh/Function/VirtualMeshMapping.cs.meta new file mode 100644 index 00000000..88648eb2 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/VirtualMesh/Function/VirtualMeshMapping.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 9f5b40e8547616f4eb331cc9fd5c5e1c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/VirtualMesh/Function/VirtualMeshMapping.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/VirtualMesh/Function/VirtualMeshOptimization.cs b/Assets/MagicaCloth2/Scripts/Core/VirtualMesh/Function/VirtualMeshOptimization.cs new file mode 100644 index 00000000..58878533 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/VirtualMesh/Function/VirtualMeshOptimization.cs @@ -0,0 +1,237 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using System; +using Unity.Burst; +using Unity.Collections; +using Unity.Jobs; +using Unity.Mathematics; +using UnityEngine; + +namespace MagicaCloth2 +{ + public partial class VirtualMesh + { + /// + /// メッシュを最適化する + /// + public void Optimization() + { + try + { + // 重複トライアングルの削除 + RemoveDuplicateTriangles(); + } + catch (Exception exception) + { + Debug.LogException(exception); + result.SetError(Define.Result.Optimize_Exception); + } + } + + /// + /// 重複するトライアングルを除去する + /// + void RemoveDuplicateTriangles() + { + if (TriangleCount < 2) + return; + + using var edgeToTriangleList = new NativeParallelHashMap>(TriangleCount * 2, Allocator.Persistent); + using var newTriangles = new NativeList(TriangleCount, Allocator.Persistent); + + using var useQuadSet = new NativeParallelHashSet(TriangleCount / 4, Allocator.Persistent); // Unity2023.1.5対応 + using var removeTriangleSet = new NativeParallelHashSet(TriangleCount / 4, Allocator.Persistent); // Unity2023.1.5対応 + + var job1 = new Optimize_EdgeToTrianlgeJob() + { + tcnt = TriangleCount, + triangles = triangles.GetNativeArray(), + localPositions = localPositions.GetNativeArray(), + edgeToTriangleList = edgeToTriangleList, + newTriangles = newTriangles, + + useQuadSet = useQuadSet, // Unity2023.1.5対応 + removeTriangleSet = removeTriangleSet, // Unity2023.1.5対応 + }; + job1.Run(); + + // 新しいトライアングルリストに入れ替える + triangles?.Dispose(); + triangles = new ExSimpleNativeArray(); + if (newTriangles.Length > 0) + { + triangles.AddRange(newTriangles); + } + } + + [BurstCompile] + struct Optimize_EdgeToTrianlgeJob : IJob + { + public int tcnt; + [Unity.Collections.ReadOnly] + public NativeArray triangles; + [Unity.Collections.ReadOnly] + public NativeArray localPositions; + + public NativeParallelHashMap> edgeToTriangleList; + [Unity.Collections.WriteOnly] + public NativeList newTriangles; + + public NativeParallelHashSet useQuadSet; // Unity2023.1.5対応 + public NativeParallelHashSet removeTriangleSet; // Unity2023.1.5対応 + + public void Execute() + { + // エッジに接続するトライアングルリストを作成する + for (int i = 0; i < tcnt; i++) + { + int3 tri = triangles[i]; + int2x3 edges = new int2x3(tri.xy, tri.yz, tri.zx); + for (int j = 0; j < 3; j++) + { + int2 edge = DataUtility.PackInt2(edges[j]); + if (edgeToTriangleList.ContainsKey(edge)) + { + var tlist = edgeToTriangleList[edge]; + if (tlist.Length < tlist.Capacity) // Capacity check + { + tlist.MC2Set(i); + edgeToTriangleList[edge] = tlist; + } + } + else + { + var tlist = new FixedList128Bytes(); + tlist.MC2Set(i); + edgeToTriangleList.Add(edge, tlist); + } + } + } + + // debug + //foreach (var kv in edgeToTriangleList) + //{ + // Debug.Log($"edge[{kv.Key}]"); + // var data = kv.Value; + // for (int i = 0; i < data.Length; i++) + // Debug.Log($":{data[i]}"); + //} + + // ほぼ水平なトライアングルペアを登録していき、ペアが重複した場合は1つをの残して削除対象とする + //var useQuadSet = new NativeParallelHashSet(tcnt / 4, Allocator.Temp); // Unity2023.1.5対応 + //var removeTriangleSet = new NativeParallelHashSet(tcnt / 4, Allocator.Temp); // Unity2023.1.5対応 + foreach (var kv in edgeToTriangleList) + { + int2 edge = kv.Key; + var px = localPositions[edge.x]; + var py = localPositions[edge.y]; + var tlist = kv.Value; + int tcnt = tlist.Length; + for (int i = 0; i < tcnt - 1; i++) + { + int3 tri1 = triangles[tlist[i]]; + int z = DataUtility.RemainingData(tri1, edge); + var pz = localPositions[z]; + for (int j = i + 1; j < tcnt; j++) + { + int3 tri2 = triangles[tlist[j]]; + int w = DataUtility.RemainingData(tri2, edge); + var pw = localPositions[w]; + + // z + + // / \ + // edge.x +---+ edge.y + // \ / + // w + + + // トライアングルペアのなす角を求める + float ang = math.degrees(MathUtility.TriangleAngle(px, py, pz, pw)); + //Debug.Log($"[{edge.x},{edge.y},{z},{w}] :{ang}"); + + //if (edge.x == 107 || edge.y == 107 || z == 107 || w == 107) + // Debug.Log($"[{edge.x}-{edge.y},{z},{w}], ang:{ang}"); + + // ほぼ水平が対象(歪な形状も弾かれる) + if (math.abs(ang) > Define.System.ProxyMeshTrianglePairAngle) + continue; + + // くの字型のトライアングルペアは無視する + MathUtility.ClosestPtSegmentSegment(px, py, pz, pw, out var s, out var t, out _, out _); + if (s == 0.0f || s == 1.0f || t == 0.0f || t == 1.0f) + continue; + + // この2つのトライアングルペアの四辺形 + int4 quad = DataUtility.PackInt4(edge.x, edge.y, z, w); + + // すでにこの四辺形が登録されているならば2つのトライアングルは削除対象に入れる + if (useQuadSet.Contains(quad)) + { + removeTriangleSet.Add(tri1); + removeTriangleSet.Add(tri2); + //Debug.Log($"removeTriangleSet:{tri1}"); + //Debug.Log($"removeTriangleSet:{tri2}"); + } + else + { + useQuadSet.Add(quad); + } + } + } + } + + // 削除トライアングルを除いた新しいトライアングルリストを作成する + for (int i = 0; i < tcnt; i++) + { + int3 tri = triangles[i]; + if (removeTriangleSet.Contains(tri)) + continue; + + // 登録 + newTriangles.AddNoResize(tri); + } + //foreach (var tri in removeTriangleSet) + //{ + // Debug.Log($"Remove Triangle:{tri}"); + //} + } + } + + /// + /// 共通するエッジをもつ2つのトライアングルが開いているか判定する + /// + /// + /// + /// + /// + bool CheckTwoTriangleOpen(in int3 tri1, in int3 tri2, in int2 edge, in float3 tri1n) + { + var sv0 = DataUtility.RemainingData(tri2, edge); + var v = math.normalize(localPositions[sv0] - localPositions[edge.x]); + return math.dot(tri1n, v) <= 0.0f; + } + + /// + /// 共通するエッジをもつ2つのトライアングルのなす角を求める(デグリー角) + /// + /// + /// + /// + /// + float CalcTwoTriangleAngle(in int3 tri1, in int3 tri2, in int2 edge) + { + var sv1 = DataUtility.RemainingData(tri1, edge); + var sv2 = DataUtility.RemainingData(tri2, edge); + + // トライアングル角度 + var va = localPositions[edge.y] - localPositions[edge.x]; + var vb = localPositions[sv1] - localPositions[edge.x]; + var vc = localPositions[sv2] - localPositions[edge.x]; + + var n0 = math.cross(va, vb); + var n1 = math.cross(vc, va); + + return math.degrees(MathUtility.Angle(n0, n1)); + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/VirtualMesh/Function/VirtualMeshOptimization.cs.meta b/Assets/MagicaCloth2/Scripts/Core/VirtualMesh/Function/VirtualMeshOptimization.cs.meta new file mode 100644 index 00000000..f524c8ea --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/VirtualMesh/Function/VirtualMeshOptimization.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: a5ea1d28ce226d74bb733f6c9a5a08e0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/VirtualMesh/Function/VirtualMeshOptimization.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/VirtualMesh/Function/VirtualMeshProxy.cs b/Assets/MagicaCloth2/Scripts/Core/VirtualMesh/Function/VirtualMeshProxy.cs new file mode 100644 index 00000000..e702ff61 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/VirtualMesh/Function/VirtualMeshProxy.cs @@ -0,0 +1,2426 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using System; +using System.Collections.Generic; +using Unity.Burst; +using Unity.Collections; +using Unity.Collections.LowLevel.Unsafe; +using Unity.Jobs; +using Unity.Mathematics; +using UnityEngine; + +namespace MagicaCloth2 +{ + public partial class VirtualMesh + { + /// + /// メッシュをプロキシメッシュに変換する(スレッド可) + /// プロキシメッシュは頂点法線接線を接続するトライアングルから求めるようになる + /// またマッピング用の頂点ごとのバインドポーズも保持する + /// + public void ConvertProxyMesh( + ClothSerializeData sdata, + TransformRecord clothTransformRecord, + List customSkinningBoneRecords, + TransformRecord normalAdjustmentTransformRecord + ) + { + try + { + if (IsError) + { + //Debug.LogError($"Invalid VirtualMesh! [{this.name}]"); + throw new MagicaClothProcessingException(); + } + + // カスタムスキニングボーン追加 + if (sdata.customSkinningSetting.enable && sdata.IsBoneSpring() == false) + { + SetCustomSkinningBones(clothTransformRecord, customSkinningBoneRecords); + } + + // 頂点に接続するトライアングル + vertexToTriangles = new NativeArray>(VertexCount, Allocator.Persistent); + + // 頂点ごとのバインドポーズ + vertexBindPosePositions = new NativeArray(VertexCount, Allocator.Persistent); + vertexBindPoseRotations = new NativeArray(VertexCount, Allocator.Persistent); + + // 頂点ごとのTransform変換用回転 + vertexToTransformRotations = new NativeArray(VertexCount, Allocator.Persistent); + JobUtility.FillRun(vertexToTransformRotations, VertexCount, quaternion.identity); + + // 頂点に接続する頂点リストを求める + // エッジリストを作成する + using var vertexDataBuilder = new MultiDataBuilder(VertexCount, VertexCount * 4); + using var edgeSet = new NativeParallelHashSet(VertexCount * 2, Allocator.Persistent); + if (TriangleCount > 0) + { + var calcTriangleVertexToVertexJob = new Proxy_CalcVertexToVertexFromTriangleJob() + { + triangleCount = TriangleCount, + triangles = triangles.GetNativeArray(), + vertexToVertexMap = vertexDataBuilder.Map, + edgeSet = edgeSet, + }; + calcTriangleVertexToVertexJob.Run(); + } + if (LineCount > 0) + { + var calcLineVertexToVertexJob = new Proxy_CalcVertexToVertexFromLineJob() + { + lineCount = LineCount, + lines = lines.GetNativeArray(), + vertexToVertexMap = vertexDataBuilder.Map, + edgeSet = edgeSet, + }; + calcLineVertexToVertexJob.Run(); + } + + // エッジをリスト化して格納する + edges = edgeSet.ToNativeArray(Allocator.Persistent); + //Debug.Log($"edges:{edges.Length}"); + + // 頂点接続頂点をリスト化して格納する + vertexDataBuilder.ToNativeArray(out vertexToVertexIndexArray, out vertexToVertexDataArray); + +#if false + // debug + for (int i = 0; i < VertexCount; i++) + { + uint pack = vertexToVertexIndexArray[i]; + int cnt = DataUtility.Unpack10_22Hi(pack); + Debug.Assert(cnt > 0); + Debug.Log($"[{i}] cnt:{cnt}"); + } +#endif +#if false + // 無効属性は移動属性に接続する場合のみ固定に変更する + var convertInvalidJob = new Proxy_ConvertInvalidToFixedJob() + { + attributes = attributes.GetNativeArray(), + vertexToVertexIndexArray = vertexToVertexIndexArray, + vertexToVertexDataArray = vertexToVertexDataArray, + }; + convertInvalidJob.Run(VertexCount); +#endif + + // エッジごとの接続トライアングルを求める + if (TriangleCount > 0) + { + // エッジごとの接続トライアングルを求める + edgeToTriangles = new NativeParallelMultiHashMap(TriangleCount * 2, Allocator.Persistent); + var calcEdgeToTriangleJob = new Proxy_CalcEdgeToTriangleJob() + { + tcnt = TriangleCount, + triangles = triangles.GetNativeArray(), + edgeToTriangles = edgeToTriangles, + }; + calcEdgeToTriangleJob.Run(); + + // トライアングル法線を求める + using var triNormals = new NativeArray(TriangleCount, Allocator.Persistent); + var calcTriangleNormalJob = new Proxy_CalcTriangleNormalJob() + { + triangles = triangles.GetNativeArray(), + localPositins = localPositions.GetNativeArray(), + triangleNormals = triNormals, + }; + calcTriangleNormalJob.Run(TriangleCount); + + // トライアングルの向きをできる限り揃える + //OptimizeTriangleDirection(triNormals, sdata.sameSurfaceAngle); + OptimizeTriangleDirection(triNormals, Define.System.SameSurfaceAngle); + + // トライアングル接線を求める + using var triTangents = new NativeArray(TriangleCount, Allocator.Persistent); + var calcTriangleTangentJob = new Proxy_CalcTriangleTangentJob() + { + triangles = triangles.GetNativeArray(), + localPositins = localPositions.GetNativeArray(), + uv = uv.GetNativeArray(), + triangleTangents = triTangents, + }; + calcTriangleTangentJob.Run(TriangleCount); + + // 頂点に接続するトライアングルセットを求める(最大7つ) + var createVertexToTriangleJob = new Proxy_CreateVertexToTrianglesJob() + { + triangles = triangles.GetNativeArray(), + vertexToTriangles = vertexToTriangles, + }; + createVertexToTriangleJob.Run(); + + // トライアングルから頂点法線を計算するためのvertexToTrianglesを求める + // また頂点がトライアングルに属する場合はフラグを立てる + var organizeVertexToTriangleJob = new Proxy_OrganizeVertexToTrianglsJob() + { + vertexToTriangles = vertexToTriangles, + triangleNormals = triNormals, + triangleTangents = triTangents, + attributes = attributes.GetNativeArray(), + }; + organizeVertexToTriangleJob.Run(VertexCount); + + // トライアングル組み合わせから法線と接線を求める + var calcVertexNormalTangentBindposeJob = new Proxy_CalcVertexNormalTangentFromTriangleJob() + { + triangleNormals = triNormals, + triangleTangents = triTangents, + vertexToTriangles = vertexToTriangles, + localNormals = localNormals.GetNativeArray(), + localTangents = localTangents.GetNativeArray(), + }; + calcVertexNormalTangentBindposeJob.Run(VertexCount); + } + else + { + // エッジごとの接続トライアングルは空にする + edgeToTriangles = new NativeParallelMultiHashMap(1, Allocator.Persistent); + } + + // シミュレーションに関係する頂点からAABBと固定頂点リストを作成する + ProxyCreateFixedListAndAABB(); + + // ベースラインの作成 + if (isBoneCloth) + { + // BoneCloth + CreateTransformBaseLine(); + } + else + { + // MeshCloth + CreateMeshBaseLine(); + } + + // 法線方向の調整 + ProxyNormalAdjustment(sdata, normalAdjustmentTransformRecord); + + // BoneClothではトランスフォーム書き戻し用の回転を求める + if (isBoneCloth) + { + var calcVertexToTransformJob = new Proxy_CalcVertexToTransformJob() + { + invRot = initInverseRotation, + localNormals = localNormals.GetNativeArray(), + localTangents = localTangents.GetNativeArray(), + vertexToTransformRotations = vertexToTransformRotations, + transformRotations = transformData.rotationArray.GetNativeArray(), + }; + calcVertexToTransformJob.Run(VertexCount); + } + + // 頂点のバインドポーズを求める + var calcVertexBindposeJob = new Proxy_CalcVertexBindPoseJob2() + { + localPositions = localPositions.GetNativeArray(), + localNormals = localNormals.GetNativeArray(), + localTangents = localTangents.GetNativeArray(), + vertexBindPosePositions = vertexBindPosePositions, + vertexBindPoseRotations = vertexBindPoseRotations, + }; + calcVertexBindposeJob.Run(VertexCount); + + // エッジ固有フラグを設定 + edgeFlags = new NativeArray(EdgeCount, Allocator.Persistent); + if (EdgeCount > 0) + { + var createEdgeFlagJob = new Proxy_CreateEdgeFlagJob() + { + edges = edges, + edgeToTriangles = edgeToTriangles, + edgeFlags = edgeFlags, + }; + createEdgeFlagJob.Run(EdgeCount); + } + + // ベースラインの基本姿勢を求める + CreateBaseLinePose(); + + // 頂点ごとのルートインデックスと深さを求める + CreateVertexRootAndDepth(); + + // AABB再計算 + //JobUtility.CalcAABBRun(localPositions.GetNativeArray(), VertexCount, boundingBox); + + // カスタムスキニング設定 + if (sdata.customSkinningSetting.enable && sdata.IsBoneSpring() == false) + { + CreateCustomSkinning(sdata.customSkinningSetting, customSkinningBoneRecords); + } + + // メッシュタイプ + if (isBoneCloth) + meshType = MeshType.ProxyBoneMesh; + else + meshType = MeshType.ProxyMesh; + } + catch (MagicaClothProcessingException) + { + if (result.IsError() == false) + result.SetError(Define.Result.ProxyMesh_UnknownError); + result.DebugLog(); + } + catch (Exception exception) + { + Debug.LogException(exception); + result.SetError(Define.Result.ProxyMesh_Exception); + } + finally + { + } + } + +#if false + [BurstCompile] + struct Proxy_ConvertInvalidToFixedJob : IJobParallelFor + { + // proxy mesh + public NativeArray attributes; + [Unity.Collections.ReadOnly] + public NativeArray vertexToVertexIndexArray; + [Unity.Collections.ReadOnly] + public NativeArray vertexToVertexDataArray; + + public void Execute(int vindex) + { + var attr = attributes[vindex]; + + // 無効判定 + if (attr.IsInvalid()) + { + // 移動属性に接続する場合のみ固定に変更する + var pack = vertexToVertexIndexArray[vindex]; + DataUtility.Unpack10_22(pack, out var dcnt, out var dstart); + for (int i = 0; i < dcnt; i++) + { + int tvindex = vertexToVertexDataArray[dstart + i]; + var tattr = attributes[tvindex]; + if (tattr.IsMove()) + { + // 固定に変更 + attr.SetFlag(VertexAttribute.Flag_Ignore, true); + attr.SetFlag(VertexAttribute.Flag_Fixed, true); + attributes[vindex] = attr; + return; + } + } + } + } + } +#endif + + /// + /// 法線方向の調整 + /// + void ProxyNormalAdjustment(ClothSerializeData sdata, TransformRecord normalAdjustmentTransformRecord) + { + int vcnt = VertexCount; + if (vcnt == 0) + return; + + // 配列初期化(未使用でも領域確保) + normalAdjustmentRotations = new NativeArray(vcnt, Allocator.Persistent); + JobUtility.FillRun(normalAdjustmentRotations, vcnt, quaternion.identity); + + var mode = sdata.normalAlignmentSetting.alignmentMode; + if (mode == NormalAlignmentSettings.AlignmentMode.None) + return; + + // 中心からの放射 + if (mode == NormalAlignmentSettings.AlignmentMode.BoundingBoxCenter || mode == NormalAlignmentSettings.AlignmentMode.Transform) + { + float3 center; + if (mode == NormalAlignmentSettings.AlignmentMode.BoundingBoxCenter) + { + center = boundingBox.Value.Center; + } + else + { + center = math.transform(initWorldToLocal, normalAdjustmentTransformRecord.position); + } + + var job1 = new ProxyNormalRadiationAdjustmentJob() + { + center = center, + localPositions = localPositions.GetNativeArray(), + + localNormals = localNormals.GetNativeArray(), + localTangents = localTangents.GetNativeArray(), + normalAdjustmentRotations = normalAdjustmentRotations, + }; + job1.Run(vcnt); + } + } + + [BurstCompile] + struct ProxyNormalRadiationAdjustmentJob : IJobParallelFor + { + public float3 center; + [Unity.Collections.ReadOnly] + public NativeArray localPositions; + + // out + public NativeArray localNormals; + public NativeArray localTangents; + [Unity.Collections.WriteOnly] + public NativeArray normalAdjustmentRotations; + + public void Execute(int vindex) + { + var lpos = localPositions[vindex]; + var v = lpos - center; + if (math.length(v) < Define.System.Epsilon) + return; + + // 指定されたセンターからの放射方向に法線を変更する + var n = math.normalize(v); + + // 現在の回転 + var ln = localNormals[vindex]; + var lt = localTangents[vindex]; + var lrot = MathUtility.ToRotation(ln, lt); + + // 接線を補正する + float dot = math.dot(n, lt); + if (dot < 0.99f) + { + float3 bn = math.normalize(math.cross(n, lt)); + lt = math.normalize(math.cross(bn, n)); + } + else + { + // 元の接線と新しい法線が同じベクトルの場合は、従法線から新しい接線を算出する + var lbn = math.normalize(math.cross(ln, lt)); + lt = math.normalize(math.cross(lbn, n)); + } + + localNormals[vindex] = n; + localTangents[vindex] = lt; + var nrot = MathUtility.ToRotation(n, lt); + + // 補正用回転を算出し格納する + normalAdjustmentRotations[vindex] = math.mul(math.inverse(lrot), nrot); + } + } + + /// + /// シミュレーションに関係する頂点からAABBと固定頂点のリストを作成する + /// + void ProxyCreateFixedListAndAABB() + { + localCenterPosition = new NativeReference(0, Allocator.Persistent); + + using var fixedList = new NativeList(VertexCount / 20 + 1, Allocator.TempJob); + var job = new ProxyCreateFixedListAndAABBJob() + { + vcnt = VertexCount, + attributes = attributes.GetNativeArray(), + localPositions = localPositions.GetNativeArray(), + vertexToVertexIndexArray = vertexToVertexIndexArray, + vertexToVertexDataArray = vertexToVertexDataArray, + + outAABB = boundingBox, + fixedList = fixedList, + localCenterPosition = localCenterPosition, + }; + job.Run(); + + // 固定頂点リスト格納 + if (fixedList.Length > 0) + { +#if MC2_COLLECTIONS_200 + centerFixedList = fixedList.AsArray().ToArray(); +#else + centerFixedList = fixedList.ToArray(); +#endif + } + //Debug.Log($"Local Center Pos:{localCenterPosition.Value}"); + } + + [BurstCompile] + struct ProxyCreateFixedListAndAABBJob : IJob + { + public int vcnt; + [Unity.Collections.ReadOnly] + public NativeArray attributes; + [Unity.Collections.ReadOnly] + public NativeArray localPositions; + [Unity.Collections.ReadOnly] + public NativeArray vertexToVertexIndexArray; + [Unity.Collections.ReadOnly] + public NativeArray vertexToVertexDataArray; + + // out + [Unity.Collections.WriteOnly] + public NativeReference outAABB; + [Unity.Collections.WriteOnly] + public NativeList fixedList; + [Unity.Collections.WriteOnly] + public NativeReference localCenterPosition; + + public void Execute() + { + fixedList.Clear(); + + float3 lcenpos = 0; + int fixcnt = 0; + + int cnt = 0; + float3 min = float.MaxValue; + float3 max = float.MinValue; + for (int i = 0; i < vcnt; i++) + { + var lpos = localPositions[i]; + + // 固定頂点の場合は接続がすべて固定ならば無効とする(シミュレーションに無関係) + if (attributes[i].IsMove() == false) + { + var pack = vertexToVertexIndexArray[i]; + DataUtility.Unpack12_20(pack, out var dcnt, out var dstart); + int j = 0; + for (; j < dcnt; j++) + { + int tindex = vertexToVertexDataArray[dstart + j]; + if (attributes[tindex].IsMove()) + { + // OK + break; + } + } + if (j == dcnt && dcnt > 0) + continue; + + // 固定頂点リストに追加する + fixedList.Add((ushort)i); + + lcenpos += lpos; + fixcnt++; + } + + // min/max + min = math.min(min, lpos); + max = math.max(max, lpos); + cnt++; + } + + // aabb + outAABB.Value = cnt > 0 ? new AABB(min, max) : new AABB(); + + // local center position + if (fixcnt > 0) + lcenpos = lcenpos / fixcnt; + localCenterPosition.Value = lcenpos; + } + } + + + /// + /// トライアングルの方向を頂点法線に沿うようにできるだけ合わせる + /// ※この処理はとても重要。この合わせにより法線の計算精度が上がる。 + /// + void OptimizeTriangleDirection(NativeArray triangleNormals, float sameSurfaceAngle) + { + if (TriangleCount == 0) + return; + + // トライアングルを隣接する法線角度によりレイヤー分けしながら法線を揃える + int startIndex = 0; + //var useTriSet = new HashSet(TriangleCount); + var useTriSet = new HashSet(); + var triQueue = new Queue(TriangleCount / 2); + var layerList = new List(TriangleCount); + while (startIndex < TriangleCount) + { + // レイヤー起点トライアングル + if (useTriSet.Contains(startIndex)) + { + // すでに処理済み + startIndex++; + continue; + } + useTriSet.Add(startIndex); + triQueue.Clear(); + triQueue.Enqueue(startIndex); + layerList.Clear(); + int openCount = 0; + int closeCount = 0; + + //Debug.Log($"レイヤー起点:{startIndex}"); + + // 起点トライアングル情報 + while (triQueue.Count > 0) + { + // 1つ取り出し + int tindex = triQueue.Dequeue(); + var n = triangleNormals[tindex]; + int3 tri = triangles[tindex]; + layerList.Add(tindex); + + //Debug.Log($"レイヤー起点:{tindex}, tri:{tri}"); + + // 隣接トライアングル + int2x3 edges = new int2x3( + DataUtility.PackInt2(tri.xy), + DataUtility.PackInt2(tri.yz), + DataUtility.PackInt2(tri.zx) + ); + for (int i = 0; i < 3; i++) + { + int2 edge = edges[i]; + + if (edgeToTriangles.ContainsKey(edge) == false) + continue; + + foreach (var data in edgeToTriangles.GetValuesForKey(edge)) + { + int tindex2 = data; + + // すでに処理済みならスキップ + if (useTriSet.Contains(tindex2)) + continue; + + // 同一レイヤー判定(トライアングルのなす角度) + int3 tri2 = triangles[tindex2]; + var n2 = triangleNormals[tindex2]; + float ang = CalcTwoTriangleAngle(tri, tri2, edge); + //Debug.Log($"tindex2:{tindex2}, tri2:{tri2}, ang:{ang}"); + + // 面角度が一定上ならば不連続としてスキップする + if (ang > sameSurfaceAngle) // 80.0f? + continue; + + // 面の法線が一定方向を向くように調整する + if (math.dot(n, n2) < 0.0f) + { + // フリップ + tri2 = MathUtility.FlipTriangle(tri2); + triangles[tindex2] = tri2; + triangleNormals[tindex2] = -n2; + //Debug.Log($"フリップ:{tri2}"); + } + + // 隣接トライアングルの法線が開いているか閉じているかのカウント + if (CheckTwoTriangleOpen(tri, tri2, edge, n)) + openCount++; + else + closeCount++; + + // 同一レイヤーとして処理する + useTriSet.Add(tindex2); + triQueue.Enqueue(tindex2); + } + } + } + + // 閉じているトライアングルのほうが多い場合はレイヤー全体の法線をフリップさせる + //Debug.Log("layer tcnt:" + layerList.Count + " open:" + openCount + " close:" + closeCount); + if (closeCount > openCount) + { + foreach (int tindex in layerList) + { + triangles[tindex] = MathUtility.FlipTriangle(triangles[tindex]); + triangleNormals[tindex] = -triangleNormals[tindex]; + } + } + } + } + + + /// + /// トライアングル法線を求める + /// + [BurstCompile] + struct Proxy_CalcTriangleNormalJob : IJobParallelFor + { + [Unity.Collections.ReadOnly] + public NativeArray triangles; + [Unity.Collections.ReadOnly] + public NativeArray localPositins; + + [Unity.Collections.WriteOnly] + public NativeArray triangleNormals; + + public void Execute(int tindex) + { + int3 tri = triangles[tindex]; + + // トライアングル法線を求める + var p0 = localPositins[tri.x]; + var p1 = localPositins[tri.y]; + var p2 = localPositins[tri.z]; + var n = MathUtility.TriangleNormal(p0, p1, p2); + triangleNormals[tindex] = n; + } + } + + /// + /// トライアングル接線を求める + /// + [BurstCompile] + struct Proxy_CalcTriangleTangentJob : IJobParallelFor + { + [Unity.Collections.ReadOnly] + public NativeArray triangles; + [Unity.Collections.ReadOnly] + public NativeArray localPositins; + [Unity.Collections.ReadOnly] + public NativeArray uv; + + [Unity.Collections.WriteOnly] + public NativeArray triangleTangents; + + public void Execute(int tindex) + { + int3 tri = triangles[tindex]; + + // トライアングル接線を求める + var p0 = localPositins[tri.x]; + var p1 = localPositins[tri.y]; + var p2 = localPositins[tri.z]; + var uv0 = uv[tri.x]; + var uv1 = uv[tri.y]; + var uv2 = uv[tri.z]; + var tan = MathUtility.TriangleTangent(p0, p1, p2, uv0, uv1, uv2); + Develop.Assert(math.lengthsq(tan) > 0.0f); + triangleTangents[tindex] = tan; + } + } + + /// + /// 頂点ごとに接続するトライアングルを求める(最大7つ) + /// + [BurstCompile] + unsafe struct Proxy_CreateVertexToTrianglesJob : IJob + { + [Unity.Collections.ReadOnly] + public NativeArray triangles; + + public NativeArray> vertexToTriangles; + + public void Execute() + { + var ptr = (FixedList32Bytes*)vertexToTriangles.GetUnsafePtr(); + + int tcnt = triangles.Length; + for (uint tindex = 0; tindex < tcnt; tindex++) + { + int3 tri = triangles[(int)tindex]; + + var vset_x = (ptr + tri.x); + var vset_y = (ptr + tri.y); + var vset_z = (ptr + tri.z); + + if (vset_x->Length < 7) + vset_x->MC2Set(tindex); + if (vset_y->Length < 7) + vset_y->MC2Set(tindex); + if (vset_z->Length < 7) + vset_z->MC2Set(tindex); + } + } + } + + /// + /// 接続トライアングルから頂点法線接線を計算するために最適なトライアングル方向を計算して格納する + /// またトライアングルに属する頂点にはフラグを立てる + /// + [BurstCompile] + struct Proxy_OrganizeVertexToTrianglsJob : IJobParallelFor + { + public NativeArray> vertexToTriangles; + + [Unity.Collections.ReadOnly] + public NativeArray triangleNormals; + [Unity.Collections.ReadOnly] + public NativeArray triangleTangents; + + public NativeArray attributes; + + public void Execute(int vindex) + { + var tset = vertexToTriangles[vindex]; + int tcnt = tset.Length; + if (tcnt == 0) + return; + + // この頂点はトライアングルに属する + var attr = attributes[vindex]; + attr.SetFlag(VertexAttribute.Flag_Triangle, true); + attributes[vindex] = attr; + + // まず普通に現在のトライアングル面法線から頂点法線を求めてみる + float3 finalNormal = 0; + float3 finalTangent = 0; + for (int i = 0; i < tcnt; i++) + { + int tindex = (int)tset[i]; + finalNormal += triangleNormals[tindex]; + finalTangent += triangleTangents[tindex]; + } + + //if (math.length(finalTangent) < 0.5f) + // Debug.LogError($"vindex:{vindex} finalTangent:{finalTangent}"); + + // 普通に求めた法線が短い場合は最適な法線を算出する + if (math.length(finalNormal) < 0.5f) + { + // すべての接続トライアングルをループ + // ループの最初のトライアングルを基準としてその法線方向に他のトライアングルをあわせてみる + // 法線の合計の長さがもっとも長いものを採用する + float maxDist = -1; + finalNormal = 0; + + for (int i = 0; i < tcnt; i++) + { + // このトライアングルを基準として計算する + int tindex1 = (int)tset[i]; + float3 n = 0; + float3 tn1 = triangleNormals[tindex1]; + + for (int j = 0; j < tcnt; j++) + { + int tindex2 = (int)tset[j]; + if (tindex2 == tindex1) + continue; + + float3 tn2 = triangleNormals[tindex2]; + if (math.dot(tn1, tn2) >= 0.0f) + n += tn2; + else + n += -tn2; + } + + // 計算された法線の長さを判定 + // 最も長いものを基準法線として採用する + float ndist = math.lengthsq(n); + if (ndist > maxDist) + { + maxDist = ndist; + finalNormal = tn1; + } + } + } + else + { + // この法線を基準法線とする + finalNormal = math.normalize(finalNormal); + } + + // 普通に求めた接線が短い場合は最適な接線を算出する + if (math.length(finalTangent) < 0.5f) + { + // すべての接続トライアングルをループ + // ループの最初のトライアングルを基準としてその接線方向に他のトライアングルをあわせてみる + // 接線の合計の長さがもっとも長いものを採用する + float maxDist = -1; + finalTangent = 0; + + for (int i = 0; i < tcnt; i++) + { + // このトライアングルを基準として計算する + int tindex1 = (int)tset[i]; + float3 n = 0; + float3 tt1 = triangleTangents[tindex1]; + + for (int j = 0; j < tcnt; j++) + { + int tindex2 = (int)tset[j]; + if (tindex2 == tindex1) + continue; + + float3 tt2 = triangleTangents[tindex2]; + if (math.dot(tt1, tt2) >= 0.0f) + n += tt2; + else + n += -tt2; + } + + // 計算された接線の長さを判定 + // 最も長いものを基準接線として採用する + float ndist = math.lengthsq(n); + if (ndist > maxDist) + { + maxDist = ndist; + finalTangent = tt1; + } + } + } + else + { + // この接線を基準とする + finalTangent = math.normalize(finalTangent); + } + + // トライアングルを登録する + // 同時に法線と接線の加算方向をフラグとして追加する + for (int i = 0; i < tcnt; i++) + { + int tindex = (int)tset[i]; + + float3 tn = triangleNormals[tindex]; + float3 tt = triangleTangents[tindex]; + + // 反転フラグ + int flipFlag = 0; + if (math.dot(finalNormal, tn) < 0.0f) + flipFlag |= 0x1; + if (math.dot(finalTangent, tt) < 0.0f) + flipFlag |= 0x2; + + // 12-20bitでuintにパックする + tset[i] = DataUtility.Pack12_20(flipFlag, tindex); + } + + /* + // 算出された法線向きに合わせるようにトライアングルを登録する + // 反転の場合はマイナスのインデックスで登録する + for (int i = 0; i < tcnt; i++) + { + int tindex = tset[i]; + + float3 tn = triangleNormals[tindex]; + + // 基準法線と逆向きならマイナスインデックスとして記録する + // ★インデックスは+1して記録するので注意!(0を除外するため) + int registTriangleIndex = math.dot(finalNormal, tn) >= 0.0f ? (tindex + 1) : -(tindex + 1); + + // 再登録 + tset[i] = registTriangleIndex; + } + */ + + // 結果格納 + vertexToTriangles[vindex] = tset; + } + } + + /// + /// 現在メッシュの頂点法線接線を接続トライアングル情報から更新する + /// + [BurstCompile] + struct Proxy_CalcVertexNormalTangentFromTriangleJob : IJobParallelFor + { + [Unity.Collections.ReadOnly] + public NativeArray triangleNormals; + [Unity.Collections.ReadOnly] + public NativeArray triangleTangents; + + [Unity.Collections.ReadOnly] + public NativeArray> vertexToTriangles; + public NativeArray localNormals; + public NativeArray localTangents; + + public void Execute(int vindex) + { + var tset = vertexToTriangles[vindex]; + int tcnt = tset.Length; + if (tcnt > 0) + { + float3 nor = 0; + float3 tan = 0; + + for (int i = 0; i < tcnt; i++) + { + // 12-20bitのパックで格納されている + uint data = tset[i]; + int flipFlag = DataUtility.Unpack12_20Hi(data); + int tindex = DataUtility.Unpack12_20Low(data); + + nor += triangleNormals[tindex] * ((flipFlag & 0x1) == 0 ? 1 : -1); + tan += triangleTangents[tindex] * ((flipFlag & 0x2) == 0 ? 1 : -1); + + //int data = tset[i]; + //int tindex = math.abs(data) - 1; + + // 法線フリップフラグ + //float flip = math.sign(data); + + //nor += triangleNormals[tindex] * flip; + //tan += triangleTangents[tindex]; // 接線はフリップさせては駄目! + } + + nor = math.normalize(nor); + + // 従法線に変更(v2.1.7) + //tan = math.normalize(tan); + float3 binor = math.normalize(math.cross(nor, tan)); + + localNormals[vindex] = nor; + //localTangents[vindex] = tan; + localTangents[vindex] = binor; // 従法線に変更(v2.1.7) + } + } + } + + [BurstCompile] + struct Proxy_CalcVertexToTransformJob : IJobParallelFor + { + public quaternion invRot; + + // vmesh + [Unity.Collections.ReadOnly] + public NativeArray localNormals; + [Unity.Collections.ReadOnly] + public NativeArray localTangents; + [Unity.Collections.WriteOnly] + public NativeArray vertexToTransformRotations; + + // transform + [Unity.Collections.ReadOnly] + public NativeArray transformRotations; + + public void Execute(int vindex) + { + // トランスフォームのローカル回転 + var trot = math.mul(invRot, transformRotations[vindex]); + + // 頂点のローカル回転 + var vrot = MathUtility.ToRotation(localNormals[vindex], localTangents[vindex]); + + // 頂点ローカル回転をトランスフォームローカル回転に復元する回転を求める + var toRot = math.mul(math.inverse(vrot), trot); + + vertexToTransformRotations[vindex] = toRot; + } + } + + /// + /// エッジごとの接続トライアングルマップを作成する + /// + [BurstCompile] + struct Proxy_CalcEdgeToTriangleJob : IJob + { + public int tcnt; + [Unity.Collections.ReadOnly] + public NativeArray triangles; + public NativeParallelMultiHashMap edgeToTriangles; + + public void Execute() + { + for (int i = 0; i < tcnt; i++) + { + var tri = triangles[i]; + int2x3 edges = new int2x3( + DataUtility.PackInt2(tri.xy), + DataUtility.PackInt2(tri.yz), + DataUtility.PackInt2(tri.zx) + ); + for (int j = 0; j < 3; j++) + { + int2 edge = edges[j]; + edgeToTriangles.MC2UniqueAdd(edge, (ushort)i); + } + } + } + } + + /// + /// 頂点のバインドポーズを求める + /// + [BurstCompile] + struct Proxy_CalcVertexBindPoseJob2 : IJobParallelFor + { + [Unity.Collections.ReadOnly] + public NativeArray localPositions; + [Unity.Collections.ReadOnly] + public NativeArray localNormals; + [Unity.Collections.ReadOnly] + public NativeArray localTangents; + + [Unity.Collections.WriteOnly] + public NativeArray vertexBindPosePositions; + [Unity.Collections.WriteOnly] + public NativeArray vertexBindPoseRotations; + + public void Execute(int vindex) + { + float3 lpos = localPositions[vindex]; + var lnor = localNormals[vindex]; + var ltan = localTangents[vindex]; + + // マッピング用の頂点バインドポーズを求める + quaternion rot = MathUtility.ToRotation(lnor, ltan); + vertexBindPosePositions[vindex] = -lpos; + vertexBindPoseRotations[vindex] = math.inverse(rot); + } + } + + /// + /// トライアングルに接続する頂点セットを求める + /// およびエッジセットを作成する + /// + [BurstCompile] + struct Proxy_CalcVertexToVertexFromTriangleJob : IJob + { + public int triangleCount; + + [Unity.Collections.ReadOnly] + public NativeArray triangles; + public NativeParallelMultiHashMap vertexToVertexMap; + public NativeParallelHashSet edgeSet; + + public void Execute() + { + for (int i = 0; i < triangleCount; i++) + { + int3 tri = triangles[i]; + + ushort x = (ushort)tri.x; + ushort y = (ushort)tri.y; + ushort z = (ushort)tri.z; + + vertexToVertexMap.MC2UniqueAdd(tri.x, y); + vertexToVertexMap.MC2UniqueAdd(tri.x, z); + vertexToVertexMap.MC2UniqueAdd(tri.y, x); + vertexToVertexMap.MC2UniqueAdd(tri.y, z); + vertexToVertexMap.MC2UniqueAdd(tri.z, x); + vertexToVertexMap.MC2UniqueAdd(tri.z, y); + + edgeSet.Add(DataUtility.PackInt2(tri.xy)); + edgeSet.Add(DataUtility.PackInt2(tri.yz)); + edgeSet.Add(DataUtility.PackInt2(tri.zx)); + } + } + } + + /// + /// ラインに接続する頂点セットを求める + /// およびエッジセットを作成する + /// + [BurstCompile] + struct Proxy_CalcVertexToVertexFromLineJob : IJob + { + public int lineCount; + + [Unity.Collections.ReadOnly] + public NativeArray lines; + public NativeParallelMultiHashMap vertexToVertexMap; + public NativeParallelHashSet edgeSet; + + public void Execute() + { + for (int i = 0; i < lineCount; i++) + { + int2 line = lines[i]; + + vertexToVertexMap.MC2UniqueAdd(line.x, (ushort)line.y); + vertexToVertexMap.MC2UniqueAdd(line.y, (ushort)line.x); + + edgeSet.Add(DataUtility.PackInt2(line)); + } + } + } + + [BurstCompile] + struct Proxy_CreateEdgeFlagJob : IJobParallelFor + { + [Unity.Collections.ReadOnly] + public NativeArray edges; + [Unity.Collections.ReadOnly] + public NativeParallelMultiHashMap edgeToTriangles; + + [Unity.Collections.WriteOnly] + public NativeArray edgeFlags; + + public void Execute(int eindex) + { + var flag = new ExBitFlag8(); + + // 切り口エッジか判定する + var edge = edges[eindex]; + if (edgeToTriangles.ContainsKey(edge)) + { + if (edgeToTriangles.CountValuesForKey(edge) <= 1) + { + flag.SetFlag(EdgeFlag_Cut, true); + //Debug.Log($"切り口エッジ. eindex:{eindex}, edge:{edge}"); + } + } + + edgeFlags[eindex] = flag; + } + } + + //========================================================================================= + struct SkinningBoneInfo + { + //public int transformIndex; + public int parentTransformIndex; + public float3 parentPos; + public int childTransformIndex; + public float3 childPos; + } + + /// + /// カスタムスキニング情報の作成 + /// + void CreateCustomSkinning(CustomSkinningSettings setting, List bones) + { + if (CustomSkinningBoneCount == 0) + return; + + // ボーン情報の構築 + using var boneInfoList = new NativeList(CustomSkinningBoneCount * 2, Allocator.Persistent); + for (int i = 0; i < CustomSkinningBoneCount; i++) + { + int tindex = customSkinningBoneIndices[i]; + if (tindex == -1) + continue; + +#if MC2_CUSTOM_SKINNING_V1 + // 旧 + int pid = bones[i].pid; + if (pid == 0) + continue; + int pindex = bones.FindIndex(x => x.id == pid); + if (pindex < 0) + continue; + + // ボーンライン情報の作成 + // localPositonはクロス空間での座標に変換済み + var info = new SkinningBoneInfo(); + info.parentTransformIndex = customSkinningBoneIndices[pindex]; + info.parentPos = bones[pindex].localPosition; + info.childTransformIndex = tindex; + info.childPos = bones[i].localPosition; + + // 距離がほぼ0なら無効 + if (math.distance(info.parentPos, info.childPos) < Define.System.Epsilon) + continue; +#else + // V2 + var info = new SkinningBoneInfo(); + info.childTransformIndex = tindex; + info.childPos = bones[i].localPosition; +#endif + + // 登録 + boneInfoList.Add(info); + //Debug.Log($"[{boneInfoList.Length - 1}] parent:{pindex} -> {i}"); + } + if (boneInfoList.Length == 0) + return; + + // 頂点ごとにカスタムスキニングウエイトを算出 +#if MC2_CUSTOM_SKINNING_V1 + // 旧 + var job = new Proxy_CalcCustomSkinningWeightsJob() + { + isBoneCloth = isBoneCloth, + angularAttenuation = Define.System.CustomSkinningAngularAttenuation, + distanceReduction = Define.System.CustomSkinningDistanceReduction, + distancePow = Define.System.CustomSkinningDistancePow, + + attributes = attributes.GetNativeArray(), + localPositions = localPositions.GetNativeArray(), + boneInfoList = boneInfoList, + boneWeights = boneWeights.GetNativeArray(), + }; +#else + // V2 + var job = new Proxy_CalcCustomSkinningWeightsJobV2() + { + isBoneCloth = isBoneCloth, + angularAttenuation = Define.System.CustomSkinningAngularAttenuation, + distanceReduction = Define.System.CustomSkinningDistanceReduction, + distancePow = Define.System.CustomSkinningDistancePow, + + attributes = attributes.GetNativeArray(), + localPositions = localPositions.GetNativeArray(), + boneInfoList = boneInfoList, + boneWeights = boneWeights.GetNativeArray(), + }; +#endif + job.Run(VertexCount); + } + +#if !MC2_CUSTOM_SKINNING_V1 + // V2 + [BurstCompile] + struct Proxy_CalcCustomSkinningWeightsJobV2 : IJobParallelFor + { + public bool isBoneCloth; + public float angularAttenuation; + public float distanceReduction; + public float distancePow; + + [Unity.Collections.ReadOnly] + public NativeArray attributes; + [Unity.Collections.ReadOnly] + public NativeArray localPositions; + [Unity.Collections.ReadOnly] + public NativeList boneInfoList; + [Unity.Collections.WriteOnly] + public NativeArray boneWeights; + + // プロキシメッシュ頂点ごと + public void Execute(int vindex) + { + // 移動属性のみ + if (attributes[vindex].IsDontMove()) + return; + + var lpos = localPositions[vindex]; + + var costList = new ExCostSortedList4(-1); + int bcnt = boneInfoList.Length; + for (int i = 0; i < bcnt; i++) + { + var binfo = boneInfoList[i]; + var bpos = binfo.childPos; + int boneIndex = binfo.childTransformIndex; + + // 距離 + var v = lpos - bpos; + float dist = math.length(v); + + // 登録。すでに登録済みならばdistがより小さい場合のみ再登録 + int nowIndex = costList.indexOf(boneIndex); + if (nowIndex >= 0) + { + if (dist < costList.costs[nowIndex]) + { + costList.RemoveItem(boneIndex); + costList.Add(dist, boneIndex); + } + } + else + costList.Add(dist, boneIndex); + } + + // (1)最小距離のn%を減算する + int cnt = costList.Count; + float mindist = costList.MinCost * distanceReduction; // 0.6 + for (int i = 0; i < cnt; i++) + costList.costs[i] = costList.costs[i] - mindist; + + // (2)distanceをn乗する + for (int i = 0; i < cnt; i++) + costList.costs[i] = math.pow(costList.costs[i], distancePow); // 2.0 + + // ウエイト算出 + if (costList.MinCost < Define.System.Epsilon) + { + costList.costs = new float4(1, 0, 0, 0); + costList.data = new int4(costList.data[0], 0, 0, 0); + } + else + { + // コストの逆数の合計 + cnt = costList.Count; + float sum = 0; + for (int i = 0; i < cnt; i++) + { + sum += 1.0f / costList.costs[i]; + } + + // 1.0fに正規化 + for (int i = 0; i < cnt; i++) + { + costList.costs[i] = (1.0f / costList.costs[i]) / sum; + } + + // 極小のウエイトは削除する + const float InvalidWeight = 0.001f; // 0.1% + sum = 0; + for (int i = 0; i < 4; i++) + { + if (costList.costs[i] < InvalidWeight || i >= cnt) + { + // 打ち切り + costList.costs[i] = 0.0f; + costList.data[i] = 0; + } + else + { + sum += costList.costs[i]; + } + } + Debug.Assert(sum > 0); + costList.costs /= sum; // 再度1.0正規化 + } + //Debug.Log($"[{vindex}] :{costList}"); + + // ウエイト構造体に変換して格納 + var bw = new VirtualMeshBoneWeight(costList.data, costList.costs); + boneWeights[vindex] = bw; + } + } +#endif + +#if MC2_CUSTOM_SKINNING_V1 + [BurstCompile] + struct Proxy_CalcCustomSkinningWeightsJob : IJobParallelFor + { + public bool isBoneCloth; + public float angularAttenuation; + public float distanceReduction; + public float distancePow; + + [Unity.Collections.ReadOnly] + public NativeArray attributes; + [Unity.Collections.ReadOnly] + public NativeArray localPositions; + [Unity.Collections.ReadOnly] + public NativeList boneInfoList; + [Unity.Collections.WriteOnly] + public NativeArray boneWeights; + + // プロキシメッシュ頂点ごと + public void Execute(int vindex) + { + // BoneClothカスタムスキニングでは固定は動かさない + if (isBoneCloth && attributes[vindex].IsFixed()) + return; + + var lpos = localPositions[vindex]; + + var costList = new ExCostSortedList4(-1); + int bcnt = boneInfoList.Length; + for (int i = 0; i < bcnt; i++) + { + var binfo = boneInfoList[i]; + float3 d = MathUtility.ClosestPtPointSegment(lpos, binfo.parentPos, binfo.childPos); + //float dist = math.distance(lpos, d); + + // ボーンラインとの角度により判定距離を調整する + // ラインと水平になるほど影響がよわくなる + var v = lpos - d; + var bv = binfo.childPos - binfo.parentPos; + float dot = math.dot(math.normalize(v), math.normalize(bv)); + float ratio = 1.0f + math.abs(dot) * angularAttenuation; // 1.0 + + // 登録。すでに登録済みならばdistがより小さい場合のみ再登録 + for (int j = 0; j < 2; j++) + { + int boneIndex = j == 0 ? binfo.parentTransformIndex : binfo.childTransformIndex; + float dist = j == 0 ? math.distance(lpos, binfo.parentPos) : math.distance(lpos, binfo.childPos); + dist *= ratio; + + int nowIndex = costList.indexOf(boneIndex); + if (nowIndex >= 0) + { + if (dist < costList.costs[nowIndex]) + { + costList.RemoveItem(boneIndex); + costList.Add(dist, boneIndex); + } + } + else + costList.Add(dist, boneIndex); + } + } + + // ウエイト算出 + // (0)最小距離のn%を減算する + int cnt = costList.Count; + float mindist = costList.MinCost * distanceReduction; // 0.6 + costList.costs -= mindist; + + // (1)distanceをn乗する + costList.costs = math.pow(costList.costs, distancePow); // 2.0 + + // (2)最小値の逆数にする + float min = math.max(costList.MinCost, 1e-06f); + float sum = 0; + for (int i = 0; i < cnt; i++) + { + costList.costs[i] = min / costList.costs[i]; + sum += costList.costs[i]; + } + + // (3)割合を出す + costList.costs /= sum; + + // (4)極小のウエイトは削除する + sum = 0; + for (int i = 0; i < 4; i++) + { + if (costList.costs[i] < 0.01f || i >= cnt) + { + // 打ち切り + costList.costs[i] = 0.0f; + costList.data[i] = 0; + } + else + { + sum += costList.costs[i]; + } + } + Debug.Assert(sum > 0); + + // (5)再度1.0に平均化 + costList.costs /= sum; + + //Debug.Log($"[{vindex}] :{costList}"); + + // ウエイト作成 + var bw = new VirtualMeshBoneWeight(costList.data, costList.costs); + boneWeights[vindex] = bw; + } + } +#endif + + //========================================================================================= + /// + /// セレクションデータ属性をプロキシメッシュに反映させる(スレッド可) + /// + /// + public void ApplySelectionAttribute(SelectionData selectionData) + { + try + { + //Debug.Log($"ApplySelection.SearchRadius:{searchRadius}"); + + using var selectionPositions = selectionData.GetPositionNativeArray(); + using var selectionAttributes = selectionData.GetAttributeNativeArray(); + + // グリッドサイズ計算 + // 検索半径(メッシュの平均接続距離とセレクションデータの最大接続距離の大きい方) + float searchRadius = math.max(averageVertexDistance.Value, selectionData.maxConnectionDistance); + searchRadius = math.max(searchRadius, Define.System.MinimumGridSize); + float gridSize = searchRadius * 1.5f; + //Develop.DebugLog($"ApplySelectionAttribute. searchRadius:{searchRadius}, gridSize:{gridSize}"); + + // セレクションデータをグリッドマップに格納する + using var gridMap = SelectionData.CreateGridMapRun(gridSize, selectionPositions, selectionAttributes); + + // メッシュ頂点ごとに最も近いセレクションデータに接続し頂点属性を決定する + var applyJob = new Proxy_ApplySelectionJob() + { + gridSize = gridSize, + radius = searchRadius, + localPositions = localPositions.GetNativeArray(), + attributes = attributes.GetNativeArray(), + + gridMap = gridMap.GetMultiHashMap(), + selectionPositions = selectionPositions, + selectionAttributes = selectionAttributes, + }; + applyJob.Run(VertexCount); + + // BoneClothの場合はTransformの書き込み方法をTransformFlagに設定する + if (isBoneCloth) + { + var transformFlagJob = new Proxy_BoneClothApplayTransformFlagJob() + { + attributes = attributes.GetNativeArray(), + transformFlags = transformData.flagArray.GetNativeArray(), + }; + transformFlagJob.Run(VertexCount); + } + } + catch (Exception) + { + result.SetError(Define.Result.ProxyMesh_ApplySelectionError); + } + } + + [BurstCompile] + struct Proxy_ApplySelectionJob : IJobParallelFor + { + public float gridSize; + public float radius; + + // proxy mesh + [Unity.Collections.ReadOnly] + public NativeArray localPositions; + public NativeArray attributes; + + // selection + [Unity.Collections.ReadOnly] + public NativeParallelMultiHashMap gridMap; + [Unity.Collections.ReadOnly] + public NativeArray selectionPositions; + [Unity.Collections.ReadOnly] + public NativeArray selectionAttributes; + + public void Execute(int vindex) + { + float3 pos = localPositions[vindex]; + + // 属性フラグはすでに設定されている場合があるので追加書き込みにする + var attr = attributes[vindex]; + + // 範囲グリッド走査 + float minDist = float.MaxValue; + //VertexAttribute minAttr = default; + VertexAttribute minAttr = VertexAttribute.Invalid; + foreach (int3 grid in GridMap.GetArea(pos, radius, gridMap, gridSize)) + { + if (gridMap.ContainsKey(grid) == false) + continue; + + // このグリッドを検索する + foreach (int tindex in gridMap.GetValuesForKey(grid)) + { + // 距離判定 + float3 tpos = selectionPositions[tindex]; + float dist = math.distance(pos, tpos); + if (dist > radius) + continue; + if (dist > minDist) + continue; + + // 近傍属性 + minDist = dist; + minAttr = selectionAttributes[tindex]; + } + } + + // 属性反映 + //if (minAttr.IsInvalid()) + // minAttr = VertexAttribute.Fixed; // InvalidはFixedに変換 + //Debug.Log($"vindex:{vindex} minAttr:{minAttr.Value:X}"); + attr.SetFlag(minAttr, true); // フラグ結合 + attributes[vindex] = attr; + } + } + + [BurstCompile] + struct Proxy_BoneClothApplayTransformFlagJob : IJobParallelFor + { + [Unity.Collections.ReadOnly] + public NativeArray attributes; + + public NativeArray transformFlags; + + public void Execute(int vindex) + { + var attr = attributes[vindex]; + + var flag = transformFlags[vindex]; + + // 書き込み方法 + if (attr.IsMove()) + flag.SetFlag(TransformManager.Flag_LocalPosRotWrite, true); + else if (attr.IsFixed()) + flag.SetFlag(TransformManager.Flag_WorldRotWrite, true); + + // 復元 + if (attr.IsInvalid() == false) + flag.SetFlag(TransformManager.Flag_Restore, true); + + transformFlags[vindex] = flag; + } + } + + //----------------------------------------------------------------------------------------- + /// + /// [MeshCloth]ベースラインの作成 + /// 頂点接続情報から親情報を作成する + /// + void CreateMeshBaseLine() + { + int vcnt = VertexCount; + vertexParentIndices = new NativeArray(vcnt, Allocator.Persistent); + using var dataBuilder = new MultiDataBuilder(vcnt, vcnt); + + // 親接続を(-1)で初期化する + JobUtility.FillRun(vertexParentIndices, vcnt, -1); + + // 固定頂点のリストを作成する + using var fixedList = new NativeList(vcnt, Allocator.Persistent); + var job1 = new BaseLine_Mesh_CareteFixedListJob() + { + vcnt = vcnt, + attribues = attributes.GetNativeArray(), + fixedList = fixedList, + }; + job1.Run(); + + // 固定数が0ならばベースラインは作れない! + if (fixedList.Length == 0) + { + //Debug.LogWarning("BaseLine.fixedPoint count = 0!"); + vertexChildIndexArray = new NativeArray(vcnt, Allocator.Persistent, NativeArrayOptions.ClearMemory); + vertexChildDataArray = new NativeArray(0, Allocator.Persistent); + return; + } + + // 頂点接続情報から親接続を作成する + using var nextList = new NativeList(vcnt, Allocator.Persistent); + using var markBuff = new NativeArray(vcnt, Allocator.Persistent, NativeArrayOptions.ClearMemory); // Unity2023.1.5対応 + using var vertexMap = new NativeParallelHashMap(vcnt, Allocator.Persistent); // Unity2023.1.5対応 + var job2 = new BaseLine_Mesh_CreateParentJob2() + { + vcnt = vcnt, + avgDist = averageVertexDistance.Value, + + attribues = attributes.GetNativeArray(), + localPositions = localPositions.GetNativeArray(), + vertexToVertexIndexArray = vertexToVertexIndexArray, + vertexToVertexDataArray = vertexToVertexDataArray, + + vertexParentIndices = vertexParentIndices, + vertexChildMap = dataBuilder.Map, + + fixedList = fixedList, + nextList = nextList, + + markBuff = markBuff, // Unity2023.1.5対応 + vertexMap = vertexMap, // Unity2023.1.5対応 + }; + job2.Run(); + + // ベースラインの構築 + var stack = new Stack(vcnt); + var lineFlags = new List(fixedList.Length); + var startIndices = new List(fixedList.Length); + var dataCounts = new List(fixedList.Length); + var indices = new List(vcnt); + for (int i = 0; i < fixedList.Length; i++) + { + int fvindex = fixedList[i]; + // 子が接続されていない固定頂点は無効 + if (dataBuilder.GetDataCount(fvindex) == 0) + continue; + + // この頂点を起点としてラインを形成する + stack.Clear(); + stack.Push(fvindex); + + ushort start = (ushort)indices.Count; + ushort count = 0; + ExBitFlag8 lineflag = new ExBitFlag8(); + + while (stack.Count > 0) + { + int vindex = stack.Pop(); + indices.Add((ushort)vindex); + count++; + + // この頂点がラインに属している場合はフラグを立てる + if (attributes[vindex].IsSet(VertexAttribute.Flag_Triangle) == false) + { + lineflag.SetFlag(BaseLineFlag_IncludeLine, true); + } + + if (dataBuilder.Map.ContainsKey(vindex)) + { + foreach (var data in dataBuilder.Map.GetValuesForKey(vindex)) + { + stack.Push(data); + } + } + } + + // 格納 + lineFlags.Add(lineflag); + startIndices.Add(start); + dataCounts.Add(count); + //Debug.Log($"BaseLine data count:{count}"); + } + baseLineFlags = new NativeArray(lineFlags.ToArray(), Allocator.Persistent); + baseLineStartDataIndices = new NativeArray(startIndices.ToArray(), Allocator.Persistent); + baseLineDataCounts = new NativeArray(dataCounts.ToArray(), Allocator.Persistent); + baseLineData = new NativeArray(indices.ToArray(), Allocator.Persistent); + + (ushort[] dataArry, uint[] indexArray) = dataBuilder.ToArray(); + vertexChildIndexArray = new NativeArray(indexArray, Allocator.Persistent); + vertexChildDataArray = new NativeArray(dataArry, Allocator.Persistent); + } + + struct BaseLineWork : IComparable + { + public int vindex; + public float dist; + + public int CompareTo(BaseLineWork other) + { + return (int)math.sign(dist - other.dist); + } + } + + [BurstCompile] + struct BaseLine_Mesh_CreateParentJob2 : IJob + { + public int vcnt; + public float avgDist; + + [Unity.Collections.ReadOnly] + public NativeArray attribues; + [Unity.Collections.ReadOnly] + public NativeArray localPositions; + [Unity.Collections.ReadOnly] + public NativeArray vertexToVertexIndexArray; + [Unity.Collections.ReadOnly] + public NativeArray vertexToVertexDataArray; + + public NativeArray vertexParentIndices; + public NativeParallelMultiHashMap vertexChildMap; + + [Unity.Collections.ReadOnly] + public NativeList fixedList; + public NativeList nextList; + + public NativeArray markBuff; // Unity2023.1.5対応 + public NativeParallelHashMap vertexMap; // Unity2023.1.5対応 + + public void Execute() + { + // 処理済みマーク + //var markBuff = new NativeArray(vcnt, Allocator.Temp, NativeArrayOptions.ClearMemory); // Unity2023.1.5対応 + //var vertexMap = new NativeParallelHashMap(vcnt, Allocator.Temp); // Unity2023.1.5対応 + + // 最初の作業バッファを固定頂点で初期化する + foreach (int vindex in fixedList) + { + nextList.Add(new BaseLineWork() { vindex = vindex, dist = 0 }); + } + int level = 0; + + while (nextList.Length > 0) + { + foreach (var data in nextList) + { + int vindex = data.vindex; + + // 親への接続を作成する + var attr = attribues[vindex]; + if (attr.IsDontMove()) + continue; + + var pos = localPositions[vindex]; + + // ■親が固定ならば距離が近い方、親が移動ならそのさらに親へのベクトル角度が浅い方を採用する + var cost = new ExCostSortedList1(-1, -1); + DataUtility.Unpack12_20(vertexToVertexIndexArray[vindex], out var dcnt, out var dstart); + for (int i = 0; i < dcnt; i++) + { + int tindex = vertexToVertexDataArray[dstart + i]; + if (markBuff[tindex] == 0) + continue; + var tpos = localPositions[tindex]; + + if (attribues[tindex].IsDontMove()) + { + // 親が固定なら距離優先 + float tdist = math.distance(pos, tpos); + cost.Add(tdist, tindex); + } + else + { + // 親の親へのベクトル + int pindex = vertexParentIndices[tindex]; + var v1 = tpos - pos; + var v2 = localPositions[pindex] - tpos; + float ang = MathUtility.Angle(v1, v2); + cost.Add(ang, tindex); + } + } + if (cost.IsValid) + { + int pindex = cost.data; + vertexParentIndices[vindex] = pindex; + markBuff[vindex] = 1; + } + } + + // まとめ + foreach (var data in nextList) + { + int vindex = data.vindex; + + // 今回のセットを処理済みとしてマークする + markBuff[vindex] = 2; + + // 子の接続情報を作成 + int pindex = vertexParentIndices[vindex]; + if (pindex >= 0) + { + vertexChildMap.MC2UniqueAdd(pindex, (ushort)vindex); + } + } + + // 次の作業セットを作成する + vertexMap.Clear(); + int mapcnt = 0; + foreach (var data in nextList) + { + int vindex = data.vindex; + + // 自身の接続を調べる + DataUtility.Unpack12_20(vertexToVertexIndexArray[vindex], out var dcnt, out var dstart); + if (dcnt == 0) + continue; + + var pos = localPositions[vindex]; + + for (int i = 0; i < dcnt; i++) + { + int tindex = vertexToVertexDataArray[dstart + i]; + var tattr = attribues[tindex]; + if (tattr.IsInvalid()) + continue; + // 処理済みなら除外する + if (markBuff[tindex] != 0) + continue; + + // 次の候補として登録する + float dist = math.distance(pos, localPositions[tindex]); + if (vertexMap.ContainsKey(tindex)) + { + var d = vertexMap[tindex]; + if (dist < d.dist) + { + d.dist = dist; + vertexMap[tindex] = d; + } + } + else + { + vertexMap.Add(tindex, new BaseLineWork() { vindex = tindex, dist = dist }); + mapcnt++; + } + } + } + + // nextリスト構築 + nextList.Clear(); + if (mapcnt > 0) + { + // Unity2023.1.5対応 + //nextList.AddRange(vertexMap.GetValueArray(Allocator.Temp)); + foreach (var kv in vertexMap) + { + nextList.Add(kv.Value); + } + + // 親への距離の昇順にソート + nextList.Sort(); + } + + level++; + } + } + } + + /// + /// (Mesh)固定ポイントをリストにする + /// + [BurstCompile] + struct BaseLine_Mesh_CareteFixedListJob : IJob + { + public int vcnt; + [Unity.Collections.ReadOnly] + public NativeArray attribues; + + public NativeList fixedList; + + public void Execute() + { + for (int i = 0; i < vcnt; i++) + { + var attr = attribues[i]; + if (attr.IsFixed()) + { + fixedList.Add(i); + } + } + } + } + + //----------------------------------------------------------------------------------------- + /// + /// [BoneCloth]ベースライン情報の作成 + /// BoneClothでは単純にTransformの親子構造がそのままベースラインとなる + /// + void CreateTransformBaseLine() + { + int vcnt = VertexCount; + vertexParentIndices = new NativeArray(vcnt, Allocator.Persistent); + using var dataBuilder = new MultiDataBuilder(vcnt, vcnt * 2); + + // トランスフォーム情報から親子関係を構築する + // parent + var idToIndexDict = new Dictionary(vcnt); + var idArray = transformData.idArray.GetNativeArray(); + var parentIdArray = transformData.parentIdArray.GetNativeArray(); + for (int i = 0; i < vcnt; i++) + { + idToIndexDict.Add(idArray[i], i); + } + for (int index = 0; index < vcnt; index++) + { + MagicaObjectId pid = parentIdArray[index]; + if (idToIndexDict.ContainsKey(pid)) + vertexParentIndices[index] = idToIndexDict[pid]; + else + vertexParentIndices[index] = -1; + } + + // child + var job = new BaseLine_Bone_CreateBoneChildInfoJob() + { + vcnt = vcnt, + parentIndices = vertexParentIndices, + childMap = dataBuilder.Map, + }; + job.Run(); + + // 親子関係からベースラインを構築する + int rootCount = transformData.RootCount; + Debug.Assert(rootCount > 0); + var rootStack = new Stack(vcnt); + var stack = new Stack(vcnt); + var lineFlags = new List(rootCount); + var startIndices = new List(rootCount); + var dataCounts = new List(rootCount); + var indices = new List(vcnt); + foreach (MagicaObjectId id in transformData.rootIdList) + { + // ルートからTransformを走査して最初の移動ポイントを持つ固定を起点とする + rootStack.Clear(); + int rootIndex = idToIndexDict[id]; + rootStack.Push(rootIndex); + + while (rootStack.Count > 0) + { + int index0 = rootStack.Pop(); + var attr = attributes[index0]; + if (attr.IsDontMove() == false) + continue; + + // 子に移動が含まれるかチェック + bool hasMove = false; + foreach (var data in dataBuilder.Map.GetValuesForKey(index0)) + { + if (attributes[data].IsMove()) + hasMove = true; + } + + // 子に移動が含まれない場合はさらに深く潜る + if (hasMove == false) + { + foreach (var data in dataBuilder.Map.GetValuesForKey(index0)) + { + if (attributes[data].IsDontMove()) + rootStack.Push(data); + } + continue; + } + + // 自身が固定で子に移動が含まれる場合はここをベースラインの起点として構築する + stack.Clear(); + stack.Push(index0); + ushort start = (ushort)indices.Count; + ushort count = 0; + ExBitFlag8 lineflag = new ExBitFlag8(); + + while (stack.Count > 0) + { + int index = stack.Pop(); + indices.Add((ushort)index); + count++; + + // この頂点がラインに属している場合はフラグを立てる + if (attributes[index].IsSet(VertexAttribute.Flag_Triangle) == false) + { + lineflag.SetFlag(BaseLineFlag_IncludeLine, true); + } + + // 子 + if (dataBuilder.Map.ContainsKey(index)) + { + foreach (var data in dataBuilder.Map.GetValuesForKey(index)) + { + // 移動属性以外は無視する + if (attributes[data].IsDontMove()) + continue; + + stack.Push(data); + } + } + } + + // 格納 + lineFlags.Add(lineflag); + startIndices.Add(start); + dataCounts.Add(count); + } + } + baseLineFlags = new NativeArray(lineFlags.ToArray(), Allocator.Persistent); + baseLineStartDataIndices = new NativeArray(startIndices.ToArray(), Allocator.Persistent); + baseLineDataCounts = new NativeArray(dataCounts.ToArray(), Allocator.Persistent); + baseLineData = new NativeArray(indices.ToArray(), Allocator.Persistent); + + dataBuilder.ToNativeArray(out vertexChildIndexArray, out vertexChildDataArray); + } + + /// + /// (Bone)ベースライン上の頂点ごとの子頂点リストを求める + /// + [BurstCompile] + struct BaseLine_Bone_CreateBoneChildInfoJob : IJob + { + public int vcnt; + + [Unity.Collections.ReadOnly] + public NativeArray parentIndices; + //[Unity.Collections.WriteOnly] + public NativeParallelMultiHashMap childMap; + + public void Execute() + { + // 頂点ごとの子頂点を調べるて格納する + for (int i = 0; i < vcnt; i++) + { + int pindex = parentIndices[i]; + if (pindex >= 0) + { + childMap.Add(pindex, (ushort)i); + } + } + } + } + + //----------------------------------------------------------------------------------------- + /// + /// (Mesh/Bone)ベースラインの基準姿勢を求める + /// + void CreateBaseLinePose() + { + int dataCount = baseLineData.Length; + vertexLocalPositions = new NativeArray(VertexCount, Allocator.Persistent); + vertexLocalRotations = new NativeArray(VertexCount, Allocator.Persistent); + var calcLinePoseJob = new BaseLine_CalcLocalPositionRotationJob() + { + attributes = attributes.GetNativeArray(), + parentIndices = vertexParentIndices, + localPositions = localPositions.GetNativeArray(), + localNormals = localNormals.GetNativeArray(), + localTangents = localTangents.GetNativeArray(), + baseLineIndices = baseLineData, + vertexLocalPositions = vertexLocalPositions, + vertexLocalRotations = vertexLocalRotations, + }; + calcLinePoseJob.Run(dataCount); + } + + /// + /// ベースラインの基準姿勢を求める + /// + [BurstCompile] + struct BaseLine_CalcLocalPositionRotationJob : IJobParallelFor + { + [NativeDisableParallelForRestriction] + public NativeArray attributes; + + [Unity.Collections.ReadOnly] + public NativeArray parentIndices; + [Unity.Collections.ReadOnly] + public NativeArray localPositions; + [Unity.Collections.ReadOnly] + public NativeArray localNormals; + [Unity.Collections.ReadOnly] + public NativeArray localTangents; + + + [Unity.Collections.ReadOnly] + public NativeArray baseLineIndices; + [NativeDisableParallelForRestriction] + [Unity.Collections.WriteOnly] + public NativeArray vertexLocalPositions; + [NativeDisableParallelForRestriction] + [Unity.Collections.WriteOnly] + public NativeArray vertexLocalRotations; + + public void Execute(int index) + { + int vindex = baseLineIndices[index]; + + int pvindex = parentIndices[vindex]; + if (pvindex >= 0) + { + float3 ppos = localPositions[pvindex]; + float3 pnor = localNormals[pvindex]; + float3 ptan = localTangents[pvindex]; + quaternion prot = MathUtility.ToRotation(pnor, ptan); + quaternion iprot = math.inverse(prot); + + float3 pos = localPositions[vindex]; + float3 nor = localNormals[vindex]; + float3 tan = localTangents[vindex]; + quaternion rot = MathUtility.ToRotation(nor, tan); + + float3 lpos = math.mul(iprot, pos - ppos); + quaternion lrot = math.mul(iprot, rot); + vertexLocalPositions[vindex] = lpos; + vertexLocalRotations[vindex] = lrot; + + // 親とのゼロ距離判定。フラグを立てる + if (MathUtility.IsZeroDistance(lpos)) + { + var flag = attributes[vindex]; + flag.SetFlag(VertexAttribute.Flag_ZeroDistance, true); + attributes[vindex] = flag; + } + + //Debug.Log($"vertexLocalPositions [{vindex}] : {lpos}"); + //Debug.Log($"vertexLocalRotations [{vindex}] : {lrot}"); + } + else + { + vertexLocalPositions[vindex] = 0; + vertexLocalRotations[vindex] = quaternion.identity; + + //Debug.Log($"vertexLocalPositions [{vindex}] : 0"); + //Debug.Log($"vertexLocalRotations [{vindex}] : (0, 0, 0, 1)"); + } + } + } + + /// + /// 頂点ごとのルートインデックスと深さを求める + /// + void CreateVertexRootAndDepth() + { + // ベースラインが存在しなくとも配列は用意する + int vcnt = VertexCount; + vertexDepths = new NativeArray(vcnt, Allocator.Persistent); + vertexRootIndices = new NativeArray(vcnt, Allocator.Persistent); + + // 作業バッファ + using var rootLengthArray = new NativeArray(vcnt, Allocator.Persistent); + + // 頂点ごとのルートインデックスと深さを計算する + var job = new BaseLine_CalcMaxBaseLineLengthJob() + { + vcnt = vcnt, + attribues = attributes.GetNativeArray(), + localPositions = localPositions.GetNativeArray(), + vertexParentIndices = vertexParentIndices, + + vertexDepths = vertexDepths, + vertexRootIndices = vertexRootIndices, + + rootLengthArray = rootLengthArray, + }; + job.Run(); + + } + + [BurstCompile] + struct BaseLine_CalcMaxBaseLineLengthJob : IJob + { + public int vcnt; + + [Unity.Collections.ReadOnly] + public NativeArray attribues; + [Unity.Collections.ReadOnly] + public NativeArray localPositions; + [Unity.Collections.ReadOnly] + public NativeArray vertexParentIndices; + + [Unity.Collections.WriteOnly] + public NativeArray vertexDepths; + [Unity.Collections.WriteOnly] + public NativeArray vertexRootIndices; + + public NativeArray rootLengthArray; + + + public void Execute() + { + float maxLen = 0; + + // 各移動頂点のルートまでの距離を計算する + // およびルート頂点を記録する + for (int i = 0; i < vcnt; i++) + { + int rootIndex = -1; + float rootLen = 0; + + if (attribues[i].IsMove()) + { + int cindex = i; + int pindex = vertexParentIndices[cindex]; + while (pindex >= 0) + { + var pos = localPositions[cindex]; + var ppos = localPositions[pindex]; + float dist = math.distance(pos, ppos); + rootLen += dist; + rootIndex = pindex; + + // 親が固定ならばここがルートとなり終了 + if (attribues[pindex].IsMove() == false) + break; + + // next + cindex = pindex; + pindex = vertexParentIndices[cindex]; + } + } + + vertexRootIndices[i] = rootIndex; + rootLengthArray[i] = rootLen; + + // 最大距離 + maxLen = math.max(maxLen, rootLen); + } + + // 深さを割り出す + if (maxLen > Define.System.Epsilon) + { + for (int i = 0; i < vcnt; i++) + { + var rootLen = rootLengthArray[i]; + float depth = math.saturate(rootLen / maxLen); + vertexDepths[i] = depth; + } + } + } + } + + //========================================================================================= +#if false // pitch/yaw個別制限はv1.0では実装しないので一旦停止 + /// + /// 角度制限計算用ローカル回転の算出 + /// + public void CreateAngleCalcLocalRotation(NormalCalcMode normalCalcMode, float3 normalCalcCenter) + { + if (VertexCount == 0) + return; + + // 配列初期化 + vertexAngleCalcLocalRotations = new NativeArray(VertexCount, Allocator.Persistent); + JobUtility.FillRun(vertexAngleCalcLocalRotations, VertexCount, quaternion.identity); + + // 頂点ごとに算出する + var job = new AngleCalcLocalRotationJob() + { + calcMode = normalCalcMode, + calcPoint = normalCalcCenter, + //calcPoint = GetCenterTransform().TransformPoint(normalCalcCenter), + //calcPoint = math.transform(initLocalToWorld, normalCalcCenter), + + attribues = attributes.GetNativeArray(), + localPositions = localPositions.GetNativeArray(), + localNormals = localNormals.GetNativeArray(), + localTangents = localTangents.GetNativeArray(), + vertexParentIndices = vertexParentIndices, + vertexChildIndices = vertexChildIndices, + vertexAngleCalcLocalRotations = vertexAngleCalcLocalRotations, + }; + job.Run(VertexCount); + } + + [BurstCompile] + struct AngleCalcLocalRotationJob : IJobParallelFor + { + public NormalCalcMode calcMode; + public float3 calcPoint; + [Unity.Collections.ReadOnly] + public NativeArray attribues; + [Unity.Collections.ReadOnly] + public NativeArray localPositions; + [Unity.Collections.ReadOnly] + public NativeArray localNormals; + [Unity.Collections.ReadOnly] + public NativeArray localTangents; + [Unity.Collections.ReadOnly] + public NativeArray vertexParentIndices; + [Unity.Collections.ReadOnly] + public NativeArray> vertexChildIndices; + + [Unity.Collections.WriteOnly] + public NativeArray vertexAngleCalcLocalRotations; + + public void Execute(int vindex) + { + // 子への方向、子がいない場合は親からの方向をfowardベクトルとする + float3 z = 0; + var clist = vertexChildIndices[vindex]; + int pindex = vertexParentIndices[vindex]; + var pos = localPositions[vindex]; + var nor = localNormals[vindex]; // 実はforward + var tan = localTangents[vindex]; // 実はup + var bin = MathUtility.Binormal(nor, tan); + if (clist.Count > 0) + { + // 子への方向の平均ベクトル + for (int i = 0; i < clist.Count; i++) + { + int cindex = clist.Get(i); + var cpos = localPositions[cindex]; + z += (cpos - pos); + } + z = math.normalize(z); + } + else if (pindex >= 0) + { + // 親からのベクトル + var ppos = localPositions[pindex]; + z = math.normalize(pos - ppos); + } + else + return; + + // upベクトル + float3 y = 0; + if (calcMode == NormalCalcMode.Auto) + { + // z方向と内積がもっとも0に近いものを見つける(つまり直角) + // その軸をupベクトルとする + float norDot = math.abs(math.dot(z, nor)); + float tanDot = math.abs(math.dot(z, tan)); + y = norDot < tanDot ? nor : tan; + } + else if (calcMode == NormalCalcMode.X_Axis) + { + // 元のX軸をupベクトルとする + y = bin; + } + else if (calcMode == NormalCalcMode.Y_Axis) + { + // 元のY軸をupベクトルとする + y = tan; + } + else if (calcMode == NormalCalcMode.Z_Axis) + { + // 元のZ軸をupベクトルとする + y = nor; + } + else if (calcMode == NormalCalcMode.Point_Outside) + { + // 指定された中心点から外側へ + y = math.normalize(pos - calcPoint); + } + else if (calcMode == NormalCalcMode.Point_Inside) + { + // 指定された中心点から内側へ + y = math.normalize(calcPoint - pos); + } + else + { + Debug.LogError("まだ未実装!"); + return; + } + + // rightベクトルを求める + float3 x = math.cross(z, y); + + // もう一度upベクトルを求める + y = math.cross(x, z); + + // このz/y軸で回転を作成 + var angleRot = quaternion.LookRotation(z, y); + + // 元の頂点回転姿勢 + var rot = MathUtility.ToRotation(nor, tan); + + // ローカル回転に変換 + angleRot = math.mul(math.inverse(rot), angleRot); + + + vertexAngleCalcLocalRotations[vindex] = angleRot; + } + } +#endif + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/VirtualMesh/Function/VirtualMeshProxy.cs.meta b/Assets/MagicaCloth2/Scripts/Core/VirtualMesh/Function/VirtualMeshProxy.cs.meta new file mode 100644 index 00000000..c71bb2a1 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/VirtualMesh/Function/VirtualMeshProxy.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: f23f05fdc7b93ce40beda3969f3012e6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/VirtualMesh/Function/VirtualMeshProxy.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/VirtualMesh/Function/VirtualMeshReduction.cs b/Assets/MagicaCloth2/Scripts/Core/VirtualMesh/Function/VirtualMeshReduction.cs new file mode 100644 index 00000000..141e70d5 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/VirtualMesh/Function/VirtualMeshReduction.cs @@ -0,0 +1,892 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using System; +using System.Threading; +using Unity.Burst; +using Unity.Collections; +using Unity.Jobs; +using Unity.Mathematics; +using UnityEngine; + +namespace MagicaCloth2 +{ + public partial class VirtualMesh + { + //static readonly ProfilerMarker reductionProfiler = new ProfilerMarker("Reduction"); + + //========================================================================================= + /// + /// リダクションを実行する(スレッド可) + /// 処理時間が長いためCancellationTokenを受け入れる + /// + /// + /// + public void Reduction(ReductionSettings settings, CancellationToken ct) + { + //reductionProfiler.Begin(); + + try + { + // リダクション作業データ + using var workData = new ReductionWorkData(this); + + // 作業データの初期化 + InitReductionWorkData(workData); + if (result.IsError()) + { + throw new MagicaClothProcessingException(); + } + + // リダクションのリニア距離をAABBの最大の辺の長さを基準に算出する + float maxSideLength = boundingBox.Value.MaxSideLength; + if (maxSideLength < 1e-08f) + { + result.SetError(Define.Result.Reduction_MaxSideLengthZero); + throw new MagicaClothProcessingException(); // リダクション失敗 + } + float sameDistance = maxSideLength * math.saturate(Define.System.ReductionSameDistance); + float simpleDistance = maxSideLength * math.saturate(settings.simpleDistance); + float shapeDistance = maxSideLength * math.saturate(settings.shapeDistance); + Develop.DebugLog($"ReductionDista. maxSideLength:{maxSideLength}, same:{sameDistance}, simple:{simpleDistance}, shape:{shapeDistance}"); + + // 同一距離リダクション + ct.ThrowIfCancellationRequested(); +#if true + using (var sameReduction = new SameDistanceReduction(this.name, this, workData, sameDistance)) + { + sameReduction.Reduction(); + if (sameReduction.Result.IsError()) + { + result = sameReduction.Result; + throw new MagicaClothProcessingException(); // リダクション失敗 + } + //workData.DebugVerify(); + } +#endif + + // 距離リダクション + ct.ThrowIfCancellationRequested(); + if (simpleDistance > sameDistance) + { + float startDistance = math.min(sameDistance * 2.0f, simpleDistance); + using (var simpleReduction = new SimpleDistanceReduction(this.name, this, workData, startDistance, simpleDistance, Define.System.ReductionMaxStep, Define.System.ReductionDontMakeLine, Define.System.ReductionJoinPositionAdjustment)) + { + simpleReduction.Reduction(); + if (simpleReduction.Result.IsError()) + { + result = simpleReduction.Result; + throw new MagicaClothProcessingException(); // リダクション失敗 + } + //workData.DebugVerify(); + } + } + + // 接続リダクション + ct.ThrowIfCancellationRequested(); + if (shapeDistance > 0.0f && shapeDistance > simpleDistance) + { + float startDistance = math.min(math.max(sameDistance * 2.0f, simpleDistance), shapeDistance); + using (var shapeReduction = new ShapeDistanceReduction(this.name, this, workData, startDistance, shapeDistance, Define.System.ReductionMaxStep, Define.System.ReductionDontMakeLine, Define.System.ReductionJoinPositionAdjustment)) + { + shapeReduction.Reduction(); + if (shapeReduction.Result.IsError()) + { + result = shapeReduction.Result; + throw new MagicaClothProcessingException(); // リダクション失敗 + } + //workData.DebugVerify(); + } + } + + //workData.DebugInfo(); + + // リダクション結果からメッシュを再構成する + ct.ThrowIfCancellationRequested(); + Organization(settings, workData); + if (result.IsError()) + { + throw new MagicaClothProcessingException(); + } + + //Debug.Log($"Vertex:{workData.newVertexCount}, Line:{workData.newLineList.Length}, Triangle:{workData.newTriangleList.Length}"); + + // 結果をvmeshに書き込む + ct.ThrowIfCancellationRequested(); + OrganizeStoreVirtualMesh(workData); + if (result.IsError()) + { + throw new MagicaClothProcessingException(); + } + + // 平均頂点間距離を再計算する + CalcAverageAndMaxVertexDistanceRun(); + + // 成功 + ct.ThrowIfCancellationRequested(); + } + catch (MagicaClothProcessingException) + { + if (result.IsError() == false) + result.SetError(Define.Result.Reduction_UnknownError); + result.DebugLog(); + } + catch (OperationCanceledException) + { + result.SetCancel(); + } + catch (Exception exception) + { + Debug.LogError(exception); + result.SetError(Define.Result.Reduction_Exception); + } + finally + { + } + + //reductionProfiler.End(); + } + + //========================================================================================= + /// + /// リダクション用作業データの初期化 + /// + /// + void InitReductionWorkData(ReductionWorkData workData) + { + try + { + int vertexCount = VertexCount; + int triangleCount = TriangleCount; + + // 頂点結合先リストの作成 + workData.vertexJoinIndices = new NativeArray(vertexCount, Allocator.Persistent); + JobUtility.FillRun(workData.vertexJoinIndices, vertexCount, -1); + + // 頂点ごとの接続先頂点マップの構築 + workData.vertexToVertexMap = new NativeParallelMultiHashMap(vertexCount, Allocator.Persistent); + new Reduction_InitVertexToVertexJob2() + { + triangleCount = triangleCount, + triangles = triangles.GetNativeArray(), + vertexToVertexMap = workData.vertexToVertexMap, + }.Run(); + } + catch (Exception) + { + result.SetError(Define.Result.Reduction_InitError); + } + } + + [BurstCompile] + unsafe struct Reduction_InitVertexToVertexJob2 : IJob + { + public int triangleCount; + + [Unity.Collections.ReadOnly] + public NativeArray triangles; + + public NativeParallelMultiHashMap vertexToVertexMap; + + public void Execute() + { + for (int i = 0; i < triangleCount; i++) + { + int3 tri = triangles[i]; + + ushort x = (ushort)tri.x; + ushort y = (ushort)tri.y; + ushort z = (ushort)tri.z; + + vertexToVertexMap.Add(x, y); + vertexToVertexMap.Add(x, z); + vertexToVertexMap.Add(y, x); + vertexToVertexMap.Add(y, z); + vertexToVertexMap.Add(z, x); + vertexToVertexMap.Add(z, y); + } + } + } + +#if false + [BurstCompile] + unsafe struct Reduction_InitVertexToVertexJob : IJob + { + public int triangleCount; + + [Unity.Collections.ReadOnly] + public NativeArray triangles; + + public NativeArray> vertexToVertexArray; + + public void Execute() + { + var arrayPtr = (FixedList128Bytes*)vertexToVertexArray.GetUnsafePtr(); + + for (int i = 0; i < triangleCount; i++) + { + int3 tri = triangles[i]; + + var ptrx = (arrayPtr + tri.x); + var ptry = (arrayPtr + tri.y); + var ptrz = (arrayPtr + tri.z); + + ushort x = (ushort)tri.x; + ushort y = (ushort)tri.y; + ushort z = (ushort)tri.z; + ptrx->SetLimit(y); + ptrx->SetLimit(z); + ptry->SetLimit(x); + ptry->SetLimit(z); + ptrz->SetLimit(x); + ptrz->SetLimit(y); + } + } + } +#endif + + //========================================================================================= + /// + /// リダクション結果からデータを再編成する + /// + /// + /// + void Organization(ReductionSettings setting, ReductionWorkData workData) + { + try + { + // 再編成に必要なすべての準備を整える + OrganizationInit(setting, workData); + + // リマップデータの作成 + OrganizationCreateRemapData(workData); + + // 基本データ作成 + OrganizationCreateBasicData(workData); + + // ライン/トライアングル生成 + OrganizationCreateLineTriangle(workData); + } + catch (Exception) + { + result.SetError(Define.Result.Reduction_OrganizationError); + } + } + + //========================================================================================= + /// + /// 再編成に必要なすべての準備を整える + /// + /// + /// + void OrganizationInit(ReductionSettings setting, ReductionWorkData workData) + { + // 最終的な頂点数 + // 生存頂点のみのリスト + // 旧頂点リストからの連動インデックス + workData.oldVertexCount = VertexCount; + workData.newVertexCount = workData.oldVertexCount - workData.removeVertexCount; + + int newVertexCount = workData.newVertexCount; + + // 削除された頂点やボーンを生存するデータへ接続する + // OrganizationCreateRemapData用 + { + // 頂点リマップデータ + workData.vertexRemapIndices = new NativeArray(workData.oldVertexCount, Allocator.Persistent); + + // スキンボーンリマップデータ作成 + workData.useSkinBoneMap = new NativeParallelHashMap(SkinBoneCount, Allocator.Persistent); + + // 使用ボーンに新しいインデックスを割り振る + // ついでに新しいスキンボーンリストとバインドポーズのリストを作成する + workData.newSkinBoneCount = new NativeReference(Allocator.Persistent); + workData.newSkinBoneTransformIndices = new NativeList(SkinBoneCount, Allocator.Persistent); + workData.newSkinBoneBindPoseList = new NativeList(SkinBoneCount, Allocator.Persistent); + } + + // 基本データの作成 + //OrganizationCreateBasicData用 + { + workData.newAttributes = new ExSimpleNativeArray(newVertexCount); + workData.newLocalPositions = new ExSimpleNativeArray(newVertexCount); + workData.newLocalNormals = new ExSimpleNativeArray(newVertexCount); + workData.newLocalTangents = new ExSimpleNativeArray(newVertexCount); + workData.newUv = new ExSimpleNativeArray(newVertexCount); + workData.newBoneWeights = new ExSimpleNativeArray(newVertexCount); + + // 新しい頂点の接続頂点リスト + workData.newVertexToVertexMap = new NativeParallelMultiHashMap(newVertexCount, Allocator.Persistent); + } + + // ライン/トライアングル生成 + // OrganizationCreateLineTriangle用 + { + workData.edgeSet = new NativeParallelHashSet(newVertexCount * 2, Allocator.Persistent); + workData.triangleSet = new NativeParallelHashSet(newVertexCount, Allocator.Persistent); + workData.newLineList = new NativeList(newVertexCount, Allocator.Persistent); + workData.newTriangleList = new NativeList(newVertexCount, Allocator.Persistent); + } + } + + //========================================================================================= + /// + /// リマップデータの作成 + /// 削除された頂点やボーンを生存するデータへ接続する + /// + /// + void OrganizationCreateRemapData(ReductionWorkData workData) + { + // 頂点リマップデータ作成 + // 生存頂点にインデックスを割り振る、削除頂点に新しい生存頂点インデックスを割り振る + var vertexRemapJob = new Organize_RemapVertexJob() + { + oldVertexCount = workData.oldVertexCount, + joinIndices = workData.vertexJoinIndices, + vertexRemapIndices = workData.vertexRemapIndices, + }; + vertexRemapJob.Run(); + + // スキニングボーンのリマップデータ作成 + // 使用しているボーンインデックスを収集する + //Debug.Log($"workData.useSkinBoneMap count:{workData.useSkinBoneMap.Count()}"); + using var useSkinBoneMapKeyList = new NativeList(Allocator.Persistent); // Unity2023.1.5対応 + var collectUseSkinJob = new Organize_CollectUseSkinBoneJob() + { + oldVertexCount = workData.oldVertexCount, + joinIndices = workData.vertexJoinIndices, + oldBoneWeights = boneWeights.GetNativeArray(), + oldBindPoses = skinBoneBindPoses.GetNativeArray(), + useSkinBoneMap = workData.useSkinBoneMap, + newSkinBoneTransformIndices = workData.newSkinBoneTransformIndices, + newSkinBoneBindPoses = workData.newSkinBoneBindPoseList, + newSkinBoneCount = workData.newSkinBoneCount, + useSkinBoneMapKeyList = useSkinBoneMapKeyList, // Unity2023.1.5対応 + }; + collectUseSkinJob.Run(); + } + + /// + /// 生存頂点にインデックスを割り振る + /// + [BurstCompile] + struct Organize_RemapVertexJob : IJob + { + public int oldVertexCount; + + [Unity.Collections.ReadOnly] + public NativeArray joinIndices; + public NativeArray vertexRemapIndices; + + public void Execute() + { + // 生存頂点に新しいインデックスを割り振る + int remapIndex = 0; + for (int i = 0; i < oldVertexCount; i++) + { + int join = joinIndices[i]; + if (join < 0) + { + // live + vertexRemapIndices[i] = remapIndex; + remapIndex++; + } + } + + // 削除頂点に新しい生存頂点インデックスを割り振る + for (int i = 0; i < oldVertexCount; i++) + { + int join = joinIndices[i]; + if (join >= 0) + { + // delete + vertexRemapIndices[i] = vertexRemapIndices[join]; + } + } + } + } + + /// + /// 使用しているスキニングボーンを収集する + /// + [BurstCompile] + struct Organize_CollectUseSkinBoneJob : IJob + { + public int oldVertexCount; + + [Unity.Collections.ReadOnly] + public NativeArray joinIndices; + [Unity.Collections.ReadOnly] + public NativeArray oldBoneWeights; + [Unity.Collections.ReadOnly] + public NativeArray oldBindPoses; + + public NativeParallelHashMap useSkinBoneMap; + + public NativeList newSkinBoneTransformIndices; + public NativeList newSkinBoneBindPoses; + public NativeReference newSkinBoneCount; + + public NativeList useSkinBoneMapKeyList; // Unity2023.1.5対応 + + public void Execute() + { + // 生存頂点で使用されている旧ボーンインデックスを収集する + for (int vindex = 0; vindex < oldVertexCount; vindex++) + { + int join = joinIndices[vindex]; + if (join >= 0) + continue; // isDelete + + // 使用している旧ボーンインデックスを収集する + var bw = oldBoneWeights[vindex]; + for (int i = 0; i < 4; i++) + { + if (bw.weights[i] > 0.0f) + { + //Debug.Log(bw.boneIndices[i]); + + // まずは旧ボーンインデックスを収集 + int index = bw.boneIndices[i]; + useSkinBoneMap.TryAdd(bw.boneIndices[i], 0); + } + } + } + + // 利用されるボーンに連番をふる + // Unity2023.1.5対応 + //var oldBoneIndexArray = useSkinBoneMap.GetKeyArray(Allocator.Temp); + useSkinBoneMapKeyList.Clear(); + foreach (var kv in useSkinBoneMap) + { + useSkinBoneMapKeyList.Add(kv.Key); + } + + // 不要なトランスフォームを削除した新しいスキニングボーンとバインドポーズのリストを作成する + //for (int i = 0; i < oldBoneIndexArray.Length; i++) // Unity2023.1.5対応 + for (int i = 0; i < useSkinBoneMapKeyList.Length; i++) // Unity2023.1.5対応 + { + //int oldBoneIndex = oldBoneIndexArray[i]; // Unity2023.1.5対応 + int oldBoneIndex = useSkinBoneMapKeyList[i]; // Unity2023.1.5対応 + useSkinBoneMap[oldBoneIndex] = i; + + // 新しいトランスフォームインデックス + newSkinBoneTransformIndices.Add(i); + + // バインドポーズ + newSkinBoneBindPoses.Add(oldBindPoses[oldBoneIndex]); + } + + // 最適化後のスキンボーン数 + //newSkinBoneCount.Value = oldBoneIndexArray.Length; // Unity2023.1.5対応 + newSkinBoneCount.Value = useSkinBoneMapKeyList.Length; // Unity2023.1.5対応 + } + } + + //========================================================================================= + /// + /// 基本データ作成 + /// Line/Triangleを再編成するための基本的なデータを作成する + /// + /// + void OrganizationCreateBasicData(ReductionWorkData workData) + { + int newVertexCount = workData.newVertexCount; + int oldVertexCount = workData.oldVertexCount; + + // position/normal/tangent/attributeコピー + var copyVertexJob = new Organize_CopyVertexJob() + { + joinIndices = workData.vertexJoinIndices, + vertexRemapIndices = workData.vertexRemapIndices, + oldAttributes = attributes.GetNativeArray(), + oldLocalPositions = localPositions.GetNativeArray(), + oldLocalNormals = localNormals.GetNativeArray(), + oldLocalTangents = localTangents.GetNativeArray(), + newAttributes = workData.newAttributes.GetNativeArray(), + newLocalPositions = workData.newLocalPositions.GetNativeArray(), + newLocalNormals = workData.newLocalNormals.GetNativeArray(), + newLocalTangents = workData.newLocalTangents.GetNativeArray(), + }; + copyVertexJob.Run(oldVertexCount); + + // 新しいuvを計算する(このUVは接線計算用でありテクスチャ用ではないので注意!) + JobUtility.CalcUVWithSphereMappingRun(workData.newLocalPositions.GetNativeArray(), newVertexCount, workData.vmesh.boundingBox, workData.newUv.GetNativeArray()); + + // 新しいボーンウエイトリストを作成する + var remapBoneWeightJob = new Organize_RemapBoneWeightJob() + { + joinIndices = workData.vertexJoinIndices, + vertexRemapIndices = workData.vertexRemapIndices, + useSkinBoneMap = workData.useSkinBoneMap, + oldSkinBoneIndices = skinBoneTransformIndices.GetNativeArray(), + oldBoneWeights = boneWeights.GetNativeArray(), + newBoneWeights = workData.newBoneWeights.GetNativeArray(), + }; + remapBoneWeightJob.Run(oldVertexCount); + + // 新しい頂点の接続頂点リストを作成する + var remapLinkPointArrayJob = new Organize_RemapLinkPointArrayJob() + { + joinIndices = workData.vertexJoinIndices, + vertexRemapIndices = workData.vertexRemapIndices, + oldVertexToVertexMap = workData.vertexToVertexMap, + newVertexToVertexMap = workData.newVertexToVertexMap, + }; + remapLinkPointArrayJob.Run(VertexCount); + + } + + /// + /// 新しい頂点にリダクション後のPositin/Normal/Tangent/Attributeをコピーする + /// + [BurstCompile] + struct Organize_CopyVertexJob : IJobParallelFor + { + [Unity.Collections.ReadOnly] + public NativeArray joinIndices; + [Unity.Collections.ReadOnly] + public NativeArray vertexRemapIndices; + [Unity.Collections.ReadOnly] + public NativeArray oldAttributes; + [Unity.Collections.ReadOnly] + public NativeArray oldLocalPositions; + [Unity.Collections.ReadOnly] + public NativeArray oldLocalNormals; + [Unity.Collections.ReadOnly] + public NativeArray oldLocalTangents; + + [NativeDisableParallelForRestriction] + [Unity.Collections.WriteOnly] + public NativeArray newAttributes; + [NativeDisableParallelForRestriction] + [Unity.Collections.WriteOnly] + public NativeArray newLocalPositions; + [NativeDisableParallelForRestriction] + [Unity.Collections.WriteOnly] + public NativeArray newLocalNormals; + [NativeDisableParallelForRestriction] + [Unity.Collections.WriteOnly] + public NativeArray newLocalTangents; + + public void Execute(int index) + { + int join = joinIndices[index]; + if (join < 0) + { + // live + int remapIndex = vertexRemapIndices[index]; + newAttributes[remapIndex] = oldAttributes[index]; + newLocalPositions[remapIndex] = oldLocalPositions[index]; + newLocalNormals[remapIndex] = oldLocalNormals[index]; + newLocalTangents[remapIndex] = oldLocalTangents[index]; + } + } + } + + /// + /// 新しいボーンウエイトリストを作成する + /// + [BurstCompile] + struct Organize_RemapBoneWeightJob : IJobParallelFor + { + [Unity.Collections.ReadOnly] + public NativeArray joinIndices; + [Unity.Collections.ReadOnly] + public NativeArray vertexRemapIndices; + [Unity.Collections.ReadOnly] + public NativeParallelHashMap useSkinBoneMap; + + [Unity.Collections.ReadOnly] + public NativeArray oldSkinBoneIndices; + [Unity.Collections.ReadOnly] + public NativeArray oldBoneWeights; + [NativeDisableParallelForRestriction] + [Unity.Collections.WriteOnly] + public NativeArray newBoneWeights; + + public void Execute(int vindex) + { + int join = joinIndices[vindex]; + if (join < 0) + { + // live + int remapIndex = vertexRemapIndices[vindex]; + var bw = oldBoneWeights[vindex]; + + // ボーンインデックスリマップ + for (int j = 0; j < 4; j++) + { + if (bw.weights[j] > 0.0f) + { + int oldBoneIndex = bw.boneIndices[j]; + bw.boneIndices[j] = useSkinBoneMap[oldBoneIndex]; + } + else + { + bw.boneIndices[j] = 0; + } + } + newBoneWeights[remapIndex] = bw; + } + } + } + + /// + /// 新しい頂点の接続頂点リストを作成する + /// + [BurstCompile] + struct Organize_RemapLinkPointArrayJob : IJobParallelFor + { + [Unity.Collections.ReadOnly] + public NativeArray joinIndices; + [Unity.Collections.ReadOnly] + public NativeArray vertexRemapIndices; + [Unity.Collections.ReadOnly] + public NativeParallelMultiHashMap oldVertexToVertexMap; + [NativeDisableParallelForRestriction] + public NativeParallelMultiHashMap newVertexToVertexMap; + + public void Execute(int vindex) + { + int join = joinIndices[vindex]; + if (join >= 0) + return; // 自身は削除されている + + int newIndex = vertexRemapIndices[vindex]; + + foreach (var oldVertexIndex in oldVertexToVertexMap.GetValuesForKey((ushort)vindex)) + { + int newIndex2 = vertexRemapIndices[oldVertexIndex]; + //Debug.Assert(newIndex != newIndex2); + newVertexToVertexMap.MC2UniqueAdd((ushort)newIndex, (ushort)newIndex2); + } + + //Debug.Log($"[{newIndex}] cnt:{newVertexToVertexMap.CountValuesForKey((ushort)newIndex)}"); + //Debug.Assert(newVertexToVertexMap.ContainsKey((ushort)newIndex)); + //Debug.Assert(newVertexToVertexMap.CountValuesForKey((ushort)newIndex) > 0); + } + } + + //========================================================================================= + /// + /// 新しいラインとトライアングルを生成する + /// + /// + void OrganizationCreateLineTriangle(ReductionWorkData workData) + { + // 新しい頂点接続情報からエッジセットを作成する + var createLineTriangleJob = new Organize_CreateLineTriangleJob() + { + newVertexCount = workData.newVertexCount, + newVertexToVertexMap = workData.newVertexToVertexMap, + edgeSet = workData.edgeSet, + }; + createLineTriangleJob.Run(); + + // エッジセットからラインとトライアングルセットを作成する + var createLineTriangleJob2 = new Organize_CreateLineTriangleJob2() + { + newVertexToVertexMap = workData.newVertexToVertexMap, + newLineList = workData.newLineList, + edgeSet = workData.edgeSet, + triangleSet = workData.triangleSet, + }; + createLineTriangleJob2.Run(); + + // トライアングルセットからトライアングルリストを作成する + var createNewTriangleJob3 = new Organize_CreateNewTriangleJob3() + { + newTriangleList = workData.newTriangleList, + triangleSet = workData.triangleSet, + }; + createNewTriangleJob3.Run(); + } + + /// + /// エッジセットを作成する + /// + [BurstCompile] + struct Organize_CreateLineTriangleJob : IJob + { + public int newVertexCount; + + [Unity.Collections.ReadOnly] + public NativeParallelMultiHashMap newVertexToVertexMap; + + [Unity.Collections.WriteOnly] + public NativeParallelHashSet edgeSet; + + public void Execute() + { + // 新しい頂点接続情報からエッジセットを作成する + //Debug.Log($"newVertexCount:{newVertexCount}"); + for (int vindex = 0; vindex < newVertexCount; vindex++) + { + //Debug.Assert(newVertexToVertexMap.CountValuesForKey((ushort)vindex) > 0); + + foreach (ushort vindex2 in newVertexToVertexMap.GetValuesForKey((ushort)vindex)) + { + int2 edge = DataUtility.PackInt2(vindex, vindex2); + edgeSet.Add(edge); + + //Debug.Log($"edge {vindex} -> {vindex2}"); + } + } + } + } + + /// + /// エッジセットからラインとトライアングルセットを作成する + /// + [BurstCompile] + struct Organize_CreateLineTriangleJob2 : IJob + { + [Unity.Collections.ReadOnly] + public NativeParallelMultiHashMap newVertexToVertexMap; + + [Unity.Collections.WriteOnly] + public NativeList newLineList; + + [Unity.Collections.ReadOnly] + public NativeParallelHashSet edgeSet; + [Unity.Collections.WriteOnly] + public NativeParallelHashSet triangleSet; + + public void Execute() + { + // エッジセットからトライアングルとラインを生成する + foreach (int2 edge in edgeSet) + { + int tcnt = 0; + foreach (ushort vindex in newVertexToVertexMap.GetValuesForKey((ushort)edge.x)) + { + if (vindex == edge.x || vindex == edge.y) + continue; + + if (newVertexToVertexMap.MC2Contains((ushort)edge.y, vindex)) + { + // トライアングル生成 + int3 tri = DataUtility.PackInt3(edge.x, edge.y, vindex); + triangleSet.Add(tri); + tcnt++; + + //if (math.all(tri - 927) == false) + // Debug.Log($"tri:{tri}"); + } + } + // トライアングルが生成出来ない場合はラインとして登録する + if (tcnt == 0) + { + newLineList.Add(edge); + + //if (math.all(edge - 927) == false) + // Debug.Log($"line:{edge}"); + } + } + } + } + + /// + /// トライアングルセットからトライアングルリストを作成する + /// + [BurstCompile] + struct Organize_CreateNewTriangleJob3 : IJob + { + [Unity.Collections.WriteOnly] + public NativeList newTriangleList; + + [Unity.Collections.ReadOnly] + public NativeParallelHashSet triangleSet; + + public void Execute() + { + // トライアングルマップからトライアングルリストを生成する + foreach (int3 tri in triangleSet) + { + int3 newTri = tri; + newTriangleList.Add(newTri); + + //if (math.all(tri - 927) == false) + // Debug.Log($"new tri:{tri}"); + } + } + } + + //========================================================================================= + /// + /// リダクション結果をvmeshに反映させる + /// + /// + /// + void OrganizeStoreVirtualMesh(ReductionWorkData workData) + { + try + { + int vcnt = workData.newVertexCount; + + // 参照インデックス + // すべて連番で再設定する + referenceIndices.Dispose(); + referenceIndices = new ExSimpleNativeArray(vcnt); + JobUtility.SerialNumberRun(referenceIndices.GetNativeArray(), vcnt); + + // attribute + attributes.Dispose(); + attributes = workData.newAttributes; + workData.newAttributes = null; + + // positin + localPositions.Dispose(); + localPositions = workData.newLocalPositions; + workData.newLocalPositions = null; + + // normal + localNormals.Dispose(); + localNormals = workData.newLocalNormals; + workData.newLocalNormals = null; + + // tangent + localTangents.Dispose(); + localTangents = workData.newLocalTangents; + workData.newLocalTangents = null; + + // uv + uv.Dispose(); + uv = workData.newUv; + workData.newUv = null; + + // bone weight + boneWeights.Dispose(); + boneWeights = workData.newBoneWeights; + workData.newBoneWeights = null; + + // line + lines.Dispose(); + lines = new ExSimpleNativeArray(workData.newLineList); + + // triangle + triangles.Dispose(); + triangles = new ExSimpleNativeArray(workData.newTriangleList); + + // トランスフォーム情報再編成 + transformData.OrganizeReductionTransform(this, workData); + + // skin bone index + skinBoneTransformIndices.Dispose(); + skinBoneTransformIndices = new ExSimpleNativeArray(workData.newSkinBoneTransformIndices); + + // skin bone bind pose + skinBoneBindPoses.Dispose(); + skinBoneBindPoses = new ExSimpleNativeArray(workData.newSkinBoneBindPoseList); + + // 元の頂点の結合頂点インデックス + joinIndices = new NativeArray(workData.vertexRemapIndices, Allocator.Persistent); + } + catch (Exception) + { + result.SetError(Define.Result.Reduction_StoreVirtualMeshError); + } + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/VirtualMesh/Function/VirtualMeshReduction.cs.meta b/Assets/MagicaCloth2/Scripts/Core/VirtualMesh/Function/VirtualMeshReduction.cs.meta new file mode 100644 index 00000000..ec044f35 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/VirtualMesh/Function/VirtualMeshReduction.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 90031fc5a00f3f045b88eac913436848 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/VirtualMesh/Function/VirtualMeshReduction.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/VirtualMesh/Function/VirtualMeshSerialization.cs b/Assets/MagicaCloth2/Scripts/Core/VirtualMesh/Function/VirtualMeshSerialization.cs new file mode 100644 index 00000000..6a223f46 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/VirtualMesh/Function/VirtualMeshSerialization.cs @@ -0,0 +1,291 @@ +// Magica Cloth 2. +// Copyright (c) 2024 MagicaSoft. +// https://magicasoft.jp +using System; +using System.Collections.Generic; +using System.Text; +using Unity.Collections; +using Unity.Mathematics; +using UnityEngine; + +namespace MagicaCloth2 +{ + public partial class VirtualMesh + { + /// + /// PreBuildの共有部分データ + /// + [System.Serializable] + public class ShareSerializationData + { + public string name; + public MeshType meshType; + public bool isBoneCloth; + + // 基本 + public ExSimpleNativeArray.SerializationData referenceIndices; + public ExSimpleNativeArray.SerializationData attributes; + public ExSimpleNativeArray.SerializationData localPositions; + public ExSimpleNativeArray.SerializationData localNormals; + public ExSimpleNativeArray.SerializationData localTangents; + public ExSimpleNativeArray.SerializationData uv; + public ExSimpleNativeArray.SerializationData boneWeights; + public ExSimpleNativeArray.SerializationData triangles; + public ExSimpleNativeArray.SerializationData lines; + public int centerTransformIndex; + public float4x4 initLocalToWorld; + public float4x4 initWorldToLocal; + public quaternion initRotation; + public quaternion initInverseRotation; + public float3 initScale; + public int skinRootIndex; + public ExSimpleNativeArray.SerializationData skinBoneTransformIndices; + public ExSimpleNativeArray.SerializationData skinBoneBindPoses; + public TransformData.ShareSerializationData transformData; + public AABB boundingBox; + public float averageVertexDistance; + public float maxVertexDistance; + + // プロキシメッシュ + public byte[] vertexToTriangles; + public byte[] vertexToVertexIndexArray; + public byte[] vertexToVertexDataArray; + public byte[] edges; + public byte[] edgeFlags; + public int2[] edgeToTrianglesKeys; + public ushort[] edgeToTrianglesValues; + public byte[] vertexBindPosePositions; + public byte[] vertexBindPoseRotations; + public byte[] vertexToTransformRotations; + public byte[] vertexDepths; + public byte[] vertexRootIndices; + public byte[] vertexParentIndices; + public byte[] vertexChildIndexArray; + public byte[] vertexChildDataArray; + public byte[] vertexLocalPositions; + public byte[] vertexLocalRotations; + public byte[] normalAdjustmentRotations; + public byte[] baseLineFlags; + public byte[] baseLineStartDataIndices; + public byte[] baseLineDataCounts; + public byte[] baseLineData; + public int[] customSkinningBoneIndices; + public ushort[] centerFixedList; + public float3 localCenterPosition; + + // マッピングメッシュ + public float3 centerWorldPosition; + public quaternion centerWorldRotation; + public float3 centerWorldScale; + public float4x4 toProxyMatrix; + public quaternion toProxyRotation; + + public override string ToString() + { + StringBuilder sb = new StringBuilder(1024); + + sb.AppendLine("===== VirtualMesh.SerializeData ====="); + sb.AppendLine($"name:{name}"); + sb.AppendLine($"meshType:{meshType}"); + sb.AppendLine($"isBoneCloth:{isBoneCloth}"); + sb.AppendLine($"VertexCount:{attributes.count}"); + sb.AppendLine($"TriangleCount:{triangles.count}"); + sb.AppendLine($"LineCount:{lines.count}"); + + return sb.ToString(); + } + } + + public ShareSerializationData ShareSerialize() + { + var sdata = new ShareSerializationData(); + try + { + sdata.name = name; + sdata.meshType = meshType; + sdata.isBoneCloth = isBoneCloth; + + // 基本 + sdata.referenceIndices = referenceIndices.Serialize(); + sdata.attributes = attributes.Serialize(); + sdata.localPositions = localPositions.Serialize(); + sdata.localNormals = localNormals.Serialize(); + sdata.localTangents = localTangents.Serialize(); + sdata.uv = uv.Serialize(); + sdata.boneWeights = boneWeights.Serialize(); + sdata.triangles = triangles.Serialize(); + sdata.lines = lines.Serialize(); + sdata.centerTransformIndex = centerTransformIndex; + sdata.initLocalToWorld = initLocalToWorld; + sdata.initWorldToLocal = initWorldToLocal; + sdata.initRotation = initRotation; + sdata.initInverseRotation = initInverseRotation; + sdata.initScale = initScale; + sdata.skinRootIndex = skinRootIndex; + sdata.skinBoneTransformIndices = skinBoneTransformIndices.Serialize(); + sdata.skinBoneBindPoses = skinBoneBindPoses.Serialize(); + sdata.transformData = transformData?.ShareSerialize(); + if (boundingBox.IsCreated) + sdata.boundingBox = boundingBox.Value; + if (averageVertexDistance.IsCreated) + sdata.averageVertexDistance = averageVertexDistance.Value; + if (maxVertexDistance.IsCreated) + sdata.maxVertexDistance = maxVertexDistance.Value; + + // プロキシメッシュ + sdata.vertexToTriangles = vertexToTriangles.MC2ToRawBytes(); + sdata.vertexToVertexIndexArray = vertexToVertexIndexArray.MC2ToRawBytes(); + sdata.vertexToVertexDataArray = vertexToVertexDataArray.MC2ToRawBytes(); + sdata.edges = edges.MC2ToRawBytes(); + sdata.edgeFlags = edgeFlags.MC2ToRawBytes(); + (sdata.edgeToTrianglesKeys, sdata.edgeToTrianglesValues) = edgeToTriangles.MC2Serialize(); + sdata.vertexBindPosePositions = vertexBindPosePositions.MC2ToRawBytes(); + sdata.vertexBindPoseRotations = vertexBindPoseRotations.MC2ToRawBytes(); + sdata.vertexToTransformRotations = vertexToTransformRotations.MC2ToRawBytes(); + sdata.vertexDepths = vertexDepths.MC2ToRawBytes(); + sdata.vertexRootIndices = vertexRootIndices.MC2ToRawBytes(); + sdata.vertexParentIndices = vertexParentIndices.MC2ToRawBytes(); + sdata.vertexChildIndexArray = vertexChildIndexArray.MC2ToRawBytes(); + sdata.vertexChildDataArray = vertexChildDataArray.MC2ToRawBytes(); + sdata.vertexLocalPositions = vertexLocalPositions.MC2ToRawBytes(); + sdata.vertexLocalRotations = vertexLocalRotations.MC2ToRawBytes(); + sdata.normalAdjustmentRotations = normalAdjustmentRotations.MC2ToRawBytes(); + sdata.baseLineFlags = baseLineFlags.MC2ToRawBytes(); + sdata.baseLineStartDataIndices = baseLineStartDataIndices.MC2ToRawBytes(); + sdata.baseLineDataCounts = baseLineDataCounts.MC2ToRawBytes(); + sdata.baseLineData = baseLineData.MC2ToRawBytes(); + DataUtility.ArrayCopy(customSkinningBoneIndices, ref sdata.customSkinningBoneIndices); + DataUtility.ArrayCopy(centerFixedList, ref sdata.centerFixedList); + if (localCenterPosition.IsCreated) + sdata.localCenterPosition = localCenterPosition.Value; + + // マッピングメッシュ + sdata.centerWorldPosition = centerWorldPosition; + sdata.centerWorldRotation = centerWorldRotation; + sdata.centerWorldScale = centerWorldScale; + sdata.toProxyMatrix = toProxyMatrix; + sdata.toProxyRotation = toProxyRotation; + } + catch (Exception exception) + { + Debug.LogException(exception); + } + + return sdata; + } + + public static VirtualMesh ShareDeserialize(ShareSerializationData sdata) + { + var vmesh = new VirtualMesh(); + vmesh.isManaged = true; + + try + { + vmesh.name = sdata.name; + vmesh.meshType = sdata.meshType; + vmesh.isBoneCloth = sdata.isBoneCloth; + + // 基本 + vmesh.referenceIndices.Deserialize(sdata.referenceIndices); + vmesh.attributes.Deserialize(sdata.attributes); + vmesh.localPositions.Deserialize(sdata.localPositions); + vmesh.localNormals.Deserialize(sdata.localNormals); + vmesh.localTangents.Deserialize(sdata.localTangents); + vmesh.uv.Deserialize(sdata.uv); + vmesh.boneWeights.Deserialize(sdata.boneWeights); + vmesh.triangles.Deserialize(sdata.triangles); + vmesh.lines.Deserialize(sdata.lines); + vmesh.centerTransformIndex = sdata.centerTransformIndex; + vmesh.initLocalToWorld = sdata.initLocalToWorld; + vmesh.initWorldToLocal = sdata.initWorldToLocal; + vmesh.initRotation = sdata.initRotation; + vmesh.initInverseRotation = sdata.initInverseRotation; + vmesh.initScale = sdata.initScale; + vmesh.skinRootIndex = sdata.skinRootIndex; + vmesh.skinBoneTransformIndices.Deserialize(sdata.skinBoneTransformIndices); + vmesh.skinBoneBindPoses.Deserialize(sdata.skinBoneBindPoses); + vmesh.transformData = TransformData.ShareDeserialize(sdata.transformData); + vmesh.boundingBox = new NativeReference(sdata.boundingBox, Allocator.Persistent); + vmesh.averageVertexDistance = new NativeReference(sdata.averageVertexDistance, Allocator.Persistent); + vmesh.maxVertexDistance = new NativeReference(sdata.maxVertexDistance, Allocator.Persistent); + + // プロキシメッシュ + vmesh.vertexToTriangles = NativeArrayExtensions.MC2FromRawBytes>(sdata.vertexToTriangles); + vmesh.vertexToVertexIndexArray = NativeArrayExtensions.MC2FromRawBytes(sdata.vertexToVertexIndexArray); + vmesh.vertexToVertexDataArray = NativeArrayExtensions.MC2FromRawBytes(sdata.vertexToVertexDataArray); + vmesh.edges = NativeArrayExtensions.MC2FromRawBytes(sdata.edges); + vmesh.edgeFlags = NativeArrayExtensions.MC2FromRawBytes(sdata.edgeFlags); + vmesh.edgeToTriangles = NativeMultiHashMapExtensions.MC2Deserialize(sdata.edgeToTrianglesKeys, sdata.edgeToTrianglesValues); + vmesh.vertexBindPosePositions = NativeArrayExtensions.MC2FromRawBytes(sdata.vertexBindPosePositions); + vmesh.vertexBindPoseRotations = NativeArrayExtensions.MC2FromRawBytes(sdata.vertexBindPoseRotations); + vmesh.vertexToTransformRotations = NativeArrayExtensions.MC2FromRawBytes(sdata.vertexToTransformRotations); + vmesh.vertexDepths = NativeArrayExtensions.MC2FromRawBytes(sdata.vertexDepths); + vmesh.vertexRootIndices = NativeArrayExtensions.MC2FromRawBytes(sdata.vertexRootIndices); + vmesh.vertexParentIndices = NativeArrayExtensions.MC2FromRawBytes(sdata.vertexParentIndices); + vmesh.vertexChildIndexArray = NativeArrayExtensions.MC2FromRawBytes(sdata.vertexChildIndexArray); + vmesh.vertexChildDataArray = NativeArrayExtensions.MC2FromRawBytes(sdata.vertexChildDataArray); + vmesh.vertexLocalPositions = NativeArrayExtensions.MC2FromRawBytes(sdata.vertexLocalPositions); + vmesh.vertexLocalRotations = NativeArrayExtensions.MC2FromRawBytes(sdata.vertexLocalRotations); + vmesh.normalAdjustmentRotations = NativeArrayExtensions.MC2FromRawBytes(sdata.normalAdjustmentRotations); + vmesh.baseLineFlags = NativeArrayExtensions.MC2FromRawBytes(sdata.baseLineFlags); + vmesh.baseLineStartDataIndices = NativeArrayExtensions.MC2FromRawBytes(sdata.baseLineStartDataIndices); + vmesh.baseLineDataCounts = NativeArrayExtensions.MC2FromRawBytes(sdata.baseLineDataCounts); + vmesh.baseLineData = NativeArrayExtensions.MC2FromRawBytes(sdata.baseLineData); + DataUtility.ArrayCopy(sdata.customSkinningBoneIndices, ref vmesh.customSkinningBoneIndices); + DataUtility.ArrayCopy(sdata.centerFixedList, ref vmesh.centerFixedList); + vmesh.localCenterPosition = new NativeReference(sdata.localCenterPosition, Allocator.Persistent); + + // マッピングメッシュ + vmesh.centerWorldPosition = sdata.centerWorldPosition; + vmesh.centerWorldRotation = sdata.centerWorldRotation; + vmesh.centerWorldScale = sdata.centerWorldScale; + vmesh.toProxyMatrix = sdata.toProxyMatrix; + vmesh.toProxyRotation = sdata.toProxyRotation; + + vmesh.result.SetSuccess(); + } + catch (Exception exception) + { + Debug.LogException(exception); + vmesh.result.SetError(Define.Result.PreBuildData_VirtualMeshDeserializationException); + } + + return vmesh; + } + + //========================================================================================= + /// + /// PreBuildの固有部分データ + /// + [System.Serializable] + public class UniqueSerializationData : ITransform + { + public TransformData.UniqueSerializationData transformData; + + public void GetUsedTransform(HashSet transformSet) + { + transformData?.GetUsedTransform(transformSet); + } + + public void ReplaceTransform(Dictionary replaceDict) + { + transformData?.ReplaceTransform(replaceDict); + } + } + + public UniqueSerializationData UniqueSerialize() + { + var sdata = new UniqueSerializationData(); + try + { + sdata.transformData = transformData?.UniqueSerialize(); + } + catch (Exception exception) + { + Debug.LogException(exception); + } + + return sdata; + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/VirtualMesh/Function/VirtualMeshSerialization.cs.meta b/Assets/MagicaCloth2/Scripts/Core/VirtualMesh/Function/VirtualMeshSerialization.cs.meta new file mode 100644 index 00000000..eb1daf84 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/VirtualMesh/Function/VirtualMeshSerialization.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 0d0b2768c9c7600468b9f1a7b39dd80d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/VirtualMesh/Function/VirtualMeshSerialization.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/VirtualMesh/Function/VirtualMeshWork.cs b/Assets/MagicaCloth2/Scripts/Core/VirtualMesh/Function/VirtualMeshWork.cs new file mode 100644 index 00000000..0c0eecb4 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/VirtualMesh/Function/VirtualMeshWork.cs @@ -0,0 +1,465 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using System; +using Unity.Burst; +using Unity.Collections; +using Unity.Jobs; +using Unity.Mathematics; +using UnityEngine; + +namespace MagicaCloth2 +{ + public partial class VirtualMesh + { + //========================================================================================= + /// + /// 頂点間の平均/最大距離を調べる(スレッド可) + /// 結果はaverageVertexDistance/maxVertexDistanceに格納される + /// + internal void CalcAverageAndMaxVertexDistanceRun() + { + try + { + if (averageVertexDistance.IsCreated == false) + averageVertexDistance = new NativeReference(Allocator.Persistent); + if (maxVertexDistance.IsCreated == false) + maxVertexDistance = new NativeReference(Allocator.Persistent); + + averageVertexDistance.Value = 0; + maxVertexDistance.Value = 0; + using var averageCount = new NativeReference(Allocator.TempJob); + + // triangle + if (TriangleCount > 0) + { + var job = new Work_AverageTriangleDistanceJob() + { + vcnt = VertexCount, + tcnt = TriangleCount, + localPositions = localPositions.GetNativeArray(), + triangles = triangles.GetNativeArray(), + averageVertexDistance = averageVertexDistance, + averageCount = averageCount, + maxVertexDistance = maxVertexDistance, + }; + job.Run(); + } + + // line + if (LineCount > 0) + { + var job = new Work_AverageLineDistanceJob() + { + vcnt = VertexCount, + lcnt = LineCount, + localPositions = localPositions.GetNativeArray(), + lines = lines.GetNativeArray(), + averageVertexDistance = averageVertexDistance, + averageCount = averageCount, + maxVertexDistance = maxVertexDistance, + }; + job.Run(); + } + + // 平均化する + int cnt = averageCount.Value; + if (cnt > 0) + { + float sqlen = averageVertexDistance.Value; + averageVertexDistance.Value = math.sqrt(sqlen / cnt); + maxVertexDistance.Value = math.sqrt(maxVertexDistance.Value); + //Debug.Log($"max:{maxVertexDistance.Value}"); + } + } + catch (Exception exception) + { + Debug.LogException(exception); + result.SetError(Define.Result.Reduction_CalcAverageException); + } + } + + [BurstCompile] + struct Work_AverageTriangleDistanceJob : IJob + { + public int vcnt; + public int tcnt; + + [Unity.Collections.ReadOnly] + public NativeArray localPositions; + [Unity.Collections.ReadOnly] + public NativeArray triangles; + + public NativeReference averageVertexDistance; + public NativeReference averageCount; + public NativeReference maxVertexDistance; + + public void Execute() + { + // 調べるトライアングルは最大100まで + int step = math.max(tcnt / 100, 1); + float sumsqlen = 0; + float maxsqlen = 0; + int cnt = 0; + for (int tindex = 0; tindex < tcnt; tindex += step) + { + int3 tri = triangles[tindex]; + var p0 = localPositions[tri.x]; + var p1 = localPositions[tri.y]; + var p2 = localPositions[tri.z]; + float sqlen0 = math.distancesq(p0, p1); + float sqlen1 = math.distancesq(p1, p2); + float sqlen2 = math.distancesq(p2, p0); + sumsqlen += sqlen0; + sumsqlen += sqlen1; + sumsqlen += sqlen2; + cnt += 3; + maxsqlen = math.max(maxsqlen, sqlen0); + maxsqlen = math.max(maxsqlen, sqlen1); + maxsqlen = math.max(maxsqlen, sqlen2); + } + + averageVertexDistance.Value = averageVertexDistance.Value + sumsqlen; + averageCount.Value = averageCount.Value + cnt; + + // 最大 + maxVertexDistance.Value = math.max(maxVertexDistance.Value, maxsqlen); + } + } + + [BurstCompile] + struct Work_AverageLineDistanceJob : IJob + { + public int vcnt; + public int lcnt; + + [Unity.Collections.ReadOnly] + public NativeArray localPositions; + [Unity.Collections.ReadOnly] + public NativeArray lines; + + public NativeReference averageVertexDistance; + public NativeReference averageCount; + public NativeReference maxVertexDistance; + + public void Execute() + { + // 調べるラインは最大100まで + int step = math.max(lcnt / 100, 1); + float sumsqlen = 0; + int cnt = 0; + float maxsqlen = 0; + for (int lindex = 0; lindex < lcnt; lindex += step) + { + int2 line = lines[lindex]; + var p0 = localPositions[line.x]; + var p1 = localPositions[line.y]; + float sqlen = math.distancesq(p0, p1); + sumsqlen += sqlen; + cnt++; + maxsqlen = math.max(maxsqlen, sqlen); + } + + averageVertexDistance.Value = averageVertexDistance.Value + sumsqlen; + averageCount.Value = averageCount.Value + cnt; + + // 最大 + maxVertexDistance.Value = math.max(maxVertexDistance.Value, maxsqlen); + } + } + + //========================================================================================= + /// + /// 頂点インデックスを格納したグリッドマップを作成して返す + /// + /// + /// + internal GridMap CreateVertexIndexGridMapRun(float gridSize) + { + int vcnt = VertexCount; + var gridMap = new GridMap(vcnt); + + if (vcnt > 0) + { + var addJob = new Work_AddVertexIndexGirdMapJob() + { + gridSize = gridSize, + vcnt = vcnt, + positins = localPositions.GetNativeArray(), + gridMap = gridMap.GetMultiHashMap(), + }; + addJob.Run(); + } + + return gridMap; + } + + [BurstCompile] + struct Work_AddVertexIndexGirdMapJob : IJob + { + public float gridSize; + public int vcnt; + + [Unity.Collections.ReadOnly] + public NativeArray positins; + [Unity.Collections.WriteOnly] + public NativeParallelMultiHashMap gridMap; + + public void Execute() + { + for (int vindex = 0; vindex < vcnt; vindex++) + { + float3 pos = positins[vindex]; + GridMap.AddGrid(pos, vindex, gridMap, gridSize); + } + } + } + + //========================================================================================= + public VirtualMeshRaycastHit IntersectRayMesh(float3 rayPos, float3 rayDir, bool doubleSide, float pointRadius) + { + // レイをメッシュローカル空間に変換する + var t = GetCenterTransform(); + float3 localRayPos = t.InverseTransformPoint(rayPos); + float3 localRayDir = t.InverseTransformDirection(rayDir); + float3 rayEndPos = rayPos + rayDir * 1000; + float3 localRayEndPos = t.InverseTransformPoint(rayEndPos); + float localPointRadius = pointRadius / t.lossyScale.x; + + // ヒットバッファ + //int buffSize = (VertexCount + TriangleCount) / 10 + 10; + int buffSize = 100; // おそらく十分な大きさ + using var hitList = new NativeList(buffSize, Allocator.TempJob); + + JobHandle jobHandle = default; + + // トライアングル交差判定 + var job1 = new Work_IntersectTriangleJob() + { + localRayPos = localRayPos, + localRayDir = localRayDir, + localRayEndPos = localRayEndPos, + doubleSide = doubleSide, + + localPositions = localPositions.GetNativeArray(), + triangles = triangles.GetNativeArray(), + + hitList = hitList.AsParallelWriter(), + }; + jobHandle = job1.Schedule(TriangleCount, 16, jobHandle); + + // エッジ交差判定 + var job2 = new Work_IntersectEdgeJob() + { + localRayPos = localRayPos, + localRayDir = localRayDir, + localRayEndPos = localRayEndPos, + //rayDir = rayDir, + rayDir = localRayDir, + + localEdgeRadius = localPointRadius, + localPositions = localPositions.GetNativeArray(), + edges = edges, + edgeToTriangles = edgeToTriangles, + + hitList = hitList.AsParallelWriter(), + }; + jobHandle = job2.Schedule(EdgeCount, 16, jobHandle); + +#if false + // ポイント交差判定 + var job2 = new Work_IntersectPointJob() + { + localRayPos = localRayPos, + localRayDir = localRayDir, + rayDir = rayDir, + + localPointRadius = localPointRadius, + localPositions = localPositions.GetNativeArray(), + vertexToTriangles = vertexToTriangles, + + hitList = hitList.AsParallelWriter(), + }; + jobHandle = job2.Schedule(VertexCount, 16, jobHandle); +#endif + + // ソート + var job3 = new Work_IntersetcSortJob() + { + hitList = hitList, + }; + jobHandle = job3.Schedule(jobHandle); + + // 完了待ち + jobHandle.Complete(); + + // 最も近いヒット情報を返す + var rayhit = hitList.Length > 0 ? hitList[0] : default; + + //Debug.Log($"IntersectMesh: {rayhit}"); + + return rayhit; + } + + [BurstCompile] + struct Work_IntersectTriangleJob : IJobParallelFor + { + public float3 localRayPos; + public float3 localRayDir; + public float3 localRayEndPos; + public bool doubleSide; + + [Unity.Collections.ReadOnly] + public NativeArray localPositions; + [Unity.Collections.ReadOnly] + public NativeArray triangles; + + // output + [Unity.Collections.WriteOnly] + public NativeList.ParallelWriter hitList; + + + public void Execute(int tindex) + { + int3 tri = triangles[tindex]; + var pos0 = localPositions[tri.x]; + var pos1 = localPositions[tri.y]; + var pos2 = localPositions[tri.z]; + + // トライアングルを包む球 + MathUtility.GetTriangleSphere(pos0, pos1, pos2, out float3 sc, out float sr); + + // 球とレイの衝突判定 + float t = 0; + float3 q = 0; + if (MathUtility.IntersectRaySphere(localRayPos, localRayDir, sc, sr, ref t, ref q) == false) + return; + + // トライアングルとレイの詳細判定 + if (MathUtility.IntersectSegmentTriangle(localRayPos, localRayEndPos, pos0, pos1, pos2, doubleSide, out _, out _, out _, out t) == false) + return; + + // 衝突位置 + float3 hitPos = math.lerp(localRayPos, localRayEndPos, t); + + // トライアングル法線 + float3 tn = MathUtility.TriangleNormal(pos0, pos1, pos2); + + // 格納 + //Debug.Log($"Triangle Hit!. tindex:{tindex}, tri:{tri} hitpos:{hitPos}, tn:{tn}"); + var hit = new VirtualMeshRaycastHit(); + hit.type = VirtualMeshPrimitive.Triangle; + hit.index = tindex; + hit.position = hitPos; + hit.distance = t; + hit.normal = tn; + hitList.AddNoResize(hit); + } + } + + [BurstCompile] + struct Work_IntersectEdgeJob : IJobParallelFor + { + public float3 localRayPos; + public float3 localRayDir; + public float3 localRayEndPos; + public float3 rayDir; + + public float localEdgeRadius; + [Unity.Collections.ReadOnly] + public NativeArray localPositions; + [Unity.Collections.ReadOnly] + public NativeArray edges; + [Unity.Collections.ReadOnly] + public NativeParallelMultiHashMap edgeToTriangles; + + // output + [Unity.Collections.WriteOnly] + public NativeList.ParallelWriter hitList; + + public void Execute(int eindex) + { + int2 edge = edges[eindex]; + + // エッジがトライアングルに属する場合は無効 + if (edgeToTriangles.ContainsKey(edge)) + return; + + var pos0 = localPositions[edge.x]; + var pos1 = localPositions[edge.y]; + + // 2つの直線の衝突判定 + float distSq = MathUtility.ClosestPtSegmentSegment(pos0, pos1, localRayPos, localRayEndPos, out float s, out float t, out float3 c1, out float3 c2); + float dist = math.sqrt(distSq); + if (dist > localEdgeRadius) + return; + + // 衝突位置 + float3 hitPos = c2; + + // 格納 + var hit = new VirtualMeshRaycastHit(); + hit.type = VirtualMeshPrimitive.Edge; + hit.index = eindex; + hit.position = hitPos; + hit.distance = t; + hit.normal = -rayDir; + hitList.AddNoResize(hit); + } + } + + [BurstCompile] + struct Work_IntersectPointJob : IJobParallelFor + { + public float3 localRayPos; + public float3 localRayDir; + public float3 rayDir; + + public float localPointRadius; + [Unity.Collections.ReadOnly] + public NativeArray localPositions; + [Unity.Collections.ReadOnly] + public NativeArray> vertexToTriangles; + + // output + [Unity.Collections.WriteOnly] + public NativeList.ParallelWriter hitList; + + public void Execute(int vindex) + { + // 頂点がトライアングルに接続されている場合は無効 + if (vertexToTriangles[vindex].Length > 0) + return; + + var pos = localPositions[vindex]; + + // 球とレイの衝突判定 + float t = 0; + float3 q = 0; + if (MathUtility.IntersectRaySphere(localRayPos, localRayDir, pos, localPointRadius, ref t, ref q) == false) + return; + + // 格納 + var hit = new VirtualMeshRaycastHit(); + hit.type = VirtualMeshPrimitive.Point; + hit.index = vindex; + hit.position = pos; + hit.distance = t; + hit.normal = -rayDir; + hitList.AddNoResize(hit); + } + } + + [BurstCompile] + struct Work_IntersetcSortJob : IJob + { + public NativeList hitList; + + public void Execute() + { + if (hitList.Length > 1) + hitList.Sort(); + } + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/VirtualMesh/Function/VirtualMeshWork.cs.meta b/Assets/MagicaCloth2/Scripts/Core/VirtualMesh/Function/VirtualMeshWork.cs.meta new file mode 100644 index 00000000..853f3fb2 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/VirtualMesh/Function/VirtualMeshWork.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 7547f9437ec9b1f45bb3c8305bb8aadc +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/VirtualMesh/Function/VirtualMeshWork.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/VirtualMesh/VertexAttribute.cs b/Assets/MagicaCloth2/Scripts/Core/VirtualMesh/VertexAttribute.cs new file mode 100644 index 00000000..74da2f7d --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/VirtualMesh/VertexAttribute.cs @@ -0,0 +1,167 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using System; +using System.Runtime.CompilerServices; + +namespace MagicaCloth2 +{ + /// + /// 頂点の属性 + /// + [System.Serializable] + public struct VertexAttribute : IEquatable + { + /// + /// ビットフラグ + /// + public const byte Flag_Fixed = 0x01; // 固定 + public const byte Flag_Move = 0x02; // 移動 + //public const byte Flag_Ignore = 0x04; // 無視(シミュレーションの対象としない):一旦オミット! + public const byte Flag_InvalidMotion = 0x08; // モーション制約無効 + public const byte Flag_DisableCollision = 0x10; // コリジョン無効 + public const byte Flag_ZeroDistance = 0x20; // この頂点は親との距離がゼロ + public const byte Flag_Triangle = 0x80; // この頂点はトライアングルに属している + + public static readonly VertexAttribute Invalid = new VertexAttribute(); + public static readonly VertexAttribute Fixed = new VertexAttribute(Flag_Fixed); + public static readonly VertexAttribute Move = new VertexAttribute(Flag_Move); + public static readonly VertexAttribute DisableCollision = new VertexAttribute(Flag_DisableCollision); + + //========================================================================================= + /// + /// 属性値(ビットフラグ) + /// + public byte Value; + + //========================================================================================= + public VertexAttribute(byte initialValue = 0) + { + Value = initialValue; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Clear() + { + Value = 0; + } + + /// + /// フラグ設定 + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void SetFlag(byte flag, bool sw) + { + if (sw) + Value |= flag; + else + Value = (byte)(Value & ~flag); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void SetFlag(VertexAttribute attr, bool sw) + { + if (sw) + Value |= attr.Value; + else + Value = (byte)(Value & ~attr.Value); + } + + /// + /// フラグ判定 + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool IsSet(byte flag) + { + return (Value & flag) != 0; + } + + /// + /// 無効属性判定(Move/Fixedのどれでもない場合) + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool IsInvalid() => IsSet(Flag_Fixed | Flag_Move) == false; + //public bool IsInvalid() => IsSet(Flag_Fixed | Flag_Move | Flag_Ignore) == false; + + /// + /// 固定属性判定 + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool IsFixed() => IsSet(Flag_Fixed); + + /// + /// 移動属性判定 + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool IsMove() => IsSet(Flag_Move); + + /// + /// 移動しないパーティクルか判定する + /// これは固定属性以外にも掴まれたことにより動かなくなったパーティクルも含まれる + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool IsDontMove() => !IsSet(Flag_Move); + + /// + /// 無視属性判定 + /// + /// + //[MethodImpl(MethodImplOptions.AggressiveInlining)] + //public bool IsIgnore() => IsSet(Flag_Ignore); + + /// + /// モーション制約の有効判定 + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool IsMotion() => IsSet(Flag_InvalidMotion) == false; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool IsDisableCollision() => IsSet(Flag_DisableCollision); + + //========================================================================================= + /// + /// 2つの頂点属性を結合して新しい属性を返す + /// 基本的に属性値が低い方が優先される(無効(0)>固定(1)>移動(2)) + /// + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static VertexAttribute JoinAttribute(VertexAttribute attr1, VertexAttribute attr2) + { + // todo:ここは頂点属性が増えると厄介かも + return attr1.Value < attr2.Value ? attr1 : attr2; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool Equals(VertexAttribute other) + { + return Value == other.Value; + } + + public override bool Equals(object obj) + { + return obj is VertexAttribute converted && Equals(converted); + } + + public override int GetHashCode() + { + return Value; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool operator ==(VertexAttribute lhs, VertexAttribute rhs) { return lhs.Value == rhs.Value; } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool operator !=(VertexAttribute lhs, VertexAttribute rhs) { return lhs.Value != rhs.Value; } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/VirtualMesh/VertexAttribute.cs.meta b/Assets/MagicaCloth2/Scripts/Core/VirtualMesh/VertexAttribute.cs.meta new file mode 100644 index 00000000..19c658cb --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/VirtualMesh/VertexAttribute.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: bd2250d458ce5eb4f9fbb2ad312b5762 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/VirtualMesh/VertexAttribute.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/VirtualMesh/VirtualMesh.cs b/Assets/MagicaCloth2/Scripts/Core/VirtualMesh/VirtualMesh.cs new file mode 100644 index 00000000..bc028ac7 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/VirtualMesh/VirtualMesh.cs @@ -0,0 +1,534 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using System; +using System.Text; +using Unity.Collections; +using Unity.Mathematics; + +namespace MagicaCloth2 +{ + /// + /// MagicaClothで利用する仮想メッシュ構造 + /// ・メッシュの親子関係により頂点が連動する + /// ・トライアングルだけでなくライン構造も認める + /// ・スレッドで利用できるようにする + /// ・頂点数は最大65535に制限、ただし一部を除きインデックスはintで扱う + /// + public partial class VirtualMesh : IDisposable, IValid + { + + public string name = string.Empty; + + public ResultCode result = new ResultCode(); + + public bool isManaged; // PreBuild DeserializeManager管理 + + /// + /// メッシュタイプ + /// + public enum MeshType + { + /// + /// 通常のメッシュ + /// 座標計算:Transformからスキニング、法線接線計算:Transformからスキニング + /// + NormalMesh = 0, + + /// + /// Transform連動メッシュ + /// 座標計算:Transform直値、法線接線計算:Transform直値 + /// + NormalBoneMesh = 1, + + /// + /// プロキシメッシュ + /// 法線接線の計算を接続するトライアングルから求める + /// 座標計算:Transformからスキニング、法線接線計算:接続トライアングル平均化 or スキニング直値 + /// + ProxyMesh = 2, + + /// + /// Transform連動プロキシメッシュ + /// シミュレーション前にTransformの復元を行い、シミュレーション後にTransformを書き込む + /// 座標計算:Transform直値、法線接線計算:接続トライアングル平均化 or Transform直値 + /// + ProxyBoneMesh = 3, + + /// + /// マッピングメッシュ(MeshClothのみ) + /// メッシュがプロキシメッシュにマッピングされた状態 + /// 座標計算:接続ProxyMesh頂点からスキニング、法線接線計算:接続ProxyMeshからスキニング + /// + Mapping = 4, + } + public MeshType meshType = MeshType.NormalMesh; + + /// + /// Transformと直接連動するかどうか(=BoneCloth) + /// + public bool isBoneCloth = false; + + //========================================================================================= + // メッシュ情報(基本) + //========================================================================================= + /// + /// 現在の頂点が指す元の頂点インデックス + /// + public ExSimpleNativeArray referenceIndices = new ExSimpleNativeArray(); + + /// + /// 頂点属性 + /// + public ExSimpleNativeArray attributes = new ExSimpleNativeArray(); + + public ExSimpleNativeArray localPositions = new ExSimpleNativeArray(); + public ExSimpleNativeArray localNormals = new ExSimpleNativeArray(); + public ExSimpleNativeArray localTangents = new ExSimpleNativeArray(); + + /// + /// VirtualMeshのUVはTangent計算用でありテクスチャマッピング用ではないので注意! + /// + public ExSimpleNativeArray uv = new ExSimpleNativeArray(); + public ExSimpleNativeArray boneWeights = new ExSimpleNativeArray(); + + public ExSimpleNativeArray triangles = new ExSimpleNativeArray(); + public ExSimpleNativeArray lines = new ExSimpleNativeArray(); + + /// + /// メッシュの基準トランスフォーム + /// + public int centerTransformIndex = -1; + + /// + /// このメッシュの基準マトリックスと回転 + /// + public float4x4 initLocalToWorld; + public float4x4 initWorldToLocal; + public quaternion initRotation; + public quaternion initInverseRotation; + public float3 initScale; + + /// + /// 計算用スケール(X軸のみで判定) + /// + public float InitCalcScale => initScale.x; + + /// + /// スキニングルートボーン + /// + public int skinRootIndex = -1; + + /// + /// スキニングボーン + /// + public ExSimpleNativeArray skinBoneTransformIndices = new ExSimpleNativeArray(); + public ExSimpleNativeArray skinBoneBindPoses = new ExSimpleNativeArray(); + + /// + /// このメッシュで利用するTransformの情報 + /// + public TransformData transformData; + + /// + /// バウンディングボックス + /// + public NativeReference boundingBox; + + /// + /// 頂点の平均接続距離 + /// + public NativeReference averageVertexDistance; + + /// + /// 頂点の最大接続距離 + /// + public NativeReference maxVertexDistance; + + public bool IsSuccess => result.IsSuccess(); + public bool IsError => result.IsError(); + public bool IsProcess => result.IsProcess(); + public int VertexCount => localPositions.Count; + public int TriangleCount => triangles.Count; + public int LineCount => lines.Count; + public int SkinBoneCount => skinBoneTransformIndices.Count; + public int TransformCount => transformData?.Count ?? 0; + public bool IsProxy => meshType == MeshType.ProxyMesh || meshType == MeshType.ProxyBoneMesh; + public bool IsMapping => meshType == MeshType.Mapping; + + //========================================================================================= + // 結合/リダクション + //========================================================================================= + /// + /// 結合された頂点範囲(結合もとメッシュが保持する) + /// + public DataChunk mergeChunk; + + /// + /// 元の頂点からの結合とリダクション後の頂点へのインデックス + /// + public NativeArray joinIndices; + + //========================================================================================= + // プロキシメッシュ + //========================================================================================= + /// + /// 頂点ごとの接続トライアングルインデックスと法線接線フリップフラグ(最大7つ) + /// これは法線を再計算するために用いられるもので7つあれば十分であると判断したもの。 + /// そのため正確なトライアングル接続を表していない。 + /// データは12-20bitのuintでパックされている + /// 12(hi) = 法線接線のフリップフラグ(法線:0x1,接線:0x2)。ONの場合フリップ。 + /// 20(low) = トライアングルインデックス。 + /// + public NativeArray> vertexToTriangles; + + /// + /// 頂点ごとの接続頂点インデックス + /// vertexToVertexIndexArrayは頂点ごとのデータ開始インデックス(22bit)とカウンタ(10bit)を1つのuintに結合したもの + /// todo:ここはMultiHashMapのままで良いかもしれない + /// + public NativeArray vertexToVertexIndexArray; + public NativeArray vertexToVertexDataArray; + + /// + /// エッジリスト + /// + public NativeArray edges; + + /// + /// エッジ固有フラグ + /// + public const byte EdgeFlag_Cut = 0x1; // 切り口エッジ + public NativeArray edgeFlags; + + /// + /// エッジごとの接続トライアングルインデックス + /// + public NativeParallelMultiHashMap edgeToTriangles; + + /// + /// 頂点ごとのバインドポーズ + /// 頂点バインドにはスケール値は不要 + /// + public NativeArray vertexBindPosePositions; + public NativeArray vertexBindPoseRotations; + + /// + /// 頂点ごとの計算姿勢からTransformへの変換回転(BoneClothのみ) + /// + public NativeArray vertexToTransformRotations; + + /// + /// 各頂点のレベル(起点は0から) + /// + //public NativeArray vertexLevels; + + /// + /// 各頂点の深さ(0.0-1.0) + /// + public NativeArray vertexDepths; + + /// + /// 各頂点のルートインデックス(-1=なし) + /// + public NativeArray vertexRootIndices; + + /// + /// 各頂点の親頂点インデックス(-1=なし) + /// + public NativeArray vertexParentIndices; + + /// + /// 各頂点の子頂点インデックスリスト + /// + public NativeArray vertexChildIndexArray; + public NativeArray vertexChildDataArray; + + /// + /// 各頂点の親からの基準ローカル座標 + /// + public NativeArray vertexLocalPositions; + + /// + /// 各頂点の親からの基準ローカル回転 + /// + public NativeArray vertexLocalRotations; + + /// + /// 法線調整用回転 + /// + public NativeArray normalAdjustmentRotations; + +#if false + /// + /// 角度計算用基準法線の計算方法 + /// + public enum NormalCalcMode + { + Auto = 0, + X_Axis = 1, + Y_Axis = 2, + Z_Axis = 3, + Point_Outside = 4, + Point_Inside = 5, + //Line_Outside = 6, + //Line_Inside = 7, + } + //public NormalCalcMode normalCalcMode = NormalCalcMode.Auto; + + /// + /// 各頂点の角度計算用基準ローカル回転 + /// -AngleLimitConstraintで使用する + /// pitch/yaw個別制限はv1.0では実装しないので一旦停止させる + /// + //public NativeArray vertexAngleCalcLocalRotations; +#endif + + /// + /// 最大レベル値 + /// + //public NativeReference vertexMaxLevel; + + /// + /// ベースラインごとのフラグ + /// + public const byte BaseLineFlag_IncludeLine = 0x01; // ラインを含む + public NativeArray baseLineFlags; + + /// + /// ベースラインごとのデータ開始インデックス + /// + public NativeArray baseLineStartDataIndices; + + /// + /// ベースラインごとのデータ数 + /// + public NativeArray baseLineDataCounts; + + /// + /// ベースラインデータ(頂点インデックス) + /// + public NativeArray baseLineData; + + /// + /// カスタムスキニングボーンの登録トランスフォームインデックス + /// + public int[] customSkinningBoneIndices; + + /// + /// センター計算用の固定頂点リスト + /// + public ushort[] centerFixedList; + + /// + /// プロキシメッシュ構築時のセンター位置(ローカル) + /// 固定頂点が無い場合は(0,0,0) + /// + public NativeReference localCenterPosition; + + public int BaseLineCount => baseLineStartDataIndices.IsCreated ? baseLineStartDataIndices.Length : 0; + public int EdgeCount => edges.IsCreated ? edges.Length : 0; + public int CustomSkinningBoneCount => customSkinningBoneIndices?.Length ?? 0; + public int CenterFixedPointCount => centerFixedList?.Length ?? 0; + public int NormalAdjustmentRotationCount => normalAdjustmentRotations.IsCreated ? normalAdjustmentRotations.Length : 0; + + //========================================================================================= + // マッピングメッシュ + //========================================================================================= + /// + /// 接続しているプロキシメッシュ + /// + public VirtualMesh mappingProxyMesh; + + /// + /// マッピングメッシュのセンタートランスフォーム情報 + /// 毎フレーム更新される + /// Meshの場合はレンダラーのトランスフォームとなる + /// + public float3 centerWorldPosition; + public quaternion centerWorldRotation; + public float3 centerWorldScale; + + /// + /// 初期状態でのマッピングメッシュへの変換マトリックスと変換回転 + /// この姿勢は初期化時に固定される + /// + public float4x4 toProxyMatrix; + public quaternion toProxyRotation; + + /// + /// マネージャへの登録ID + /// + public int mappingId; + + //========================================================================================= + public VirtualMesh() { } + + public VirtualMesh(bool initialize) + { + if (initialize) + { + transformData = new TransformData(100); + + // 最小限のデータ + averageVertexDistance = new NativeReference(0.0f, Allocator.Persistent); + maxVertexDistance = new NativeReference(0.0f, Allocator.Persistent); + + // 作業中にしておく + result.SetProcess(); + } + } + + public VirtualMesh(string name) : this(true) + { + this.name = name; + } + + public void Dispose() + { + // PreBuild DeserializeManager管理中は破棄させない + if (isManaged) + return; + + result.Clear(); + referenceIndices.Dispose(); + attributes.Dispose(); + localPositions.Dispose(); + localNormals.Dispose(); + localTangents.Dispose(); + uv.Dispose(); + boneWeights.Dispose(); + triangles.Dispose(); + lines.Dispose(); + skinBoneTransformIndices.Dispose(); + skinBoneBindPoses.Dispose(); + + if (joinIndices.IsCreated) + joinIndices.Dispose(); + + if (vertexToTriangles.IsCreated) + vertexToTriangles.Dispose(); + if (vertexToVertexIndexArray.IsCreated) + vertexToVertexIndexArray.Dispose(); + if (vertexToVertexDataArray.IsCreated) + vertexToVertexDataArray.Dispose(); + if (edges.IsCreated) + edges.Dispose(); + if (edgeFlags.IsCreated) + edgeFlags.Dispose(); + if (edgeToTriangles.IsCreated) + edgeToTriangles.Dispose(); + if (vertexBindPosePositions.IsCreated) + vertexBindPosePositions.Dispose(); + if (vertexBindPoseRotations.IsCreated) + vertexBindPoseRotations.Dispose(); + if (vertexToTransformRotations.IsCreated) + vertexToTransformRotations.Dispose(); + if (vertexRootIndices.IsCreated) + vertexRootIndices.Dispose(); + if (vertexParentIndices.IsCreated) + vertexParentIndices.Dispose(); + if (vertexChildIndexArray.IsCreated) + vertexChildIndexArray.Dispose(); + if (vertexChildDataArray.IsCreated) + vertexChildDataArray.Dispose(); + if (baseLineFlags.IsCreated) + baseLineFlags.Dispose(); + if (baseLineStartDataIndices.IsCreated) + baseLineStartDataIndices.Dispose(); + if (baseLineDataCounts.IsCreated) + baseLineDataCounts.Dispose(); + if (baseLineData.IsCreated) + baseLineData.Dispose(); + if (localCenterPosition.IsCreated) + localCenterPosition.Dispose(); + if (vertexLocalPositions.IsCreated) + vertexLocalPositions.Dispose(); + if (vertexLocalRotations.IsCreated) + vertexLocalRotations.Dispose(); + if (normalAdjustmentRotations.IsCreated) + normalAdjustmentRotations.Dispose(); + //if (vertexAngleCalcLocalRotations.IsCreated) + // vertexAngleCalcLocalRotations.Dispose(); + //if (vertexMaxLevel.IsCreated) + // vertexMaxLevel.Dispose(); + //if (vertexLevels.IsCreated) + // vertexLevels.Dispose(); + if (vertexDepths.IsCreated) + vertexDepths.Dispose(); + if (boundingBox.IsCreated) + boundingBox.Dispose(); + if (averageVertexDistance.IsCreated) + averageVertexDistance.Dispose(); + if (maxVertexDistance.IsCreated) + maxVertexDistance.Dispose(); + + transformData?.Dispose(); + } + + public void SetName(string newName) + { + name = newName; + } + + /// + /// 最低限のデータ検証 + /// + /// + public bool IsValid() + { + if (transformData == null) + return false; + + // レンダラーが存在する場合はその存在を確認する + // ただしPreBuildではtransformListは空なのでスキップする + if (centerTransformIndex >= 0 && transformData.IsEmpty == false && transformData.GetTransformFromIndex(centerTransformIndex) == null) + return false; + + return true; + } + + //========================================================================================= + public override string ToString() + { + StringBuilder sb = new StringBuilder(); + + sb.AppendLine($"===== {name} ====="); + sb.AppendLine($"Result:{result.GetResultString()}"); + sb.AppendLine($"Type:{meshType}"); + sb.AppendLine($"Vertex:{VertexCount}"); + sb.AppendLine($"Line:{LineCount}"); + sb.AppendLine($"Triangle:{TriangleCount}"); + sb.AppendLine($"Edge:{EdgeCount}"); + sb.AppendLine($"SkinBone:{SkinBoneCount}"); + sb.AppendLine($"Transform:{TransformCount}"); + if (averageVertexDistance.IsCreated) + sb.AppendLine($"avgDist:{averageVertexDistance.Value}"); + if (maxVertexDistance.IsCreated) + sb.AppendLine($"maxDist:{maxVertexDistance.Value}"); + if (boundingBox.IsCreated) + sb.AppendLine($"AABB:{boundingBox.Value}"); + sb.AppendLine(); + + sb.AppendLine($"<<< Proxy >>>"); + sb.AppendLine($"BaseLine:{BaseLineCount}"); + sb.AppendLine($"EdgeCount:{EdgeCount}"); + int edgeToTrianglesCnt = edgeToTriangles.IsCreated ? edgeToTriangles.Count() : 0; + sb.AppendLine($"edgeToTriangles:{edgeToTrianglesCnt}"); + sb.AppendLine($"CustomSkinningBoneCount:{CustomSkinningBoneCount}"); + sb.AppendLine($"CenterFixedPointCount:{CenterFixedPointCount}"); + sb.AppendLine($"NormalAdjustmentRotationCount:{NormalAdjustmentRotationCount}"); + sb.AppendLine(); + + sb.AppendLine($"<<< Mapping >>>"); + sb.AppendLine($"centerWorldPosition:{centerWorldPosition}"); + sb.AppendLine(); + + //sb.AppendLine($"<<< TransformData >>>"); + sb.AppendLine(transformData?.ToString() ?? "(none)"); + sb.AppendLine(); + + return sb.ToString(); + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/VirtualMesh/VirtualMesh.cs.meta b/Assets/MagicaCloth2/Scripts/Core/VirtualMesh/VirtualMesh.cs.meta new file mode 100644 index 00000000..081e0f64 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/VirtualMesh/VirtualMesh.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 12b26397b658837409cd78bc3343ac9f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/VirtualMesh/VirtualMesh.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/VirtualMesh/VirtualMeshBoneWeight.cs b/Assets/MagicaCloth2/Scripts/Core/VirtualMesh/VirtualMeshBoneWeight.cs new file mode 100644 index 00000000..191b4c45 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/VirtualMesh/VirtualMeshBoneWeight.cs @@ -0,0 +1,142 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using Unity.Mathematics; +using UnityEngine; + +namespace MagicaCloth2 +{ + /// + /// VirtualMeshで利用される頂点のボーンウエイト + /// これはUnity.BoneWeight構造体を再マッピングしたもの + /// + public struct VirtualMeshBoneWeight + { + public float4 weights; + public int4 boneIndices; + + public bool IsValid => weights[0] >= 1e-06f; + + + public VirtualMeshBoneWeight(int4 boneIndices, float4 weights) + { + this.boneIndices = boneIndices; + this.weights = weights; + } + + /// + /// 有効なウエイト数 + /// + public int Count + { + get + { + if (weights[3] > 0.0f) + return 4; + if (weights[2] > 0.0f) + return 3; + if (weights[1] > 0.0f) + return 2; + if (weights[0] > 0.0f) + return 1; + + return 0; + } + } + + public void AddWeight(int boneIndex, float weight) + { + if (weight < 1e-06f) + return; + + // すでに登録済みならばウエイトのみ加算する + int wcnt = 0; + for (int i = 0; i < 4; i++) + { + float w = weights[i]; + if (w == 0.0f) + break; + if (boneIndices[i] == boneIndex) + { + // ウエイト加算 + w += weight; + weights[i] = w; + + // ソート + for (int j = i; j >= 1; j--) + { + if (weights[j] > weights[j - 1]) + { + // swap + w = weights[j - 1]; + weights[j - 1] = weights[j]; + weights[j] = w; + + int x = boneIndices[j - 1]; + boneIndices[j - 1] = boneIndices[j]; + boneIndices[j] = x; + } + } + + return; + } + wcnt++; + } + + + // すでに登録されているウエイトより大きければ挿入する + for (int i = 0; i < 4; i++) + { + float w = weights[i]; + if (w == 0.0f) + { + weights[i] = weight; + boneIndices[i] = boneIndex; + return; + } + else if (weight > w) + { + // 挿入 + for (int j = 2; j >= i; j--) + { + weights[j + 1] = weights[j]; + boneIndices[j + 1] = boneIndices[j]; + } + weights[i] = weight; + boneIndices[i] = boneIndex; + return; + } + } + } + + public void AddWeight(in VirtualMeshBoneWeight bw) + { + if (bw.IsValid) + { + for (int i = 0; i < 4; i++) + { + AddWeight(bw.boneIndices[i], bw.weights[i]); + } + } + } + + /// + /// ウエイトを合計1に調整する + /// + public void AdjustWeight() + { + if (IsValid == false) + return; + + float total = math.csum(weights); + Debug.Assert(total >= 1e-06f); + float scl = 1.0f / total; + weights *= scl; + } + + public override string ToString() + { + return $"[{boneIndices}] w({weights})"; + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/VirtualMesh/VirtualMeshBoneWeight.cs.meta b/Assets/MagicaCloth2/Scripts/Core/VirtualMesh/VirtualMeshBoneWeight.cs.meta new file mode 100644 index 00000000..67c0f83c --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/VirtualMesh/VirtualMeshBoneWeight.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 9bd87b7656af7404ca81798fb1180cea +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/VirtualMesh/VirtualMeshBoneWeight.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/VirtualMesh/VirtualMeshContainer.cs b/Assets/MagicaCloth2/Scripts/Core/VirtualMesh/VirtualMeshContainer.cs new file mode 100644 index 00000000..2a68af9d --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/VirtualMesh/VirtualMeshContainer.cs @@ -0,0 +1,60 @@ +// Magica Cloth 2. +// Copyright (c) 2024 MagicaSoft. +// https://magicasoft.jp +using System; +using UnityEngine; + +namespace MagicaCloth2 +{ + /// + /// VirtualMeshの共有部分と固有部分を1つにまとめた情報 + /// + public class VirtualMeshContainer : IDisposable + { + public VirtualMesh shareVirtualMesh; + public VirtualMesh.UniqueSerializationData uniqueData; + + public VirtualMeshContainer() + { + } + + public VirtualMeshContainer(VirtualMesh vmesh) + { + shareVirtualMesh = vmesh; + uniqueData = null; + } + + public void Dispose() + { + shareVirtualMesh?.Dispose(); + } + + //========================================================================================= + public bool hasUniqueData => uniqueData != null; + + //========================================================================================= + public int GetTransformCount() + { + if (hasUniqueData) + return uniqueData.transformData.transformArray.Length; + else + return shareVirtualMesh.TransformCount; + } + + public Transform GetTransformFromIndex(int index) + { + if (hasUniqueData) + return uniqueData.transformData.transformArray[index]; + else + return shareVirtualMesh.transformData.GetTransformFromIndex(index); + } + + public Transform GetCenterTransform() + { + if (hasUniqueData) + return uniqueData.transformData.transformArray[shareVirtualMesh.centerTransformIndex]; + else + return shareVirtualMesh.GetCenterTransform(); + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/VirtualMesh/VirtualMeshContainer.cs.meta b/Assets/MagicaCloth2/Scripts/Core/VirtualMesh/VirtualMeshContainer.cs.meta new file mode 100644 index 00000000..3a2b1188 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/VirtualMesh/VirtualMeshContainer.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: bac7915dc7b0bda49baed15536766603 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/VirtualMesh/VirtualMeshContainer.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/VirtualMesh/VirtualMeshPrimitive.cs b/Assets/MagicaCloth2/Scripts/Core/VirtualMesh/VirtualMeshPrimitive.cs new file mode 100644 index 00000000..e1eef606 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/VirtualMesh/VirtualMeshPrimitive.cs @@ -0,0 +1,14 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp + +namespace MagicaCloth2 +{ + public enum VirtualMeshPrimitive + { + None = 0, + Point = 1, + Edge = 2, + Triangle = 3, + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/VirtualMesh/VirtualMeshPrimitive.cs.meta b/Assets/MagicaCloth2/Scripts/Core/VirtualMesh/VirtualMeshPrimitive.cs.meta new file mode 100644 index 00000000..a10afc0a --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/VirtualMesh/VirtualMeshPrimitive.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 28eb005f383ff844d9d7b674cefb6113 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/VirtualMesh/VirtualMeshPrimitive.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/VirtualMesh/VirtualMeshRaycastHit.cs b/Assets/MagicaCloth2/Scripts/Core/VirtualMesh/VirtualMeshRaycastHit.cs new file mode 100644 index 00000000..6be2da7c --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/VirtualMesh/VirtualMeshRaycastHit.cs @@ -0,0 +1,35 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using System; +using Unity.Mathematics; + +namespace MagicaCloth2 +{ + public struct VirtualMeshRaycastHit : IComparable, IValid + { + public VirtualMeshPrimitive type; + public int index; + public float3 position; + public float3 normal; + public float distance; + + public int CompareTo(VirtualMeshRaycastHit other) + { + if (distance != other.distance) + return distance < other.distance ? -1 : 1; + else + return 0; + } + + public bool IsValid() + { + return type != VirtualMeshPrimitive.None; + } + + public override string ToString() + { + return $"{type} [{index}] pos:{position}, dist:{distance}, nor:{normal}"; + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/VirtualMesh/VirtualMeshRaycastHit.cs.meta b/Assets/MagicaCloth2/Scripts/Core/VirtualMesh/VirtualMeshRaycastHit.cs.meta new file mode 100644 index 00000000..8578f651 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/VirtualMesh/VirtualMeshRaycastHit.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: b1630263613d8714dbfb6f464c6e27eb +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/VirtualMesh/VirtualMeshRaycastHit.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Core/VirtualMesh/VirtualMeshTransform.cs b/Assets/MagicaCloth2/Scripts/Core/VirtualMesh/VirtualMeshTransform.cs new file mode 100644 index 00000000..aeac9d5f --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/VirtualMesh/VirtualMeshTransform.cs @@ -0,0 +1,168 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using System.Runtime.CompilerServices; +using Unity.Collections; +using Unity.Mathematics; +using UnityEngine; + +namespace MagicaCloth2 +{ + /// + /// VirtualMeshで利用されるTransform情報 + /// スレッドからの利用を考えてデータをTransformから分離しておく + /// + public struct VirtualMeshTransform + { + /// + /// 識別名(最大29文字) + /// + public FixedString32Bytes name; + + public int index; + //public float3 localPosition; + //public quaternion localRotation; + //public float3 localScale; + public float4x4 localToWorldMatrix; + public float4x4 worldToLocalMatrix; + + public int parentIndex; + + //========================================================================================= + public VirtualMeshTransform(Transform t) + { + Debug.Assert(t); + name = t.name.Substring(0, math.min(t.name.Length, 29)); + index = -1; + //localPosition = t.localPosition; + //localRotation = t.localRotation; + //localScale = t.localScale; + localToWorldMatrix = t.localToWorldMatrix; + worldToLocalMatrix = t.worldToLocalMatrix; + parentIndex = -1; + } + + public VirtualMeshTransform(Transform t, int index) : this(t) + { + this.index = index; + } + + public VirtualMeshTransform Clone() + { + var mt = new VirtualMeshTransform() + { + name = name, + index = index, + localToWorldMatrix = localToWorldMatrix, + worldToLocalMatrix = worldToLocalMatrix, + parentIndex = parentIndex, + }; + + return mt; + } + + /// + /// ワールド座標原点 + /// + public static VirtualMeshTransform Origin + { + get + { + var mt = new VirtualMeshTransform(); + mt.name = "VirtualMesh Origin"; + //mt.localScale = 1; + mt.localToWorldMatrix = float4x4.identity; + mt.worldToLocalMatrix = float4x4.identity; + mt.parentIndex = -1; + return mt; + } + } + + /// + /// ハッシュは名前から生成する + /// + /// + public override int GetHashCode() + { + return name.GetHashCode(); + } + + public void Update(Transform t) + { + //localPosition = t.localPosition; + //localRotation = t.localRotation; + //localScale = t.localScale; + localToWorldMatrix = t.localToWorldMatrix; + worldToLocalMatrix = t.worldToLocalMatrix; + } + + //========================================================================================= + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public float3 TransformPoint(float3 pos) + { + return math.transform(localToWorldMatrix, pos); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public float3 TransformVector(float3 vec) + { + return math.mul(localToWorldMatrix, new float4(vec, 0)).xyz; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public float3 TransformDirection(float3 dir) + { + float len = math.length(dir); + if (len > 0.0f) + return math.normalize(TransformVector(dir)) * len; + else + return dir; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public float3 InverseTransformPoint(float3 pos) + { + return math.transform(worldToLocalMatrix, pos); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public float3 InverseTransformVector(float3 vec) + { + return math.mul(worldToLocalMatrix, new float4(vec, 0)).xyz; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public float3 InverseTransformDirection(float3 dir) + { + float len = math.length(dir); + if (len > 0.0f) + return math.normalize(InverseTransformVector(dir)) * len; + else + return dir; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public quaternion InverseTransformRotation(quaternion rot) + { + return math.mul(new quaternion(worldToLocalMatrix), rot); + } + + /// + /// このTransformのローカル座標をtoのローカル座標に変換するTransformを返す + /// + /// + /// + public VirtualMeshTransform Transform(in VirtualMeshTransform to) + { + var mt = new VirtualMeshTransform() + { + name = "__(temporary)__", + index = -1, + localToWorldMatrix = math.mul(to.worldToLocalMatrix, localToWorldMatrix), + worldToLocalMatrix = math.mul(worldToLocalMatrix, to.localToWorldMatrix), + parentIndex = -1, + }; + return mt; + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Core/VirtualMesh/VirtualMeshTransform.cs.meta b/Assets/MagicaCloth2/Scripts/Core/VirtualMesh/VirtualMeshTransform.cs.meta new file mode 100644 index 00000000..3e031546 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Core/VirtualMesh/VirtualMeshTransform.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: f1ab03195c884cd40a4bf12a2c22217c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Core/VirtualMesh/VirtualMeshTransform.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Editor.meta b/Assets/MagicaCloth2/Scripts/Editor.meta new file mode 100644 index 00000000..b16b1741 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Editor.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 56cddc7b23443aa4e82bc4a6fa59ccff +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/MagicaCloth2/Scripts/Editor/Cloth.meta b/Assets/MagicaCloth2/Scripts/Editor/Cloth.meta new file mode 100644 index 00000000..b9ba619c --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Editor/Cloth.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 497187e4db74fa043afca4179151e148 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/MagicaCloth2/Scripts/Editor/Cloth/ClothAssetPostprocessor.cs b/Assets/MagicaCloth2/Scripts/Editor/Cloth/ClothAssetPostprocessor.cs new file mode 100644 index 00000000..698034cd --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Editor/Cloth/ClothAssetPostprocessor.cs @@ -0,0 +1,41 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using UnityEditor; + +namespace MagicaCloth2 +{ + /// + /// インポートアセットの判定 + /// + public class ClothAssetPostprocessor : AssetPostprocessor + { + /// + /// データベースにアセットが追加/削除/移動/更新された場合にその完了後に一度呼び出される + /// + /// + /// + /// + /// + protected static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths) + { +#if false + foreach (string str in importedAssets) + { + Debug.Log("@Reimported Asset: " + str); + } + foreach (string str in deletedAssets) + { + Debug.Log("@Deleted Asset: " + str); + } + + for (int i = 0; i < movedAssets.Length; i++) + { + Debug.Log("@Moved Asset: " + movedAssets[i] + " from: " + movedFromAssetPaths[i]); + } +#endif + // アセットがインポートされたことによる編集用メッシュの更新判定 + ClothEditorManager.UpdateFromAssetImport(importedAssets); + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Editor/Cloth/ClothAssetPostprocessor.cs.meta b/Assets/MagicaCloth2/Scripts/Editor/Cloth/ClothAssetPostprocessor.cs.meta new file mode 100644 index 00000000..deeafdc8 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Editor/Cloth/ClothAssetPostprocessor.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 62851d07720bcd84f89c596c9a32c8a6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Editor/Cloth/ClothAssetPostprocessor.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Editor/Cloth/ClothEditorManager.cs b/Assets/MagicaCloth2/Scripts/Editor/Cloth/ClothEditorManager.cs new file mode 100644 index 00000000..0ae6a1bf --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Editor/Cloth/ClothEditorManager.cs @@ -0,0 +1,1110 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using Unity.Mathematics; +using UnityEditor; +using UnityEditor.Callbacks; +using UnityEditor.Compilation; +using UnityEditor.PackageManager; +using UnityEditor.SceneManagement; +using UnityEngine; + +namespace MagicaCloth2 +{ + /// + /// エディタ編集時のコンポーネント管理 + /// + [InitializeOnLoad] + public class ClothEditorManager + { + /// + /// コンポーネント情報 + /// + class ClothInfo + { + public ResultCode result = ResultCode.Empty; + public bool building; + public GizmoType gizmoType; + public ClothBehaviour component; + public int componentHash; + public VirtualMeshContainer editMeshContainer; + public int nextBuildHash; + public int importCount; + public ClothInitSerializeData editInitSerializeData; + } + + static Dictionary editClothDict = new Dictionary(); + + static List destroyList = new List(); + static List drawList = new List(); + static CancellationTokenSource cancelToken = new CancellationTokenSource(); + + static bool isValid = false; + + static internal Action OnEditMeshBuildComplete; + + //========================================================================================= + static ClothEditorManager() + { + Develop.DebugLog($"ClothEditorManager Initialize!"); + + Dispose(); + + // スクリプトコンパイルコールバック + CompilationPipeline.compilationStarted -= OnStartCompile; + CompilationPipeline.compilationStarted += OnStartCompile; + + // シーンビューにGUIを描画するためのコールバック + SceneView.duringSceneGui -= OnSceneGUI; + SceneView.duringSceneGui += OnSceneGUI; + + // プレハブステージ + PrefabStage.prefabStageClosing -= OnPrefabStageClosing; + PrefabStage.prefabStageClosing += OnPrefabStageClosing; + + // Undo/Redo + Undo.undoRedoPerformed -= OnUndoRedoPerformed; + Undo.undoRedoPerformed += OnUndoRedoPerformed; + + isValid = true; + } + + /// + /// エディタの実行状態が変更された場合に呼び出される + /// + [InitializeOnLoadMethod] + static void PlayModeStateChange() + { + EditorApplication.playModeStateChanged += (mode) => + { + Develop.DebugLog($"PlayModeStateChanged:{mode}"); + + if (mode == UnityEditor.PlayModeStateChange.ExitingEditMode || mode == UnityEditor.PlayModeStateChange.ExitingPlayMode) + { + //Develop.DebugLog($"PlayModeStateChange. Exit Editor mode!"); + Dispose(); + isValid = false; + } + if (mode == UnityEditor.PlayModeStateChange.EnteredEditMode || mode == UnityEditor.PlayModeStateChange.EnteredPlayMode) + { + //Develop.DebugLog($"PlayModeStateChange. Enter Editor mode!"); + isValid = true; + } + }; + } + + /// + /// スクリプトコンパイル開始 + /// + /// + static void OnStartCompile(object obj) + { + Develop.DebugLog($"start compile."); + Dispose(); + isValid = false; + } + + /// + /// ビルド完了時 + /// + /// + /// + [PostProcessBuildAttribute(1)] + static void OnPostprocessBuild(BuildTarget target, string pathToBuiltProject) + { + Develop.DebugLog($"build compile."); + isValid = true; + } + + /// + /// プレハブステージが閉じる時 + /// + /// + static void OnPrefabStageClosing(PrefabStage pstage) + { + ForceUpdateAllComponents(); + } + + /// + /// Undo/Redo実行時 + /// + static void OnUndoRedoPerformed() + { + ForceUpdateAllComponents(); + } + + //========================================================================================= + static bool IsActive(GizmoType gizmoType) + { + return gizmoType.HasFlag(GizmoType.Active); + } + + static bool IsActiveOrSelected(GizmoType gizmoType) + { + return IsActive(gizmoType) || gizmoType.HasFlag(GizmoType.Selected); + } + + static bool IsSelectionHierarchy(GizmoType gizmoType) + { + return IsActiveOrSelected(gizmoType) || gizmoType.HasFlag(GizmoType.InSelectionHierarchy); + } + + /// + /// MagidaClothコンポーネントの登録および編集メッシュの作成/更新 + /// + /// + public static void RegisterComponent(ClothBehaviour component, GizmoType gizmoType, bool forceUpdate = false) + { + //Develop.DebugLog($"RegisterComponent:{component.name}, isValid:{isValid}"); + if (isValid == false) + return; + if (component == null) + return; + + // ペイント中は無効 + if (ClothPainter.IsPainting()) + return; + + MagicaObjectId id = component.GetMagicaId(); + MagicaCloth cloth = component as MagicaCloth; + + //if (cloth) + // Develop.DebugLog($"Register Cloth:{component.name}, gizmoType:{gizmoType}"); + +#if true + // Unity2023のみ何故かGizmoTypeの挙動が異なり、実際には選択されてなくても親が選択中だとSelectedフラグが立ってしまう。 + // そのため、Selectedフラグに関してはここで手動で判定することにする。 +#if UNITY_6000_3_OR_NEWER + if (Selection.Contains(component.gameObject.GetEntityId())) +#else + if (Selection.Contains(component.gameObject.GetInstanceID())) +#endif + gizmoType |= GizmoType.Selected; + else + gizmoType &= ~GizmoType.Selected; +#endif + + // ギズモ表示判定 + // 常に表示 + if (cloth && cloth.GizmoSerializeData.IsAlways()) + gizmoType = GizmoType.Active; + + // クロス指定のコライダー表示 + if (cloth && cloth.GizmoSerializeData.clothDebugSettings.enable && cloth.GizmoSerializeData.clothDebugSettings.collider && IsSelectionHierarchy(gizmoType)) + { + foreach (var col in cloth.SerializeData.colliderCollisionConstraint.colliderList) + { + RegisterComponent(col, gizmoType); + } + } + + lock (editClothDict) + { + if (editClothDict.ContainsKey(id) == false) + { + //Debug.Log($"登録:{component.name}"); + var info = new ClothInfo(); + info.building = false; + info.result = ResultCode.Empty; + info.component = component; + info.editMeshContainer = null; + info.gizmoType = gizmoType; + info.componentHash = 0; + info.nextBuildHash = 0; + info.importCount = 1; + editClothDict.Add(id, info); + } + else + { + editClothDict[id].gizmoType |= gizmoType; + } + } + + // EditMesh作成(MagicaClothコンポーネントのみ) + if (cloth && EditorApplication.isPlaying == false) + { + int hash = component.GetMagicaHashCode(); + //Debug.Log($"Hash:{hash}"); + + lock (editClothDict) + { + if (editClothDict.ContainsKey(id)) + { + var info = editClothDict[id]; + + // ハッシュにはインポート回数を乗算する + hash *= (info.importCount + 1); + + // ハッシュが異なる場合のみ再構築/もしくは強制更新 + if (info.componentHash != hash || forceUpdate) + { + // 現在作成中ならば次の作成候補として登録 + if (info.building) + { + info.nextBuildHash = hash; + } + // そうでなければ作成を開始する + else + { + info.componentHash = hash; + info.nextBuildHash = 0; + + if (cloth.isActiveAndEnabled || forceUpdate) + { + // スレッドで作成 + info.building = true; + var _ = CreateOrUpdateEditMesh(id, cloth, cancelToken.Token); + } + } + } + } + } + } + } + + public static VirtualMeshContainer GetEditMeshContainer(ClothBehaviour comp) + { + if (isValid == false) + return null; + if (comp == null) + return null; + MagicaObjectId id = comp.GetMagicaId(); + VirtualMeshContainer cmesh = null; + lock (editClothDict) + { + cmesh = editClothDict.ContainsKey(id) ? editClothDict[id].editMeshContainer : null; + } + return cmesh; + } + + /// + /// 現在のコンポーネント状態を返す + /// + /// + /// + public static ResultCode GetResultCode(ClothBehaviour comp) + { + if (comp == null) + return ResultCode.Empty; + MagicaObjectId id = comp.GetMagicaId(); + lock (editClothDict) + { + if (editClothDict.ContainsKey(id)) + return editClothDict[id].result; + else + return ResultCode.Empty; + } + } + + static void Dispose() + { + cancelToken.Cancel(); + cancelToken.Dispose(); + cancelToken = new CancellationTokenSource(); + + destroyList.Clear(); + drawList.Clear(); + lock (editClothDict) + { + foreach (var info in editClothDict.Values) + { + info?.editMeshContainer?.Dispose(); + } + editClothDict.Clear(); + } + } + + /// + /// コンポーネントの削除チェック + /// + static void DestroyCheck() + { + lock (editClothDict) + { + destroyList.Clear(); + foreach (var kv in editClothDict) + { + if (kv.Value.component == null) + { + destroyList.Add(kv.Key); + } + } + foreach (var id in destroyList) + { + //Debug.Log($"削除"); + editClothDict[id].editMeshContainer?.Dispose(); + editClothDict.Remove(id); + } + destroyList.Clear(); + } + } + + /// + /// アセット更新にともなう編集用メッシュの更新 + /// + /// + public static void UpdateFromAssetImport(string[] importedAssets) + { + if (importedAssets == null || importedAssets.Length == 0) + return; + + var importedAssetSet = new HashSet(importedAssets); + + // クロスコンポーネントがインポートされたアセットを参照している場合は再構築フラグを立てる + var updateDict = new Dictionary(); + lock (editClothDict) + { + foreach (var cinfo in editClothDict.Values) + { + var cloth = cinfo.component as MagicaCloth; + if (cloth) + { + bool update = false; + var sdata = cloth.SerializeData; + + // source renderes + if (sdata.clothType == ClothProcess.ClothType.MeshCloth) + { + foreach (var ren in sdata.sourceRenderers) + { + if (ren && importedAssetSet.Contains(AssetDatabase.GetAssetPath(ren))) + update = true; + } + } + + // paint maps + if (sdata.clothType == ClothProcess.ClothType.MeshCloth && sdata.paintMode != ClothSerializeData.PaintMode.Manual) + { + foreach (var map in sdata.paintMaps) + { + if (map && importedAssetSet.Contains(AssetDatabase.GetAssetPath(map))) + update = true; + } + } + + if (update) + { + // 再構築フラグ + // インポートカウントを増加させることでハッシュ値を変化させる + cinfo.importCount++; + updateDict.Add(cinfo.component, cinfo.gizmoType); + } + } + } + } + + // 再構築開始 + foreach (var kv in updateDict) + { + RegisterComponent(kv.Key, kv.Value); + } + } + + /// + /// 強制的にすべてのコンポーネントの更新フラグを立てる + /// + static void ForceUpdateAllComponents() + { + lock (editClothDict) + { + foreach (var cinfo in editClothDict.Values) + { + var cloth = cinfo.component as MagicaCloth; + if (cloth) + { + // 再構築フラグ + // インポートカウントを増加させることでハッシュ値を変化させる + // 次のギズモ表示もしくはペイント時に再構築される + cinfo.importCount++; + } + } + } + } + + //========================================================================================= + /// + /// 編集用メッシュの作成/更新 + /// + /// + /// + /// + /// + /// + static async Task CreateOrUpdateEditMesh(MagicaObjectId id, MagicaCloth cloth, CancellationToken ct) + { + // ■メインスレッド + Develop.DebugLog($"Create and update edit meshes: {cloth.name}"); + var sdata = cloth.SerializeData; + var sdata2 = cloth.GetSerializeData2(); + var setupList = new List(); + VirtualMeshContainer editMeshContainer = null; + ClothInitSerializeData editInitSerializeData = new ClothInitSerializeData(); + ResultCode result = new ResultCode(); + + try + { + // ■メインスレッド + if (cloth == null || isValid == false) + { + result.SetError(Define.Result.CreateCloth_InvalidCloth); + throw new MagicaClothProcessingException(); + } + var statusResult = cloth.Process.GenerateStatusCheck(); + result.Merge(statusResult); + if (statusResult.IsError()) + { + throw new MagicaClothProcessingException(); + } + + // メッシュを構築するための最低限のデータが揃っているか確認 + if (sdata.IsValid() == false) + { + result.SetResult(sdata.VerificationResult); + throw new MagicaClothProcessingException(); + } + + // セットアップデータの作成 + if (sdata.clothType == ClothProcess.ClothType.MeshCloth) + { + foreach (var ren in sdata.sourceRenderers) + { + if (ren) + { + var setup = new RenderSetupData(null, ren); + result.Merge(setup.result); + if (setup.IsFaild()) + { + setup.Dispose(); + throw new MagicaClothProcessingException(); + } + setupList.Add(setup); + } + else + { + result.SetError(Define.Result.CreateCloth_NoRenderer); + throw new MagicaClothProcessingException(); + } + } + } + else if (sdata.clothType == ClothProcess.ClothType.BoneCloth) + { + var setup = new RenderSetupData(null, RenderSetupData.SetupType.BoneCloth, cloth.ClothTransform, sdata.rootBones, null, sdata.connectionMode, cloth.name); + setupList.Add(setup); + } + else if (sdata.clothType == ClothProcess.ClothType.BoneSpring) + { + // BoneSpringではLine接続のみ + var setup = new RenderSetupData(null, RenderSetupData.SetupType.BoneSpring, cloth.ClothTransform, sdata.rootBones, sdata.colliderCollisionConstraint.collisionBones, RenderSetupData.BoneConnectionMode.Line, cloth.name); + setupList.Add(setup); + } + + if (setupList.Count == 0) + { + result.SetError(Define.Result.CreateCloth_InvalidSetupList); + throw new MagicaClothProcessingException(); + } + + // クロスコンポーネントトランスフォーム情報 + var clothTransformRecord = new TransformRecord(cloth.ClothTransform, read: true); + + // 法線調整用トランスフォーム + var normalAdjustmentTransformRecored = new TransformRecord( + sdata.normalAlignmentSetting.adjustmentTransform ? + sdata.normalAlignmentSetting.adjustmentTransform : + cloth.ClothTransform, read: true + ); + + // 初期化情報収集 + editInitSerializeData.Serialize( + sdata, + clothTransformRecord, + normalAdjustmentTransformRecored, + setupList + ); + + // ペイントマップデータの作成(これはメインスレッドでのみ作成可能) + var paintMapDataList = new List(); + bool usePaintMap = false; + if (sdata.clothType == ClothProcess.ClothType.MeshCloth && sdata.paintMode != ClothSerializeData.PaintMode.Manual) + { + var ret = cloth.Process.GeneratePaintMapDataList(paintMapDataList); + if (ret.IsError()) + { + result.Merge(ret); + throw new MagicaClothProcessingException(); + } + if (paintMapDataList.Count != setupList.Count) + { + result.SetError(Define.Result.CreateCloth_PaintMapCountMismatch); + throw new MagicaClothProcessingException(); + } + usePaintMap = true; + } + + // エディットメッシュ作成 + // メッシュはセンター空間で作成される + ct.ThrowIfCancellationRequested(); + var editMesh = new VirtualMesh("EditMesh"); + editMeshContainer = new VirtualMeshContainer(editMesh); + if (sdata.clothType == ClothProcess.ClothType.MeshCloth) + { + // MeshClothではクロストランスフォームを追加しておく + editMesh.SetTransform(cloth.ClothTransform, null, MagicaObjectId.Invalid, MagicaObjectId.Invalid); + } + editMesh.result.SetProcess(); + + // セレクションデータ + // ペイントマップ指定の場合は空で初期化 + SelectionData selectionData = usePaintMap ? new SelectionData() : sdata2.selectionData.Clone(); + + // ■スレッド + await Task.Run(() => + { + try + { + // MeshCloth/BoneClothで処理が一部異なる + ct.ThrowIfCancellationRequested(); + if (sdata.clothType == ClothProcess.ClothType.MeshCloth) + { + for (int i = 0; i < setupList.Count; i++) + { + var setup = setupList[i]; + + // レンダーメッシュ作成 + using var renderMesh = new VirtualMesh($"[{setup.name}]"); + renderMesh.result.SetProcess(); + + // インポート + renderMesh.ImportFrom(setup, sdata.GetUvChannel()); + //Debug.Log($"(IMPORT) {renderMesh}"); + if (renderMesh.IsError) + continue; + renderMesh.result.SetSuccess(); + + // MeshClothでペイントテクスチャ指定の場合はセレクションデータを生成する + if (usePaintMap) + { + var ret = cloth.Process.GenerateSelectionDataFromPaintMap(clothTransformRecord, renderMesh, paintMapDataList[i], out SelectionData renderSelectionData); + if (ret.IsError()) + { + result.Merge(ret); + throw new MagicaClothProcessingException(); + } + + // セレクションデータ結合 + selectionData.Merge(renderSelectionData); + } + + // マージ + editMesh.AddMesh(renderMesh); + } + //Debug.Log($"(MERGE) {editMesh}"); + + // リダクション + if (editMesh.VertexCount > 1 && sdata.reductionSetting.IsEnabled) + { + editMesh.Reduction(sdata.reductionSetting, ct); + if (editMesh.IsError) + { + result.Merge(editMesh.result); + throw new MagicaClothProcessingException(); + } + + //Debug.Log($"(REDUCTION) {editMesh}"); + } + } + else if (sdata.clothType == ClothProcess.ClothType.BoneCloth || sdata.clothType == ClothProcess.ClothType.BoneSpring) + { + // import + editMesh.ImportFrom(setupList[0], 0); + if (editMesh.IsError) + { + result.Merge(editMesh.result); + throw new MagicaClothProcessingException(); + } + //Debug.Log($"(IMPORT) {editMesh}"); + } + + // 元の頂点から結合頂点へのインデックスを初期化 + if (editMesh.joinIndices.IsCreated == false) + { + editMesh.joinIndices = new Unity.Collections.NativeArray(editMesh.VertexCount, Unity.Collections.Allocator.Persistent); + JobUtility.SerialNumberRun(editMesh.joinIndices, editMesh.VertexCount); // 連番をつける + } + + // 最適化 + ct.ThrowIfCancellationRequested(); + editMesh.Optimization(); + if (editMesh.IsError) + { + result.Merge(editMesh.result); + throw new MagicaClothProcessingException(); + } + //Debug.Log($"(OPTIMIZE) {editMesh}"); + } + catch (OperationCanceledException) + { + throw; + } + catch (MagicaClothProcessingException) + { + throw; + } + catch (Exception exception) + { + Debug.LogException(exception); + result.SetError(Define.Result.CreateCloth_Exception); + throw; + } + }, ct); + + // ■メインスレッド + // セレクションデータの作成 + // まだセレクションデータが未編集の場合は作り直す + ct.ThrowIfCancellationRequested(); + if (cloth == null || isValid == false) + { + result.SetError(Define.Result.CreateCloth_InvalidCloth); + throw new MagicaClothProcessingException(); + } + if (usePaintMap == false) + { + if (sdata2.selectionData == null || sdata2.selectionData.IsValid() == false || sdata2.selectionData.userEdit == false) + { + // 新規作成 + selectionData = CreateAutoSelectionData(cloth, sdata, editMesh); + + // 格納 + sdata2.selectionData = selectionData; + } + } + + // ■スレッド + await Task.Run(() => + { + try + { + // セレクションデータから頂点属性を付与する + ct.ThrowIfCancellationRequested(); + if (selectionData.IsValid()) + { + editMesh.ApplySelectionAttribute(selectionData); + } + + // ProxyMeshへの変換(属性決定後に実行) + ct.ThrowIfCancellationRequested(); + editMesh.ConvertProxyMesh(cloth.SerializeData, null, null, normalAdjustmentTransformRecored); + if (editMesh.IsError) + { + result.Merge(editMesh.result); + throw new MagicaClothProcessingException(); + } + //Debug.Log($"(PROXY) {editMesh}"); + +#if false + // pitch/yaw個別制限はv1.0では実装しないので一旦停止 + // 角度制限計算用回転を作成 + ct.ThrowIfCancellationRequested(); + editMesh.CreateAngleCalcLocalRotation(sdata.normalCalculation, sdata.normalCalculationCenter); + if (editMesh.IsError) + throw new InvalidOperationException(); +#endif + + // 完了 + ct.ThrowIfCancellationRequested(); + editMesh.result.SetSuccess(); + } + catch (OperationCanceledException) + { + throw; + } + catch (MagicaClothProcessingException) + { + throw; + } + catch (Exception exception) + { + Debug.LogException(exception); + result.SetError(Define.Result.CreateCloth_Exception); + throw; + } + }, ct); + + // ■メインスレッド + ct.ThrowIfCancellationRequested(); + if (cloth == null || isValid == false) + { + // キャンセル扱いにする + throw new OperationCanceledException(); + } + + // 成功 + Develop.DebugLog($"(FINAL PROXY) {editMesh}"); + result.SetSuccess(); + } + catch (MagicaClothProcessingException) + { + if (result.IsNone()) result.SetError(Define.Result.CreateCloth_UnknownError); + result.DebugLog(); + } + catch (OperationCanceledException) + { + Develop.DebugLog($"Editor mesh build canceled!"); + result.SetCancel(); + } + catch (Exception exception) + { + Debug.LogException(exception); + result.SetError(Define.Result.CreateCloth_Exception); + } + finally + { + // 状態変更 + if (isValid) + { + lock (editClothDict) + { + if (editClothDict.ContainsKey(id)) + { + var info = editClothDict[id]; + info.building = false; + info.result = result; + info.editMeshContainer?.Dispose(); + if (result.IsSuccess()) + { + info.editMeshContainer = editMeshContainer; + editMeshContainer = null; + info.editInitSerializeData = editInitSerializeData; + Develop.DebugLog($"Registration Complete : {cloth.name}"); + + // 初期化データの保存 + // ここではローカルハッシュのみの比較とする + ApplyInitData(cloth, global: false); + } + else + { + info.editMeshContainer = null; + info.editInitSerializeData = null; + } + } + } + } + + // dispose + foreach (var setup in setupList) + { + setup?.Dispose(); + } + editMeshContainer?.Dispose(); + + //span.DebugLog(); + + // 引き続き再構築の実行判定 + if (isValid) + { + lock (editClothDict) + { + if (editClothDict.ContainsKey(id)) + { + var info = editClothDict[id]; + info.building = false; + + if (info.nextBuildHash != 0 && cloth) + { + if (info.nextBuildHash == info.componentHash) + { + info.nextBuildHash = 0; + } + else + { + info.componentHash = info.nextBuildHash; + info.nextBuildHash = 0; + info.building = true; + info.result.Clear(); + + var _ = CreateOrUpdateEditMesh(id, cloth, ct); + } + } + } + } + } + + SceneView.RepaintAll(); + + // ビルド完了通知 + OnEditMeshBuildComplete?.Invoke(); + } + } + + /// + /// 初期化データをシリアライズ化する + /// + /// + /// + public static void ApplyInitData(MagicaCloth cloth, bool global) + { + if (cloth == null) + return; + MagicaObjectId id = cloth.GetMagicaId(); + if (editClothDict.ContainsKey(id) == false) + return; + + var info = editClothDict[id]; + if (info.editInitSerializeData == null) + return; + + // ハッシュ比較 + var sdata2 = cloth.GetSerializeData2(); + int oldLocalHash = sdata2.initData?.localHash ?? 0; + bool change = oldLocalHash != info.editInitSerializeData.localHash; + if (global && change == false) + { + int oldGlobalHash = sdata2.initData?.globalHash ?? 0; + change = oldGlobalHash != info.editInitSerializeData.globalHash; + } + if (change == false) + return; // 変更なし + + // 初期化データ保存 + // Undoの対象にはしない + sdata2.initData = info.editInitSerializeData; + EditorUtility.SetDirty(cloth); + Develop.DebugLog($"* Apply initData. [{cloth.name}]"); + } + + /// + /// セレクションデータをシリアライズ化する + /// + /// + /// + public static void ApplySelectionData(MagicaCloth cloth, SelectionData selectionData) + { + if (cloth == null || selectionData == null || selectionData.IsValid() == false) + return; + + if (cloth.GetSerializeData2().selectionData != null && cloth.GetSerializeData2().selectionData.Compare(selectionData)) + return; // 変更なし + + //Debug.Log($"セレクションデータ格納!"); + Undo.RecordObject(cloth, "Paint"); + + // 最終的に[SerializeReference]から[SerializeField]に変更(2022/12/18) + cloth.GetSerializeData2().selectionData = selectionData; + + EditorUtility.SetDirty(cloth); + } + + + /// + /// 編集メッシュから自動でセレクションデータを生成する(メインスレッドのみ) + /// + /// + /// + /// + /// + public static SelectionData CreateAutoSelectionData(MagicaCloth cloth, ClothSerializeData sdata, VirtualMesh emesh) + { + var selectionData = new SelectionData(emesh, float4x4.identity); + int cnt = selectionData.Count; + if (cnt == 0) + return selectionData; + + // BoneClothはRootをFixedに定義する、それ以外はMove + if (sdata.clothType == ClothProcess.ClothType.BoneCloth || sdata.clothType == ClothProcess.ClothType.BoneSpring) + { + selectionData.Fill(VertexAttribute.Move); + + // BoneClothではセットアップデータのrootのみ固定に設定する + // BoneSpringではLine接続のみとなる + var connectionMode = sdata.clothType == ClothProcess.ClothType.BoneSpring ? RenderSetupData.BoneConnectionMode.Line : sdata.connectionMode; + var setupType = sdata.clothType == ClothProcess.ClothType.BoneSpring ? RenderSetupData.SetupType.BoneSpring : RenderSetupData.SetupType.BoneCloth; + using var setup = new RenderSetupData(null, setupType, cloth.ClothTransform, sdata.rootBones, null, connectionMode, cloth.name); + foreach (MagicaObjectId id in setup.rootTransformIdList) + { + int rootIndex = setup.GetTransformIndexFromId(id); + selectionData.attributes[rootIndex] = VertexAttribute.Fixed; + } + } + // MeshClothではすべて固定で定義する + else + { + selectionData.Fill(VertexAttribute.Invalid); + } + + return selectionData; + } + + //========================================================================================= + /// + /// シーンビューへのギズモ描画 + /// + /// + static void OnSceneGUI(SceneView sceneView) + { + if (isValid == false) + return; + + // コンポーネント削除チェック + DestroyCheck(); + + // コンポーネントギズモ描画 + if (Event.current.type == EventType.Repaint) + { + //Develop.DebugLog($"Repaint. F:{Time.frameCount}"); + + drawList.Clear(); + bool isPainting = ClothPainter.IsPainting(); + bool isPlaying = EditorApplication.isPlaying; + sceneView.camera.transform.GetPositionAndRotation(out var camPos, out Quaternion camRot); + + lock (editClothDict) + { + foreach (var info in editClothDict.Values) + { + if (info == null || info.component == null) + continue; + + if (info.component.isActiveAndEnabled == false) + continue; + + if (info.component.IsGizmoVisible == false) + continue; + + // ペイント中は表示しない + if (isPainting) + continue; + + // 選択状態 + bool selected = IsActiveOrSelected(info.gizmoType); + float dist = Vector3.Distance(camPos, info.component.transform.position); + + // Collider + if (info.component is ColliderComponent) + { + // Colliderは親選択時にも表示する + if (IsSelectionHierarchy(info.gizmoType) == false) + continue; + if (selected == false && dist >= 20.0f) + continue; + + GizmoUtility.DrawCollider(info.component as ColliderComponent, camRot, selected); + } + // MagicaCloth + else if (info.component is MagicaCloth) + { + // Clothはアクティブもしくはマルチ選択時のみ表示 + if (IsActiveOrSelected(info.gizmoType) == false) + continue; + + var cloth = info.component as MagicaCloth; + + // Cloth + if (cloth.GizmoSerializeData.clothDebugSettings.enable) + { + if (isPlaying) + ClothEditorUtility.DrawClothRuntime(cloth.Process, cloth.GizmoSerializeData.clothDebugSettings, selected); + else + ClothEditorUtility.DrawClothEditor(info.editMeshContainer, cloth.GizmoSerializeData.clothDebugSettings, cloth.SerializeData, selected, false, false); + } + +#if MC2_DEBUG + // Proxy Mesh + if (cloth.GizmoSerializeData.proxyDebugSettings.enable) + { + if (isPlaying) + VirtualMeshEditorUtility.DrawRuntimeGizmos(cloth.Process, false, cloth.Process.ProxyMeshContainer, cloth.GizmoSerializeData.proxyDebugSettings, selected, true); + else + VirtualMeshEditorUtility.DrawGizmos(info.editMeshContainer, cloth.GizmoSerializeData.proxyDebugSettings, selected, true); + } + + // Mapping Mesh + if (cloth.GizmoSerializeData.mappingDebugSettings.enable) + { + if (isPlaying) + { + var renderMeshInfo = cloth.Process.GetRenderMeshInfo(cloth.GizmoSerializeData.debugMappingIndex); + if (renderMeshInfo != null && renderMeshInfo.renderMeshContainer != null) + VirtualMeshEditorUtility.DrawRuntimeGizmos(cloth.Process, true, renderMeshInfo.renderMeshContainer, cloth.GizmoSerializeData.mappingDebugSettings, selected, true); + } + } +#endif // MC2_DEBUG + } + // WindZone + else if (info.component is MagicaWindZone) + { + GizmoUtility.DrawWindZone(info.component as MagicaWindZone, camRot, selected); + } + } + + // 描画フラグoff + foreach (var info in editClothDict.Values) + { + if (info != null) + { + info.gizmoType = 0; + if (info.component) + info.component.IsGizmoVisible = false; + } + } + } + } + } + + //========================================================================================= + public static async Task InformationLog(StringBuilder allsb) + { + StringBuilder sb = new StringBuilder(); + + sb.AppendLine($"========== System Info =========="); + sb.AppendLine($"Unity Version:{Application.unityVersion}"); + sb.AppendLine($"MagicaCloth Version:{AboutMenu.MagicaClothVersion}"); + sb.AppendLine($"PlayMode:{Application.isPlaying}"); + sb.AppendLine($"CPU Type:{SystemInfo.processorType}"); + sb.AppendLine($"CPU Freq:{SystemInfo.processorFrequency}"); + sb.AppendLine($"CPU Core:{SystemInfo.processorCount}"); + sb.AppendLine($"Device Type:{SystemInfo.deviceType}"); + sb.AppendLine($"OS:{SystemInfo.operatingSystem}"); + sb.AppendLine($"OS Family:{SystemInfo.operatingSystemFamily}"); + + // インストールパッケージ一覧 + sb.AppendLine($"<< Install Packages >>"); + var listRequest = Client.List(true, false); + int timeout = 5000; // 5s + while (listRequest.IsCompleted == false && timeout > 0) + { + await Task.Delay(50); + timeout -= 50; + } + if (listRequest.IsCompleted) + { + if (listRequest.Status == StatusCode.Success) + { + foreach (var package in listRequest.Result) + { + //Debug.Log($"{package.name} : {package.version}"); + sb.AppendLine($"{package.name} : {package.version}"); + } + } + else + { + sb.AppendLine($"Package request error!"); + Debug.LogWarning($"Package request error!"); + } + } + else + { + sb.AppendLine($"Package request timeout!"); + Debug.LogWarning($"Package request timeout!"); + } + sb.AppendLine(); + + Debug.Log(sb.ToString()); + allsb.Append(sb); + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Editor/Cloth/ClothEditorManager.cs.meta b/Assets/MagicaCloth2/Scripts/Editor/Cloth/ClothEditorManager.cs.meta new file mode 100644 index 00000000..a0d4097d --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Editor/Cloth/ClothEditorManager.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 905d98a228d9c6c4eb4d5e240f30378a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Editor/Cloth/ClothEditorManager.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Editor/Cloth/ClothEditorUtility.cs b/Assets/MagicaCloth2/Scripts/Editor/Cloth/ClothEditorUtility.cs new file mode 100644 index 00000000..5ba13da5 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Editor/Cloth/ClothEditorUtility.cs @@ -0,0 +1,1161 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using System.Collections.Generic; +using Unity.Collections; +using Unity.Mathematics; +using UnityEditor; +using UnityEngine; + + +namespace MagicaCloth2 +{ + /// + /// クロスコンポーネントのギズモ表示 + /// + public static class ClothEditorUtility + { + public static readonly Color MovePointColor = new Color(0.8f, 0.8f, 0.8f, 0.8f); + //public static readonly Color MovePointColor = Color.white; + public static readonly Color FixedPointColor = new Color(1.0f, 0.0f, 0.0f, 0.8f); + public static readonly Color InvalidPointColor = new Color(0.0f, 0.0f, 0.0f, 0.8f); + public static readonly Color AngleLimitConeColor = new Color(0.0f, 0.349f, 0.725f, 0.325f); + public static readonly Color AngleLimitWireColor = new Color(0.0f, 0.843f, 1.0f, 0.313f); + public static readonly Color BaseTriangleColor = new Color(204 / 255f, 153 / 255f, 255 / 255f); + public static readonly Color BaseLineColor = new Color(153 / 255f, 204 / 255f, 255 / 255f); + public static readonly Color TriangleColor = new Color(1.0f, 0.0f, 0.8f, 1f); + public static readonly Color LineColor = Color.cyan; + public static readonly Color SkininngLine = Color.yellow; + + /// + /// クロスペイント時のギズモ表示設定 + /// + internal static readonly ClothDebugSettings PaintSettings = new ClothDebugSettings() + { + enable = true, + position = false, + collider = false, + //basicShape = true, + animatedShape = true, + }; + + + //========================================================================================= + static List positionBuffer0 = new List(1024); + static List positionBuffer1 = new List(1024); + static List positionBuffer2 = new List(1024); + static List segmentBuffer0 = new List(2048); + static List segmentBuffer1 = new List(2048); + static List segmentBuffer2 = new List(2048); + + //========================================================================================= + /// + /// 編集時のクロスデータの表示(すべてHandlesクラスで描画) + /// + /// + /// + /// 頂点ペイント中はtrue + public static void DrawClothEditor(VirtualMeshContainer editMeshContainer, ClothDebugSettings drawSettings, ClothSerializeData serializeData, bool selected, bool direction, bool painting) + { + if (editMeshContainer == null || editMeshContainer.shareVirtualMesh == null || editMeshContainer.shareVirtualMesh.IsSuccess == false) + return; + + if (drawSettings.enable == false || serializeData == null) + return; + + // シーンカメラ + var scam = SceneView.currentDrawingSceneView != null ? SceneView.currentDrawingSceneView.camera : null; + if (scam == null) + return; + var crot = scam.transform.rotation; + + // 座標空間に合わせる + var editMesh = editMeshContainer.shareVirtualMesh; + var t = editMeshContainer.GetCenterTransform(); + if (t == null) + return; + + Handles.zTest = drawSettings.ztest ? UnityEngine.Rendering.CompareFunction.LessEqual : UnityEngine.Rendering.CompareFunction.Always; + Handles.lighting = true; + Handles.matrix = t.localToWorldMatrix; + + // シーンカメラ回転をローカル空間へ変換する + crot = Quaternion.Inverse(t.rotation) * crot; + + int vcnt = editMesh.VertexCount; + float worldToLocalScale = 1.0f / t.lossyScale.x; + float drawPointSize = drawSettings.GetPointSize() * worldToLocalScale; + float drawLineSize = drawSettings.GetLineSize() * worldToLocalScale; + float3 cdir = crot * Vector3.forward; // ローカルカメラ方向 + + float colorScale = selected ? 1.0f : 0.5f; + + // position + if (drawSettings.position || drawSettings.animatedPosition) + { + using var pointList = new NativeList(vcnt, Allocator.TempJob); + + for (int i = 0; i < vcnt; i++) + { + if (drawSettings.CheckParticleDrawing(i) == false) + continue; + + var point = new ClothPainter.Point() + { + vindex = i, + }; + pointList.AddNoResize(point); + } + if (pointList.Length > 0) + { + // カメラ距離でソート + ClothPainter.CalcPointCameraDistance(editMesh.localPositions.GetNativeArray(), 0, t.localToWorldMatrix, scam.transform.position, pointList); + + // 描画 + int cnt = pointList.Length; + for (int i = 0; i < cnt; i++) + { + var p = pointList[i]; + + var attr = editMesh.attributes[p.vindex]; + + var col = InvalidPointColor; + if (attr.IsFixed()) col = FixedPointColor; + else if (attr.IsMove()) col = MovePointColor; + GizmoUtility.SetColor(col * colorScale, true); + + // radius + float depth = editMesh.vertexDepths[p.vindex]; + var pos = editMesh.localPositions[p.vindex]; + if (attr.IsDisableCollision()) + { + // コリジョン無効は固定サイズワイヤーフレーム表示 + GizmoUtility.DrawSimpleWireSphere(pos, 0.01f, crot, true); + } + else + { + float radius = serializeData.radius.Evaluate(depth); + radius *= worldToLocalScale; + GizmoUtility.DrawSphere(pos, drawSettings.CheckRadiusDrawing() ? radius : drawPointSize, true); + } + } + } + } + + // animated shape / shape + if (drawSettings.animatedShape || drawSettings.shape) + { + positionBuffer0.Clear(); + segmentBuffer0.Clear(); + for (int i = 0; i < vcnt; i++) + { + positionBuffer0.Add(editMesh.localPositions[i]); + } + + GizmoUtility.SetColor(drawSettings.animatedShape ? BaseTriangleColor : TriangleColor, true); + int tcnt = editMesh.TriangleCount; + for (int i = 0; i < tcnt; i++) + { + if (drawSettings.CheckTriangleDrawing(i) == false) + continue; + + int3 tri = editMesh.triangles[i]; + + // attribute + //if (drawSettings.animatedShape == false) + //{ + // var attr0 = editMesh.attributes[tri.x]; + // var attr1 = editMesh.attributes[tri.y]; + // var attr2 = editMesh.attributes[tri.y]; + // if (attr0.IsInvalid() || attr1.IsInvalid() || attr2.IsInvalid()) + // continue; + //} + + // 方向性 + if (direction) + { + var tn = MathUtility.TriangleNormal(editMesh.localPositions[tri.x], editMesh.localPositions[tri.y], editMesh.localPositions[tri.z]); + if (math.dot(tn, cdir) >= 0.0f) + continue; + } + + segmentBuffer0.Add(tri.x); + segmentBuffer0.Add(tri.y); + segmentBuffer0.Add(tri.y); + segmentBuffer0.Add(tri.z); + segmentBuffer0.Add(tri.z); + segmentBuffer0.Add(tri.x); + } + Handles.DrawLines(positionBuffer0.ToArray(), segmentBuffer0.ToArray()); + + segmentBuffer0.Clear(); + GizmoUtility.SetColor((drawSettings.animatedShape ? BaseLineColor : LineColor) * colorScale, true); + int lcnt = editMesh.LineCount; + for (int i = 0; i < lcnt; i++) + { + int2 line = editMesh.lines[i]; + + // attribute + //if (drawSettings.animatedShape == false) + //{ + // var attr0 = editMesh.attributes[line.x]; + // var attr1 = editMesh.attributes[line.y]; + // if (attr0.IsInvalid() || attr1.IsInvalid()) + // continue; + //} + + segmentBuffer0.Add(line.x); + segmentBuffer0.Add(line.y); + } + Handles.DrawLines(positionBuffer0.ToArray(), segmentBuffer0.ToArray()); + } + + // base line + if (drawSettings.baseLine && editMesh.BaseLineCount > 0) + { + GizmoUtility.SetColor(new Color(1.0f, 0.27f, 0.0f) * colorScale, true); + int bcnt = editMesh.BaseLineCount; + for (int i = 0; i < bcnt; i++) + { + int dstart = editMesh.baseLineStartDataIndices[i]; + int dcnt = editMesh.baseLineDataCounts[i]; + for (int j = 1; j < dcnt; j++) + { + int vindex = editMesh.baseLineData[dstart + j]; + int pindex = editMesh.vertexParentIndices[vindex]; + if (pindex >= 0) + { + var pos = editMesh.localPositions[vindex]; + var ppos = editMesh.localPositions[pindex]; + GizmoUtility.DrawLine(pos, ppos, true); + } + } + } + } + + // axis + if (drawSettings.axis != ClothDebugSettings.DebugAxis.None || drawSettings.animatedAxis != ClothDebugSettings.DebugAxis.None) + { + positionBuffer0.Clear(); + positionBuffer1.Clear(); + positionBuffer2.Clear(); + segmentBuffer0.Clear(); + segmentBuffer1.Clear(); + segmentBuffer2.Clear(); + + for (int i = 0; i < vcnt; i++) + { + if (drawSettings.CheckParticleDrawing(i) == false) + continue; + + // attribute + //if (drawSettings.animatedAxis == ClothDebugSettings.DebugAxis.None) + //{ + // var attr = editMesh.attributes[i]; + // if (attr.IsInvalid()) + // continue; + //} + + var pos = editMesh.localPositions[i]; + var rot = MathUtility.ToRotation(editMesh.localNormals[i], editMesh.localTangents[i]); + + // 基準軸の変換用ローカル回転 + float len = drawLineSize; + + // 基準軸 + bool xaxis = false, yaxis = false, zaxis = false; + if (drawSettings.axis == ClothDebugSettings.DebugAxis.Normal || drawSettings.animatedAxis == ClothDebugSettings.DebugAxis.Normal) + { + switch (serializeData.normalAxis) + { + case ClothNormalAxis.Right: + case ClothNormalAxis.InverseRight: + xaxis = true; + break; + case ClothNormalAxis.Up: + case ClothNormalAxis.InverseUp: + yaxis = true; + break; + case ClothNormalAxis.Forward: + case ClothNormalAxis.InverseForward: + zaxis = true; + break; + } + } + if (drawSettings.axis == ClothDebugSettings.DebugAxis.All || drawSettings.animatedAxis == ClothDebugSettings.DebugAxis.All) + { + xaxis = yaxis = zaxis = true; + } + + if (xaxis) + { + int index = positionBuffer0.Count; + positionBuffer0.Add(pos); + positionBuffer0.Add(pos + MathUtility.ToBinormal(rot) * len); + segmentBuffer0.Add(index); + segmentBuffer0.Add(index + 1); + } + if (yaxis) + { + int index = positionBuffer1.Count; + positionBuffer1.Add(pos); + positionBuffer1.Add(pos + MathUtility.ToNormal(rot) * len); + segmentBuffer1.Add(index); + segmentBuffer1.Add(index + 1); + } + if (zaxis) + { + int index = positionBuffer2.Count; + positionBuffer2.Add(pos); + positionBuffer2.Add(pos + MathUtility.ToTangent(rot) * len); + segmentBuffer2.Add(index); + segmentBuffer2.Add(index + 1); + } + } + + if (positionBuffer0.Count > 0) + { + Handles.color = Color.red * colorScale; + Handles.DrawLines(positionBuffer0.ToArray(), segmentBuffer0.ToArray()); + } + if (positionBuffer1.Count > 0) + { + Handles.color = Color.green * colorScale; + Handles.DrawLines(positionBuffer1.ToArray(), segmentBuffer1.ToArray()); + } + if (positionBuffer2.Count > 0) + { + Handles.color = Color.blue * colorScale; + Handles.DrawLines(positionBuffer2.ToArray(), segmentBuffer2.ToArray()); + } + } + + // depth + if (drawSettings.depth) + { + for (int i = 0; i < vcnt; i++) + { + if (drawSettings.CheckParticleDrawing(i) == false) + continue; + + var pos = editMesh.localPositions[i]; + var depth = editMesh.vertexDepths[i]; + if (depth > 0.0f) + Handles.Label(pos, $"{depth:0.##}"); + } + } +#if MC2_DEBUG + // number + else if (drawSettings.particleNumber || drawSettings.localNumber) + { + for (int i = 0; i < vcnt; i++) + { + if (drawSettings.CheckParticleDrawing(i) == false) + continue; + + var pos = editMesh.localPositions[i]; + Handles.Label(pos, i.ToString()); + } + } + // attribute + else if (drawSettings.attribute) + { + for (int i = 0; i < vcnt; i++) + { + if (drawSettings.CheckParticleDrawing(i) == false) + continue; + + var pos = editMesh.localPositions[i]; + var attr = editMesh.attributes[i]; + Handles.Label(pos, $"0x{attr.Value:X2}"); + } + } + // triangle number + else if (drawSettings.triangleNumber) + { + int tcnt = editMesh.TriangleCount; + for (int i = 0; i < tcnt; i++) + { + if (drawSettings.CheckTriangleDrawing(i) == false) + continue; + + int3 tri = editMesh.triangles[i]; + var pos1 = editMesh.localPositions[tri.x]; + var pos2 = editMesh.localPositions[tri.y]; + var pos3 = editMesh.localPositions[tri.z]; + var cen = MathUtility.TriangleCenter(pos1, pos2, pos3); + Handles.Label(cen, i.ToString()); + } + } +#endif + + // inertia center + if (painting == false && editMesh.CenterFixedPointCount > 0 && drawSettings.inertiaCenter) + { + float3 pos = 0; + int ccnt = editMesh.CenterFixedPointCount; + for (int i = 0; i < ccnt; i++) + { + pos += editMesh.localPositions[editMesh.centerFixedList[i]]; + } + pos /= ccnt; + GizmoUtility.SetColor(Color.magenta * colorScale, true); + GizmoUtility.DrawSphere(pos, drawSettings.GetInertiaCenterRadius() * worldToLocalScale, true); + } + + Handles.matrix = Matrix4x4.identity; + crot = scam.transform.rotation; + + // custom skinning bone + if (painting == false && serializeData.customSkinningSetting.enable && drawSettings.customSkinningBone) + { + Handles.color = SkininngLine * colorScale; + var boneList = serializeData.customSkinningSetting.skinningBones; +#if MC2_CUSTOM_SKINNING_V1 + for (int i = 0; i < boneList.Count - 1; i++) + { + var bone1 = boneList[i]; + if (bone1 == null) + continue; + + for (int j = i + 1; j < boneList.Count; j++) + { + var bone2 = boneList[j]; + if (bone2 == null) + continue; + + if (bone1.parent == bone2 || bone2.parent == bone1) + { + Handles.DrawLine(bone1.position, bone2.position); + } + } + } +#else + // V2 + for (int i = 0; i < boneList.Count; i++) + { + var bone1 = boneList[i]; + if (bone1 == null) + continue; + + GizmoUtility.DrawWireSphere(bone1.position, quaternion.identity, drawSettings.GetCustomSkinningRadius(), crot, true); + } +#endif + } + } + + /// + /// 実行時のクロスデータの表示(すべてHandlesクラスで描画) + /// + /// + /// + public static void DrawClothRuntime(ClothProcess cprocess, ClothDebugSettings drawSettings, bool selected) + { + if (cprocess == null || cprocess.IsValid() == false) + return; + if (drawSettings.enable == false) + return; + if (MagicaManager.Team == null) + return; + if (MagicaManager.Team.ContainsTeamData(cprocess.TeamId) == false) + return; + + // プロキシメッシュ + var proxyMesh = cprocess.ProxyMeshContainer?.shareVirtualMesh; + if (proxyMesh == null || proxyMesh.IsSuccess == false) + return; + + // シーンカメラ + var scam = SceneView.currentDrawingSceneView != null ? SceneView.currentDrawingSceneView.camera : null; + if (scam == null) + return; + var crot = scam.transform.rotation; + + // チームデータ + var tdata = MagicaManager.Team.GetTeamDataRef(cprocess.TeamId); + var cdata = MagicaManager.Team.centerDataArray[cprocess.TeamId]; + int pcnt = tdata.ParticleCount; + int pstart = tdata.particleChunk.startIndex; + int vstart = tdata.proxyCommonChunk.startIndex; + float drawPointSize = drawSettings.GetPointSize(); + float drawLineSize = drawSettings.GetLineSize(); + + // 座標空間に合わせる + var t = cprocess.cloth.ClothTransform; + if (t == null) + return; + + Handles.zTest = drawSettings.ztest ? UnityEngine.Rendering.CompareFunction.LessEqual : UnityEngine.Rendering.CompareFunction.Always; + Handles.matrix = Matrix4x4.identity; + float colorScale = selected ? 1 : 0.5f; + + var sim = MagicaManager.Simulation; + var vm = MagicaManager.VMesh; + + // 座標参照先 + var positionArray = drawSettings.IsReferOldPos() ? sim.oldPosArray : sim.dispPosArray; + + // position + if (drawSettings.position) + { + using var pointList = new NativeList(pcnt, Allocator.TempJob); + + for (int i = 0; i < pcnt; i++) + { + if (drawSettings.CheckParticleDrawing(i) == false) + continue; + + var point = new ClothPainter.Point() + { + vindex = i, + }; + pointList.AddNoResize(point); + } + if (pointList.Length > 0) + { + // カメラ距離でソート + ClothPainter.CalcPointCameraDistance(positionArray.GetNativeArray(), pstart, float4x4.identity, scam.transform.position, pointList); + + // 描画 + int cnt = pointList.Length; + for (int i = 0; i < cnt; i++) + { + var p = pointList[i]; + + int pindex = pstart + p.vindex; + int cvindex = tdata.proxyCommonChunk.startIndex + p.vindex; + + var attr = vm.attributes[cvindex]; + + // 無効属性は表示しない + if (attr.IsInvalid()) + continue; + + var col = InvalidPointColor; + if (attr.IsFixed()) col = FixedPointColor; + else if (attr.IsMove()) col = MovePointColor; + GizmoUtility.SetColor(col * colorScale, true); + + // radius + float depth = vm.vertexDepths[cvindex]; + var pos = positionArray[pindex]; + if (attr.IsDisableCollision()) + { + // コリジョン無効は固定サイズワイヤーフレーム表示 + GizmoUtility.DrawSimpleWireSphere(pos, 0.01f, crot, true); + } + else + { + float radius = cprocess.parameters.radiusCurveData.MC2EvaluateCurve(depth); + radius *= tdata.scaleRatio; + GizmoUtility.DrawSphere(pos, drawSettings.CheckRadiusDrawing() ? radius : drawPointSize, true); + } + } + } + } + + // rotation axis / area + if (drawSettings.axis != ClothDebugSettings.DebugAxis.None) + { + positionBuffer0.Clear(); + positionBuffer1.Clear(); + positionBuffer2.Clear(); + segmentBuffer0.Clear(); + segmentBuffer1.Clear(); + segmentBuffer2.Clear(); + + for (int i = 0; i < pcnt; i++) + { + if (drawSettings.CheckParticleDrawing(i) == false) + continue; + + int pindex = pstart + i; + int cvindex = tdata.proxyCommonChunk.startIndex + i; + + // attribute + if (vm.attributes[cvindex].IsInvalid()) + continue; + + var pos = positionArray[pindex]; + var rot = vm.rotations[cvindex]; // 計算済みの前フレームの最終姿勢 + + float len = drawLineSize; + + // 基準軸 + bool xaxis = false, yaxis = false, zaxis = false; + if (drawSettings.axis == ClothDebugSettings.DebugAxis.Normal) + { + switch (cprocess.parameters.normalAxis) + { + case ClothNormalAxis.Right: + case ClothNormalAxis.InverseRight: + xaxis = true; + break; + case ClothNormalAxis.Up: + case ClothNormalAxis.InverseUp: + yaxis = true; + break; + case ClothNormalAxis.Forward: + case ClothNormalAxis.InverseForward: + zaxis = true; + break; + } + } + if (drawSettings.axis == ClothDebugSettings.DebugAxis.All) + { + xaxis = yaxis = zaxis = true; + } + + if (xaxis) + { + int index = positionBuffer0.Count; + positionBuffer0.Add(pos); + positionBuffer0.Add(pos + MathUtility.ToBinormal(rot) * len); + segmentBuffer0.Add(index); + segmentBuffer0.Add(index + 1); + } + if (yaxis) + { + int index = positionBuffer1.Count; + positionBuffer1.Add(pos); + positionBuffer1.Add(pos + MathUtility.ToNormal(rot) * len); + segmentBuffer1.Add(index); + segmentBuffer1.Add(index + 1); + } + if (zaxis) + { + int index = positionBuffer2.Count; + positionBuffer2.Add(pos); + positionBuffer2.Add(pos + MathUtility.ToTangent(rot) * len); + segmentBuffer2.Add(index); + segmentBuffer2.Add(index + 1); + } + } + + if (positionBuffer0.Count > 0) + { + Handles.color = Color.red * colorScale; + Handles.DrawLines(positionBuffer0.ToArray(), segmentBuffer0.ToArray()); + } + if (positionBuffer1.Count > 0) + { + Handles.color = Color.green * colorScale; + Handles.DrawLines(positionBuffer1.ToArray(), segmentBuffer1.ToArray()); + } + if (positionBuffer2.Count > 0) + { + Handles.color = Color.blue * colorScale; + Handles.DrawLines(positionBuffer2.ToArray(), segmentBuffer2.ToArray()); + } + } + +#if MC2_DEBUG + // collision normal + if (drawSettings.collisionNormal) + { + GizmoUtility.SetColor(Color.yellow * colorScale, true); + for (int i = 0; i < pcnt; i++) + { + if (drawSettings.CheckParticleDrawing(i) == false) + continue; + + int pindex = pstart + i; + var pos = positionArray[pindex]; + float3 cn = sim.collisionNormalArray[pindex]; + if (math.lengthsq(cn) > 1e-06f) + { + GizmoUtility.DrawLine(pos, pos + cn * drawPointSize, true); + } + } + } +#endif + + // animated shape + if (drawSettings.animatedShape) + { + positionBuffer0.Clear(); + segmentBuffer0.Clear(); + for (int i = 0; i < pcnt; i++) + { + positionBuffer0.Add(sim.basePosArray[pstart + i]); + //positionBuffer0.Add(sim.stepBasicPositionBuffer[pstart + i]); + } + + GizmoUtility.SetColor(BaseTriangleColor, true); + int tcnt = tdata.proxyTriangleChunk.dataLength; + for (int i = 0; i < tcnt; i++) + { + if (drawSettings.CheckTriangleDrawing(i) == false) + continue; + + int tindex = tdata.proxyTriangleChunk.startIndex + i; + int3 tri = vm.triangles[tindex]; + + //int3 vtri = tri + tdata.proxyCommonChunk.startIndex; + //if (vm.attributes[vtri.x].IsInvalid() || vm.attributes[vtri.y].IsInvalid() || vm.attributes[vtri.z].IsInvalid()) + // continue; + + segmentBuffer0.Add(tri.x); + segmentBuffer0.Add(tri.y); + segmentBuffer0.Add(tri.y); + segmentBuffer0.Add(tri.z); + segmentBuffer0.Add(tri.z); + segmentBuffer0.Add(tri.x); + } + Handles.DrawLines(positionBuffer0.ToArray(), segmentBuffer0.ToArray()); + + segmentBuffer0.Clear(); + GizmoUtility.SetColor(BaseLineColor * colorScale, true); + int lcnt = proxyMesh.LineCount; + for (int i = 0; i < lcnt; i++) + { + int2 line = proxyMesh.lines[i]; + segmentBuffer0.Add(line.x); + segmentBuffer0.Add(line.y); + } + Handles.DrawLines(positionBuffer0.ToArray(), segmentBuffer0.ToArray()); + } + + // shape + if (drawSettings.shape) + { + positionBuffer0.Clear(); + segmentBuffer0.Clear(); + for (int i = 0; i < pcnt; i++) + { + positionBuffer0.Add(positionArray[pstart + i]); + } + + GizmoUtility.SetColor(TriangleColor * colorScale, true); + int tcnt = tdata.proxyTriangleChunk.dataLength; + for (int i = 0; i < tcnt; i++) + { + if (drawSettings.CheckTriangleDrawing(i) == false) + continue; + + int tindex = tdata.proxyTriangleChunk.startIndex + i; + int3 tri = vm.triangles[tindex]; + +#if true + int3 vtri = tri + tdata.proxyCommonChunk.startIndex; + if (vm.attributes[vtri.x].IsInvalid() || vm.attributes[vtri.y].IsInvalid() || vm.attributes[vtri.z].IsInvalid()) + continue; +#endif + + segmentBuffer0.Add(tri.x); + segmentBuffer0.Add(tri.y); + segmentBuffer0.Add(tri.y); + segmentBuffer0.Add(tri.z); + segmentBuffer0.Add(tri.z); + segmentBuffer0.Add(tri.x); + } + Handles.DrawLines(positionBuffer0.ToArray(), segmentBuffer0.ToArray()); + + segmentBuffer0.Clear(); + GizmoUtility.SetColor(LineColor * colorScale, true); + int lcnt = proxyMesh.LineCount; + for (int i = 0; i < lcnt; i++) + { + int2 line = proxyMesh.lines[i]; + +#if true + int2 vline = line + tdata.proxyCommonChunk.startIndex; + if (vm.attributes[vline.x].IsInvalid() || vm.attributes[vline.y].IsInvalid()) + continue; +#endif + + segmentBuffer0.Add(line.x); + segmentBuffer0.Add(line.y); + } + Handles.DrawLines(positionBuffer0.ToArray(), segmentBuffer0.ToArray()); + } + + // base line + if (drawSettings.baseLine && proxyMesh.BaseLineCount > 0) + { + GizmoUtility.SetColor(new Color(1.0f, 0.27f, 0.0f) * colorScale, true); + int bcnt = proxyMesh.BaseLineCount; + for (int i = 0; i < bcnt; i++) + { + int dstart = proxyMesh.baseLineStartDataIndices[i]; + int dcnt = proxyMesh.baseLineDataCounts[i]; + for (int j = 1; j < dcnt; j++) + { + int vindex = proxyMesh.baseLineData[dstart + j]; + int pindex = proxyMesh.vertexParentIndices[vindex]; + if (pindex >= 0) + { + var pos = positionArray[pstart + vindex]; + var ppos = positionArray[pstart + pindex]; + GizmoUtility.DrawLine(pos, ppos, true); + } + } + } + } + + // animated position + if (drawSettings.animatedPosition) + { + for (int i = 0; i < pcnt; i++) + { + if (drawSettings.CheckParticleDrawing(i) == false) + continue; + + int pindex = tdata.particleChunk.startIndex + i; + + //int cvindex = tdata.proxyCommonChunk.startIndex + i; + //var attr = vm.attributes[cvindex]; + //if (attr.IsInvalid()) + // continue; + + var pos = sim.basePosArray[pindex]; + //var pos = sim.stepBasicPositionBuffer[pindex]; + GizmoUtility.SetColor(Color.cyan * colorScale, true); + GizmoUtility.DrawSphere(pos, drawPointSize, true); + } + } + + // animated axis + if (drawSettings.animatedAxis != ClothDebugSettings.DebugAxis.None) + { + float size = drawLineSize; + + positionBuffer0.Clear(); + positionBuffer1.Clear(); + positionBuffer2.Clear(); + segmentBuffer0.Clear(); + segmentBuffer1.Clear(); + segmentBuffer2.Clear(); + + for (int i = 0; i < pcnt; i++) + { + if (drawSettings.CheckParticleDrawing(i) == false) + continue; + + int pindex = tdata.particleChunk.startIndex + i; + int cvindex = tdata.proxyCommonChunk.startIndex + i; + + //var attr = vm.attributes[cvindex]; + //if (attr.IsInvalid()) + // continue; + + var pos = sim.basePosArray[pindex]; + var rot = sim.baseRotArray[pindex]; + //var pos = sim.stepBasicPositionBuffer[pindex]; + //var rot = sim.stepBasicRotationBuffer[pindex]; + + // 基準軸 + bool xaxis = false, yaxis = false, zaxis = false; + if (drawSettings.animatedAxis == ClothDebugSettings.DebugAxis.Normal) + { + switch (cprocess.parameters.normalAxis) + { + case ClothNormalAxis.Right: + case ClothNormalAxis.InverseRight: + xaxis = true; + break; + case ClothNormalAxis.Up: + case ClothNormalAxis.InverseUp: + yaxis = true; + break; + case ClothNormalAxis.Forward: + case ClothNormalAxis.InverseForward: + zaxis = true; + break; + } + } + if (drawSettings.animatedAxis == ClothDebugSettings.DebugAxis.All) + { + xaxis = yaxis = zaxis = true; + } + + if (xaxis) + { + int index = positionBuffer0.Count; + positionBuffer0.Add(pos); + positionBuffer0.Add(pos + MathUtility.ToBinormal(rot) * size); + segmentBuffer0.Add(index); + segmentBuffer0.Add(index + 1); + } + if (yaxis) + { + int index = positionBuffer1.Count; + positionBuffer1.Add(pos); + positionBuffer1.Add(pos + MathUtility.ToNormal(rot) * size); + segmentBuffer1.Add(index); + segmentBuffer1.Add(index + 1); + } + if (zaxis) + { + int index = positionBuffer2.Count; + positionBuffer2.Add(pos); + positionBuffer2.Add(pos + MathUtility.ToTangent(rot) * size); + segmentBuffer2.Add(index); + segmentBuffer2.Add(index + 1); + } + } + + if (positionBuffer0.Count > 0) + { + Handles.color = Color.red * colorScale; + Handles.DrawLines(positionBuffer0.ToArray(), segmentBuffer0.ToArray()); + } + if (positionBuffer1.Count > 0) + { + Handles.color = Color.green * colorScale; + Handles.DrawLines(positionBuffer1.ToArray(), segmentBuffer1.ToArray()); + } + if (positionBuffer2.Count > 0) + { + Handles.color = Color.blue * colorScale; + Handles.DrawLines(positionBuffer2.ToArray(), segmentBuffer2.ToArray()); + } + } + +#if false + // distance constraint + //for (int k = 0; k < DistanceConstraint.TypeCount; k++) + { + //bool drawFlag = false; + //switch (k) + //{ + // case DistanceConstraint.Type_Vertical: drawFlag = drawSettings.verticalDistanceConstraint; break; + // case DistanceConstraint.Type_Horizontal: drawFlag = drawSettings.horizontalDistanceConstraint; break; + //} + //if (drawFlag == false) + // continue; + + var distanceConstraint = sim.distanceConstraint; + //var nData = distanceConstraint.nativeData[k]; + + var sc = tdata.distanceStartChunk; + var dc = tdata.distanceDataChunk; + if (sc.IsValid) + { + //var col = Color.black; + //switch (k) + //{ + // case DistanceConstraint.Type_Vertical: + // col = Color.yellow; + // break; + // case DistanceConstraint.Type_Horizontal: + // col = Color.red; + // break; + //} + //GizmoUtility.SetColor(col * colorScale, true); + + positionBuffer0.Clear(); + segmentBuffer0.Clear(); + for (int i = 0; i < pcnt; i++) + { + positionBuffer0.Add(positionArray[pstart + i]); + } + + for (int i = 0; i < pcnt; i++) + { + if (drawSettings.CheckParticleDrawing(i) == false) + continue; + + int cindex = sc.startIndex + i; + var pack = distanceConstraint.indexArray[cindex]; + DataUtility.Unpack10_22(pack, out int dcnt, out int dstart); + if (dcnt > 0) + { + for (int j = 0; j < dcnt; j++) + { + int targetIndex = distanceConstraint.dataArray[dc.startIndex + dstart + j]; + segmentBuffer0.Add(i); + segmentBuffer0.Add(targetIndex); + } + } + } + Handles.DrawLines(positionBuffer0.ToArray(), segmentBuffer0.ToArray()); + } + } +#endif + + // depth + if (drawSettings.depth) + { + for (int i = 0; i < pcnt; i++) + { + if (drawSettings.CheckParticleDrawing(i) == false) + continue; + + int pindex = tdata.particleChunk.startIndex + i; + int cvindex = tdata.proxyCommonChunk.startIndex + i; + + if (vm.attributes[cvindex].IsInvalid()) + continue; + + var pos = positionArray[pindex]; + var depth = vm.vertexDepths[cvindex]; + Handles.Label(pos, $"{depth:0.##}"); + } + } +#if MC2_DEBUG + // number + else if (drawSettings.particleNumber || drawSettings.localNumber) + { + for (int i = 0; i < pcnt; i++) + { + //if (drawSettings.CheckParticleDrawing(i) == false) + // continue; + + int pindex = tdata.particleChunk.startIndex + i; + var pos = positionArray[pindex]; + if (drawSettings.particleNumber && drawSettings.CheckParticleDrawing(pindex)) + Handles.Label(pos, pindex.ToString()); + else if (drawSettings.localNumber && drawSettings.CheckParticleDrawing(i)) + Handles.Label(pos, i.ToString()); + } + } + // attribute + else if (drawSettings.attribute) + { + for (int i = 0; i < pcnt; i++) + { + if (drawSettings.CheckParticleDrawing(i) == false) + continue; + + int pindex = tdata.particleChunk.startIndex + i; + int cvindex = tdata.proxyCommonChunk.startIndex + i; + + var pos = positionArray[pindex]; + var attr = vm.attributes[cvindex]; + Handles.Label(pos, $"0x{attr.Value:X2}"); + } + } + // friction + else if (drawSettings.friction) + { + for (int i = 0; i < pcnt; i++) + { + if (drawSettings.CheckParticleDrawing(i) == false) + continue; + + int pindex = tdata.particleChunk.startIndex + i; + int cvindex = tdata.proxyCommonChunk.startIndex + i; + + var pos = positionArray[pindex]; + var friction = sim.frictionArray[pindex]; + if (friction > 1e-06f) + Handles.Label(pos, $"{friction:0.##}"); + } + } + // static friction + else if (drawSettings.staticFriction) + { + for (int i = 0; i < pcnt; i++) + { + if (drawSettings.CheckParticleDrawing(i) == false) + continue; + + int pindex = tdata.particleChunk.startIndex + i; + int cvindex = tdata.proxyCommonChunk.startIndex + i; + + var pos = positionArray[pindex]; + var friction = sim.staticFrictionArray[pindex]; + if (friction > 1e-06f) + Handles.Label(pos, $"{friction:0.##}"); + } + } + // triangle number + else if (drawSettings.triangleNumber) + { + int tcnt = tdata.proxyTriangleChunk.dataLength; + for (int i = 0; i < tcnt; i++) + { + if (drawSettings.CheckTriangleDrawing(i) == false) + continue; + + int tindex = tdata.proxyTriangleChunk.startIndex + i; + int3 tri = vm.triangles[tindex]; + var pos1 = positionArray[pstart + tri.x]; + var pos2 = positionArray[pstart + tri.y]; + var pos3 = positionArray[pstart + tri.z]; + var cen = MathUtility.TriangleCenter(pos1, pos2, pos3); + Handles.Label(cen, i.ToString()); + } + } + // base line pos + if (drawSettings.baseLinePos) + { + var col = new Color(1.0f, 0.7f, 0.3f); + for (int i = 0; i < pcnt; i++) + { + if (drawSettings.CheckParticleDrawing(i) == false) + continue; + + int pindex = tdata.particleChunk.startIndex + i; + + var pos = sim.stepBasicPositionBuffer[pindex]; + GizmoUtility.SetColor(col * colorScale, true); + GizmoUtility.DrawSphere(pos, drawPointSize, true); + } + } +#endif + + // 空間を戻す + Handles.matrix = Matrix4x4.identity; + crot = scam.transform.rotation; + + // 以下はワールド + // custom skinning bone + if (cprocess.cloth.SerializeData.customSkinningSetting.enable && drawSettings.customSkinningBone) + { + Handles.color = SkininngLine * colorScale; + var boneList = cprocess.cloth.SerializeData.customSkinningSetting.skinningBones; +#if MC2_CUSTOM_SKINNING_V1 + for (int i = 0; i < boneList.Count - 1; i++) + { + var bone1 = boneList[i]; + if (bone1 == null) + continue; + for (int j = i + 1; j < boneList.Count; j++) + { + var bone2 = boneList[j]; + if (bone2 == null) + continue; + + if (bone1.parent == bone2 || bone2.parent == bone1) + { + Handles.DrawLine(bone1.position, bone2.position); + } + } + } +#else + // V2 + for (int i = 0; i < boneList.Count; i++) + { + var bone1 = boneList[i]; + if (bone1 == null) + continue; + + GizmoUtility.DrawWireSphere(bone1.position, quaternion.identity, drawSettings.GetCustomSkinningRadius(), crot, true); + } +#endif + } + + + // inertia center + if (drawSettings.inertiaCenter) + { + var pos = cdata.nowWorldPosition; + var rot = cdata.nowWorldRotation; + GizmoUtility.SetColor(Color.magenta * colorScale, true); + GizmoUtility.DrawSphere(pos, drawSettings.GetInertiaCenterRadius(), true); + GizmoUtility.DrawCross(pos, rot, drawSettings.GetInertiaCenterRadius() * 2.0f, true); + } + +#if MC2_DEBUG + // cell cube + //if (drawSettings.cellCube) + //{ + // GizmoUtility.SetColor(Color.black * colorScale, true); + // GizmoUtility.DrawWireCube(tdata.cubeWorldCenter, Quaternion.identity, Vector3.one * tdata.cubeSize, true); + //} +#endif + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Editor/Cloth/ClothEditorUtility.cs.meta b/Assets/MagicaCloth2/Scripts/Editor/Cloth/ClothEditorUtility.cs.meta new file mode 100644 index 00000000..a97360ac --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Editor/Cloth/ClothEditorUtility.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: f11b17a94f5361246b6c56a0fb52570e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Editor/Cloth/ClothEditorUtility.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Editor/Cloth/ClothInspectorUtility.cs b/Assets/MagicaCloth2/Scripts/Editor/Cloth/ClothInspectorUtility.cs new file mode 100644 index 00000000..79965c79 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Editor/Cloth/ClothInspectorUtility.cs @@ -0,0 +1,76 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using UnityEditor; +using UnityEngine; + +namespace MagicaCloth2 +{ + public static class ClothInspectorUtility + { + //=============================================================================== + /// + /// 折りたたみ制御 + /// + /// 折りたたみ保存キー + /// + /// 内容描画アクション + /// 有効フラグアクション(null=無効) + /// 現在の有効フラグ + public static void Foldout( + string foldKey, + string title = null, + System.Action drawAct = null, + System.Action enableAct = null, + bool enable = false, + bool warning = false + ) + { + var style = new GUIStyle("ShurikenModuleTitle"); + style.font = new GUIStyle(EditorStyles.label).font; + style.border = new RectOffset(15, 7, 4, 4); + style.fixedHeight = 22; + style.contentOffset = new Vector2(20f, -2f); + + var rect = GUILayoutUtility.GetRect(16f, 22f, style); + + GUI.backgroundColor = warning ? Color.yellow : Color.white; + GUI.Box(rect, title, style); + GUI.backgroundColor = Color.white; + + var e = Event.current; + bool foldOut = EditorPrefs.GetBool(foldKey); + + if (enableAct == null) + { + if (e.type == EventType.Repaint) + { + var toggleRect = new Rect(rect.x + 4f, rect.y + 2f, 13f, 13f); + EditorStyles.foldout.Draw(toggleRect, false, false, foldOut, false); + } + } + else + { + // 有効チェック + var toggleRect = new Rect(rect.x + 4f, rect.y + 4f, 13f, 13f); + bool sw = GUI.Toggle(toggleRect, enable, string.Empty, new GUIStyle("ShurikenCheckMark")); + if (sw != enable) + { + enableAct(sw); + } + } + + if (e.type == EventType.MouseDown && rect.Contains(e.mousePosition)) + { + foldOut = !foldOut; + EditorPrefs.SetBool(foldKey, foldOut); + e.Use(); + } + + if (foldOut && drawAct != null) + { + drawAct(); + } + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Editor/Cloth/ClothInspectorUtility.cs.meta b/Assets/MagicaCloth2/Scripts/Editor/Cloth/ClothInspectorUtility.cs.meta new file mode 100644 index 00000000..5a52e2cd --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Editor/Cloth/ClothInspectorUtility.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 434cdfa441f5efc49954b9ba7d8bb241 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Editor/Cloth/ClothInspectorUtility.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Editor/Cloth/ClothPainter.cs b/Assets/MagicaCloth2/Scripts/Editor/Cloth/ClothPainter.cs new file mode 100644 index 00000000..84015af1 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Editor/Cloth/ClothPainter.cs @@ -0,0 +1,949 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using System; +using Unity.Burst; +using Unity.Collections; +using Unity.Jobs; +using Unity.Mathematics; +using UnityEditor; +using UnityEngine; + +namespace MagicaCloth2 +{ + /// + /// 頂点ペイントウインドウ + /// + [InitializeOnLoad] + public class ClothPainter + { + public enum PaintMode + { + None, + + /// + /// Move/Fixed/Ignore/Invalid + /// + Attribute, + + /// + /// Max Distance/Backstop + /// + Motion, + } + + static PaintMode paintMode = PaintMode.None; + + /// + /// 編集対象のクロスコンポーネント + /// + static MagicaCloth cloth = null; + + /// + /// 編集対象のクロスEditorクラス + /// + static MagicaClothEditor clothEditor = null; + + /// + /// 編集対象のエディットメッシュ + /// + static VirtualMeshContainer editMeshContainer = null; + + /// + /// 編集対象のセレクションデータ + /// + static SelectionData selectionData = null; + + /// + /// 編集開始時のセレクションデータ(コピー) + /// + static SelectionData initSelectionData = null; + + internal const int WindowWidth = 200; + internal const int WindowHeight = 200; + + //========================================================================================= + const int PointFlag_Selecting = 1; // 選択中 + + internal struct Point : IComparable + { + public int vindex; + public float distance; + public BitField32 flag; + + public int CompareTo(Point other) + { + if (distance != other.distance) + return distance < other.distance ? 1 : -1; + else if (vindex != other.vindex) + return vindex < other.vindex ? 1 : -1; + else + return 0; + } + } + static NativeList dispPointList; + static NativeArray pointWorldPositions; + static VirtualMeshRaycastHit rayhit = default; + static bool oldShowAll = false; + static bool forceUpdate = false; + + //========================================================================================= + static ClothPainter() + { + // シーンビューにGUIを描画するためのコールバック + SceneView.duringSceneGui += OnGUI; + } + + /// + /// ペイント開始 + /// + /// + public static void EnterPaint(PaintMode mode, MagicaClothEditor editor, MagicaCloth clothComponent, VirtualMeshContainer cmesh, SelectionData sdata) + { + Develop.DebugLog($"EnterPaint"); + + paintMode = mode; + cloth = clothComponent; + clothEditor = editor; + editMeshContainer = cmesh; + selectionData = sdata; + initSelectionData = sdata.Clone(); + rayhit = default; + forceUpdate = true; + + // ポイントバッファ + dispPointList = new NativeList(cmesh.shareVirtualMesh.VertexCount, Allocator.Persistent); + pointWorldPositions = new NativeArray(cmesh.shareVirtualMesh.VertexCount, Allocator.Persistent); + + // UndoRedoコールバック + Undo.undoRedoPerformed += UndoRedoCallback; + } + + /// + /// ペイント終了 + /// + public static void ExitPaint() + { + Develop.DebugLog($"ExitPaint"); + + cloth = null; + clothEditor = null; + editMeshContainer = null; + selectionData = null; + initSelectionData = null; + rayhit = default; + + if (dispPointList.IsCreated) + dispPointList.Dispose(); + if (pointWorldPositions.IsCreated) + pointWorldPositions.Dispose(); + + // UndoRedoコールバック + Undo.undoRedoPerformed -= UndoRedoCallback; + } + + /// + /// Undo/Redo実行後のコールバック + /// + static void UndoRedoCallback() + { + //Develop.DebugLog($"Undo Redo!"); + + if (EditorApplication.isPlaying) + return; + + if (cloth == null || editMeshContainer == null || selectionData == null || editMeshContainer.shareVirtualMesh.IsSuccess == false) + return; + + // セレクションデータを取り直す + selectionData = clothEditor.GetSelectionData(cloth, editMeshContainer.shareVirtualMesh); + + forceUpdate = true; + } + + //========================================================================================= + /// + /// 指定クロスコンポーネントを編集中かどうか + /// + /// + /// + public static bool HasEditCloth(MagicaCloth clothComponent) + { + return cloth == clothComponent; + } + + /// + /// 編集中かどうか + /// + /// + public static bool IsPainting() + { + return cloth != null; + } + + //========================================================================================= + static void OnGUI(SceneView sceneView) + { + if (EditorApplication.isPlaying) + return; + + // アクティブシーンビュー判定 + if (SceneView.lastActiveSceneView != sceneView) + return; + + if (cloth == null || editMeshContainer == null || editMeshContainer.shareVirtualMesh == null || selectionData == null) + return; + if (editMeshContainer.shareVirtualMesh.IsSuccess == false || selectionData.IsValid() == false) + return; + + var windata = ScriptableSingleton.instance; + + // シーンビューカメラ + Camera cam = SceneView.currentDrawingSceneView.camera; + Ray ray = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition); + Vector3 spos = ray.origin; + Vector3 epos = spos + ray.direction * 1000.0f; + + // 透過カーソル用 + float rayAngle = Vector3.Angle(cam.transform.forward, ray.direction); + float nearPlaneDistance = cam.orthographic ? cam.nearClipPlane : cam.nearClipPlane / math.cos(math.radians(rayAngle)); + float nearPlaneVSize = cam.orthographic ? cam.orthographicSize : math.tan(math.radians(cam.fieldOfView * 0.5f)) * cam.nearClipPlane * 2; + float brushSizeThrough = nearPlaneVSize * windata.brushSizeThrough; + + // カーソルのviewportポイント + var sp = HandleUtility.GUIPointToScreenPixelCoordinate(Event.current.mousePosition); + var cursorViewpos = cam.ScreenToViewportPoint(sp); + cursorViewpos = math.remap(new float3(0), new float3(1), new float3(-1), new float3(1), cursorViewpos); // 射影行列(-1 ~ +1)に変換 + + // カメラ座標をローカル空間に変換する + var t = cloth.ClothTransform; // コンポーネント空間 + + bool repaint = false; + bool updatePoint = false; + + // ポイントサイズ + float pointSize = windata.drawPointSize; + + bool showAll = windata.backFaceCulling == false; + + // マウス移動中は常にメッシュとの交差判定 + if (Event.current.type == EventType.MouseMove || Event.current.type == EventType.MouseDrag || oldShowAll != showAll || forceUpdate) + { + oldShowAll = showAll; + forceUpdate = false; + updatePoint = true; + } + + // マウス選択 + if (Event.current.type == EventType.MouseDown && Event.current.button == 0 && !Event.current.alt) + { + // ペイント適用 + ApplyPaint(windata, dispPointList); + + // シーンビューのエリア選択を出さないために、とりあえずこうするらしい + int controlId = GUIUtility.GetControlID(FocusType.Passive); + GUIUtility.hotControl = controlId; + Event.current.Use(); // ? + } + if (Event.current.type == EventType.MouseDrag && Event.current.button == 0 && !Event.current.alt) + { + // ペイント適用 + ApplyPaint(windata, dispPointList); + + Event.current.Use(); + } + if (Event.current.type == EventType.MouseUp && Event.current.button == 0 && !Event.current.alt) + { + // ペイント結果を適用する + ApplySelectionData(); + + // マウスボタンUPでコントロールロックを解除するらしい + GUIUtility.hotControl = 0; + Event.current.Use(); // ? + } + + // Handlesの描画はGUIの前でなければならない.理由は不明 + if (Event.current.type == EventType.Repaint) + { + // ディスクの描画 + if (windata.through) + { + // 透過モード + Handles.matrix = Matrix4x4.identity; + Handles.zTest = UnityEngine.Rendering.CompareFunction.Always; + var dpos = spos + ray.direction * nearPlaneDistance; + var dnor = cam.transform.forward; + Handles.color = new Color(0.6f, 0.2f, 1.0f, 0.3f); + Handles.DrawSolidDisc(dpos, dnor, brushSizeThrough); + } + else if (rayhit.IsValid()) + { + Handles.matrix = Matrix4x4.identity; + Handles.zTest = UnityEngine.Rendering.CompareFunction.Always; + var dpos = t.TransformPoint(rayhit.position); + var dnor = t.TransformDirection(rayhit.normal); + Handles.color = new Color(0.3f, 0.5f, 1.0f, 0.4f); + Handles.DrawSolidDisc(dpos, dnor, windata.brushSize); + } + + // ポイント表示 + Handles.lighting = true; + //Handles.zTest = showAll ? UnityEngine.Rendering.CompareFunction.Always : UnityEngine.Rendering.CompareFunction.LessEqual; + //Handles.zTest = UnityEngine.Rendering.CompareFunction.Always; + Handles.zTest = windata.zTest ? UnityEngine.Rendering.CompareFunction.LessEqual : UnityEngine.Rendering.CompareFunction.Always; + Handles.matrix = Matrix4x4.identity; + int cnt = dispPointList.Length; + for (int i = 0; i < cnt; i++) + { + var point = dispPointList[i]; + + Color col = Color.black; + var attr = selectionData.attributes[point.vindex]; + switch (paintMode) + { + case PaintMode.Attribute: + if (attr.IsMove()) col = Color.green; + else if (attr.IsFixed()) col = Color.red; + //else if (attr.IsIgnore()) col = Color.blue; + else col = Color.gray; + break; + case PaintMode.Motion: + if (attr.IsMotion()) col = Color.cyan; + else col = Color.gray; + break; + } + + // 選択中 + if (point.flag.IsSet(PointFlag_Selecting)) + { + col = Color.yellow; + } + + var pos = pointWorldPositions[point.vindex]; + Handles.color = col; + Handles.SphereHandleCap(0, pos, Quaternion.identity, windata.drawPointSize, EventType.Repaint); + } + + // ペイント中のギズモ表示 + if (windata.showShape) + ClothEditorUtility.DrawClothEditor(editMeshContainer, ClothEditorUtility.PaintSettings, cloth.SerializeData, true, windata.backFaceCulling, true); + } + + // GUI + //sceneView.BeginWindows(); + string title = string.Empty; + switch (paintMode) + { + case PaintMode.Attribute: + title = "Movement attribute paint"; + break; + case PaintMode.Motion: + title = "Max Distance/Backstop paint"; + break; + } + var rect = GUILayout.Window(71903439, windata.windowRect, DoWindow, title); + //Debug.Log(windata.windowRect); + // ウインドウをSceneViewの領域内にクランプする + // sceneView.positionでrectが取れる + rect.x = Mathf.Clamp(rect.x, 0, Mathf.Max(sceneView.position.width - rect.width, 0)); + rect.y = Mathf.Clamp(rect.y, 0, Mathf.Max(sceneView.position.height - rect.height - 25, 0)); + rect.width = WindowWidth; + rect.height = WindowHeight; + windata.windowRect = rect; + //sceneView.EndWindows(); + + // ポイントデータ更新 + if (updatePoint) + { + UpdatePoint( + windata.through, + t, cam, ray, showAll, + windata.through ? windata.brushSizeThrough : windata.brushSize, + windata.through ? cursorViewpos : t.TransformPoint(rayhit.position), + windata.drawPointSize + ); + repaint = true; + } + + // 画面リフレッシュ + if (repaint) + sceneView.Repaint(); + } + + /// + /// ポイントデータを更新する + /// + /// + /// + /// + /// + /// + static void UpdatePoint(bool through, Transform ct, Camera cam, Ray ray, bool showAll, float brushSize, float3 brushPos, float pointSize) + { + // 表示頂点選別 + CreateDispPointList(through, ct, cam, showAll, brushSize, brushPos).Complete(); + + // サーフェース交差判定 + //rayhit = editMesh.IntersectRayMesh(ray.origin, ray.direction, showAll, pointSize); + rayhit = editMeshContainer.shareVirtualMesh.IntersectRayMesh(ray.origin, ray.direction, showAll, pointSize); + } + + static JobHandle CreateDispPointList( + bool through, Transform ct, Camera cam, + bool showAll, float brushSize, float3 brushPosition, JobHandle jobHandle = default + ) + { + dispPointList.Clear(); + + var editMesh = editMeshContainer.shareVirtualMesh; + int vcnt = editMesh.VertexCount; + if (vcnt == 0) + return jobHandle; + + // ローカルカメラ + var localCameraDirection = ct.InverseTransformDirection(cam.transform.forward); + + // 頂点のワールド変換と表示頂点の選別 + var job = new CreateDispPointListJob() + { + through = through, + LtoW = ct.localToWorldMatrix, + showAll = showAll, + + cameraPosition = cam.transform.position, + cameraDirection = localCameraDirection, + + cameraProjectionMatrix = cam.projectionMatrix, + worldToCameraMatrix = cam.worldToCameraMatrix, + cameraAspectRatio = cam.aspect, + + useBrush = through || rayhit.IsValid(), + brushPosition = brushPosition, + brushSize = brushSize, + + localPositions = editMesh.localPositions.GetNativeArray(), + localNormals = editMesh.localNormals.GetNativeArray(), + vertexToTriangles = editMesh.vertexToTriangles, + + pointWorldPositions = pointWorldPositions, + dispPointList = dispPointList.AsParallelWriter(), + }; + jobHandle = job.Schedule(vcnt, 16, jobHandle); + + // 距離ソート + var job2 = new SortDispPointJob() + { + dispPointList = dispPointList, + }; + jobHandle = job2.Schedule(jobHandle); + + return jobHandle; + } + + [BurstCompile] + struct CreateDispPointListJob : IJobParallelFor + { + public bool through; + public float4x4 LtoW; + public bool showAll; + + public float3 cameraPosition; + public float3 cameraDirection; + public float4x4 cameraProjectionMatrix; + public float4x4 worldToCameraMatrix; + public float cameraAspectRatio; + + public bool useBrush; + public float3 brushPosition; + public float brushSize; + + [Unity.Collections.ReadOnly] + public NativeArray localPositions; + [Unity.Collections.ReadOnly] + public NativeArray localNormals; + [Unity.Collections.ReadOnly] + public NativeArray> vertexToTriangles; + + [Unity.Collections.WriteOnly] + public NativeArray pointWorldPositions; + [Unity.Collections.WriteOnly] + public NativeList.ParallelWriter dispPointList; + + public void Execute(int vindex) + { + // ワールド座標 + var lpos = localPositions[vindex]; + var wpos = math.transform(LtoW, lpos); + pointWorldPositions[vindex] = wpos; + + // カメラ距離 + float dist = math.distance(cameraPosition, wpos); + + // 表示選別 + bool show; + if (showAll) + { + show = true; + } + else + { + // 頂点がトライアングルに属さない場合は無条件で表示する + if (vertexToTriangles[vindex].Length == 0) + show = true; + else + { + // トライアングルに属する頂点は法線が画面に向いているもののみ表示 + show = math.dot(cameraDirection, localNormals[vindex]) < 0.0f; + } + } + + if (show) + { + var flag = new BitField32(); + + // ブラシ範囲内に存在するか判定 + if (useBrush) + { + if (through) + { + // 透過モード + // 射影変換 + var cpos = math.mul(worldToCameraMatrix, new float4(wpos, 1)); + var vpos = math.mul(cameraProjectionMatrix, new float4(cpos.xyz, 1)); + vpos /= vpos.w; // wで割る必要あり + + // ブラシはアスペクト比を考慮した楕円で判定する必要あり + // brushPositionはviewport座標を指す + float2 v = vpos.xy - brushPosition.xy; + v.x *= cameraAspectRatio; + var bdist = math.length(v); + if (bdist <= brushSize) + flag.SetBits(PointFlag_Selecting, true); + } + else + { + // サーフェス選択モード + var bdist = math.distance(brushPosition, wpos); + if (bdist <= brushSize) + flag.SetBits(PointFlag_Selecting, true); + } + } + + dispPointList.AddNoResize(new Point() { vindex = vindex, distance = dist, flag = flag }); + } + } + } + + [BurstCompile] + struct SortDispPointJob : IJob + { + public NativeList dispPointList; + + public void Execute() + { + if (dispPointList.Length > 1) + dispPointList.Sort(); + } + } + + /// + /// 渡されたpointListをカメラからの距離の降順にソートして返す + /// + /// + /// + /// positionをワールド座標変換するマトリックス + /// カメラワールド座標 + /// + internal static void CalcPointCameraDistance(NativeArray positions, int positonOffset, float4x4 LtoW, float3 camPos, NativeList pointList) + { + // ポイントのカメラからの距離を求める + int cnt = pointList.Length; + if (cnt <= 1) + return; + + var job = new CalcCameraDistanceJob() + { + LtoW = LtoW, + cameraPosition = camPos, + positions = positions, + pointList = pointList, + positionOffset = positonOffset, + }; + job.Run(cnt); + + // 距離ソート + var job2 = new SortDispPointJob() + { + dispPointList = pointList, + }; + job2.Run(); + } + + + [BurstCompile] + struct CalcCameraDistanceJob : IJobParallelFor + { + public float4x4 LtoW; + + public float3 cameraPosition; + + [Unity.Collections.ReadOnly] + public NativeArray positions; + + [NativeDisableParallelForRestriction] + public NativeList pointList; + public int positionOffset; + + public void Execute(int index) + { + var point = pointList[index]; + + // ワールド座標 + var lpos = positions[positionOffset + point.vindex]; + var wpos = math.transform(LtoW, lpos); + + // カメラ距離 + float dist = math.distance(cameraPosition, wpos); + point.distance = dist; + + pointList[index] = point; + } + } + + /// + /// 選択中ポイントに属性を付与する + /// + /// + static void ApplyPaint(ClothPainterWindowData windata, NativeList applyPointList) + { + int cnt = applyPointList.Length; + for (int i = 0; i < cnt; i++) + { + var point = applyPointList[i]; + if (point.flag.IsSet(PointFlag_Selecting) == false) + continue; + + var attr = selectionData.attributes[point.vindex]; + bool change = false; + + switch (paintMode) + { + case PaintMode.Attribute: + // 移動/固定 + if (windata.editAttribute == 0 && attr.IsMove() == false) + { + attr.SetFlag(VertexAttribute.Flag_Move, true); + attr.SetFlag(VertexAttribute.Flag_Fixed, false); + //attr.SetFlag(VertexAttribute.Flag_Ignore, false); + change = true; + } + else if (windata.editAttribute == 1 && attr.IsFixed() == false) + { + attr.SetFlag(VertexAttribute.Flag_Move, false); + attr.SetFlag(VertexAttribute.Flag_Fixed, true); + //attr.SetFlag(VertexAttribute.Flag_Ignore, false); + change = true; + } + //else if (windata.editAttribute == 2 && attr.IsIgnore() == false) + //{ + // attr.SetFlag(VertexAttribute.Flag_Move, false); + // attr.SetFlag(VertexAttribute.Flag_Fixed, false); + // attr.SetFlag(VertexAttribute.Flag_Ignore, true); + // change = true; + //} + else if (windata.editAttribute == 3 && attr.IsInvalid() == false) + { + attr.SetFlag(VertexAttribute.Flag_Move, false); + attr.SetFlag(VertexAttribute.Flag_Fixed, false); + //attr.SetFlag(VertexAttribute.Flag_Ignore, false); + change = true; + } + + break; + case PaintMode.Motion: + // MaxDistance/Backstop + if (windata.editMotion == 0 && attr.IsMotion() == false) + { + attr.SetFlag(VertexAttribute.Flag_InvalidMotion, false); + change = true; + } + else if (windata.editMotion == 1 && attr.IsMotion()) + { + attr.SetFlag(VertexAttribute.Flag_InvalidMotion, true); + change = true; + } + break; + } + + if (change) + selectionData.attributes[point.vindex] = attr; + } + } + + /// + /// セレクションデータをシリアライズする + /// + static void ApplySelectionData() + { + // セレクションデータデータをシリアライズ化する + selectionData.userEdit = true; // ユーザー編集フラグを立てる + if (clothEditor != null) + clothEditor.ApplyClothPainter(selectionData); + + // Undo/Redoの状態を切り替えるためセレクションデータのクローンを作成して切り替える + selectionData = selectionData.Clone(); + } + + /// + /// 塗りつぶし + /// + /// + static void Fill(ClothPainterWindowData windata) + { + // 塗りつぶし用のポイントデータを作成する + //int vcnt = editMesh.VertexCount; + int vcnt = editMeshContainer.shareVirtualMesh.VertexCount; + using var fillDispPointList = new NativeList(vcnt, Allocator.TempJob); + BitField32 flag = new(); + flag.SetBits(PointFlag_Selecting, true); + for (int i = 0; i < vcnt; i++) + { + var p = new Point() + { + vindex = i, + distance = 0, + flag = flag, + }; + fillDispPointList.Add(p); + } + + // セレクションデータへ反映 + ApplyPaint(windata, fillDispPointList); + + // シリアライズ + ApplySelectionData(); + } + + + static void DoWindow(int unusedWindowID) + { + var windata = ScriptableSingleton.instance; + + //Debug.Log(windata.windowRect); + + //float lineHight = EditorGUIUtility.singleLineHeight; + + // ポイントサイズスライダー + const float sliderLableWidth = 80; + const float sliderWidth = 180; + using (var h = new EditorGUILayout.HorizontalScope()) + { + EditorGUILayout.LabelField("Point Size", GUILayout.Width(sliderLableWidth)); + windata.drawPointSize = EditorGUILayout.Slider(GUIContent.none, windata.drawPointSize, 0.001f, 0.1f, GUILayout.Width(sliderWidth)); + } + + // ブラシサイズスライダー + using (var h = new EditorGUILayout.HorizontalScope()) + { + if (windata.through) + { + EditorGUILayout.LabelField("Brush Size T", GUILayout.Width(sliderLableWidth)); + windata.brushSizeThrough = EditorGUILayout.Slider(GUIContent.none, windata.brushSizeThrough, 0.01f, 0.3f, GUILayout.Width(sliderWidth)); + } + else + { + EditorGUILayout.LabelField("Brush Size", GUILayout.Width(sliderLableWidth)); + windata.brushSize = EditorGUILayout.Slider(GUIContent.none, windata.brushSize, 0.001f, 0.2f, GUILayout.Width(sliderWidth)); + } + } + + EditorGUILayout.Space(); + + const float toggleLableWidth = 80; + const float toggleButtonWidth = 30; + using (var h = new EditorGUILayout.HorizontalScope()) + { + // 形状表示 + EditorGUILayout.LabelField("Shape", GUILayout.Width(toggleLableWidth)); + windata.showShape = EditorGUILayout.Toggle(GUIContent.none, windata.showShape, GUILayout.Width(toggleButtonWidth)); + + // 全表示 + EditorGUILayout.LabelField("Culling", GUILayout.Width(toggleLableWidth)); + windata.backFaceCulling = EditorGUILayout.Toggle(GUIContent.none, windata.backFaceCulling, GUILayout.Width(toggleButtonWidth)); + } + + using (var h = new EditorGUILayout.HorizontalScope()) + { + // Zテスト + EditorGUILayout.LabelField("Z-Test", GUILayout.Width(toggleLableWidth)); + windata.zTest = EditorGUILayout.Toggle(GUIContent.none, windata.zTest, GUILayout.Width(toggleButtonWidth)); + + // 透過 + EditorGUILayout.LabelField("Through", GUILayout.Width(toggleLableWidth)); + windata.through = EditorGUILayout.Toggle(GUIContent.none, windata.through, GUILayout.Width(toggleButtonWidth)); + } + + // 属性ボタン + EditorGUILayout.Space(); + EditorGUILayout.LabelField("Paint Attribute"); + Color bcol = GUI.backgroundColor; + using (new EditorGUILayout.HorizontalScope()) + { + if (paintMode == PaintMode.Attribute) + { + // Move/Fixed + int nowAttr = windata.editAttribute; + for (int i = 0; i < 4; i++) + { + // !現在Ignoreはオミット + if (i == 2) + continue; + + Color col = Color.black; + string title = string.Empty; + switch (i) + { + case 0: // move + col = Color.green; + title = "Move"; + break; + case 1: // fixed + col = Color.red; + title = "Fixed"; + break; + case 2: // ignore + col = Color.blue; + title = "Ignore"; + break; + case 3: // invalid + col = Color.gray; + title = "Invalid"; + break; + } + GUI.backgroundColor = i == nowAttr ? col : Color.gray; + bool ret = GUILayout.Toggle(i == nowAttr, title, EditorStyles.miniButton); + if (ret) + { + nowAttr = i; + } + } + windata.editAttribute = nowAttr; + } + else if (paintMode == PaintMode.Motion) + { + // MaxDistance/Backstop + int nowAttr = windata.editMotion; + for (int i = 0; i < 2; i++) + { + // カラー + var col = i == 0 ? Color.cyan : Color.red; + GUI.backgroundColor = i == nowAttr ? col : Color.gray; + bool ret = GUILayout.Toggle(i == nowAttr, i == 0 ? "Valid" : "Invalid", EditorStyles.miniButton); + if (ret) + { + nowAttr = i; + } + } + windata.editMotion = nowAttr; + } + } + GUI.backgroundColor = bcol; + + // 適用/キャンセルボタン + EditorGUILayout.Space(); + using (new EditorGUILayout.HorizontalScope()) + { + // 塗りつぶしボタン + if (GUILayout.Button("Fill", GUILayout.Width(70))) + { + Fill(windata); + } + + GUILayout.FlexibleSpace(); + + // ペイント終了ボタン + if (GUILayout.Button("Exit")) + { + // 初期化データの保存確認 + ClothEditorManager.ApplyInitData(cloth, global: true); + + // ペイント終了フラグ + cloth = null; + + // この編集によりセレクションデータに変更があった場合はProxyMeshをリビルドする + if (initSelectionData.Compare(selectionData) == false) + { + Develop.DebugLog($"Change selection data!"); + if (clothEditor != null) + clothEditor.UpdateEditMesh(); + } + + ExitPaint(); + } + EditorGUILayout.Space(); + } + + GUI.DragWindow(); + } + } + + //============================================================================================= + /// + /// ペイントウインドウの保持データ + /// ScriptableSingletonを利用することによりエディタ終了時までデータを保持できる + /// + public class ClothPainterWindowData : ScriptableSingleton + { + /// + /// ウインドウの位置とサイズ + /// + public Rect windowRect = new Rect(100, 100, ClothPainter.WindowWidth, ClothPainter.WindowHeight); + + /// + /// 表示ポイントサイズ + /// + public float drawPointSize = 0.02f; + + /// + /// ブラシサイズ + /// + public float brushSize = 0.05f; + + /// + /// ブラシサイズ(透過モード時) + /// シーンカメラ垂直サイズの(%) + /// + public float brushSizeThrough = 0.1f; + + /// + /// 裏面カリング + /// + public bool backFaceCulling = true; + + /// + /// 形状を表示 + /// + public bool showShape = true; + + /// + /// Zテスト + /// + public bool zTest = false; + + /// + /// 透過モード + /// + public bool through = false; + + /// + /// 現在アクティブなポイント属性(0=Move/1=Fixed/2=Ignore/3=Invalid) + /// VertexAttributeとは異なるので注意! + /// + public int editAttribute = 0; + + /// + /// 現在アクティブなモーション制約(0=Valid, 1=Invalid) + /// + public int editMotion = 0; + } +} diff --git a/Assets/MagicaCloth2/Scripts/Editor/Cloth/ClothPainter.cs.meta b/Assets/MagicaCloth2/Scripts/Editor/Cloth/ClothPainter.cs.meta new file mode 100644 index 00000000..d070b7cf --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Editor/Cloth/ClothPainter.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 3d9ac74274185454f8b6f05bc4f2825e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Editor/Cloth/ClothPainter.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Editor/Cloth/ClothPresetUtility.cs b/Assets/MagicaCloth2/Scripts/Editor/Cloth/ClothPresetUtility.cs new file mode 100644 index 00000000..72aaa673 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Editor/Cloth/ClothPresetUtility.cs @@ -0,0 +1,232 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using System.Collections.Generic; +using System.IO; +using UnityEditor; +using UnityEngine; + +namespace MagicaCloth2 +{ + /// + /// プリセットに関するユーティリティ + /// + public static class ClothPresetUtility + { + const string prefix = "MC2_Preset"; + const string configName = "MC2 preset folder"; + + public static void DrawPresetButton(MagicaCloth cloth, ClothSerializeData sdata) + { + bool save = false; + bool load = false; + using (var horizontalScope = new GUILayout.HorizontalScope()) + { + EditorGUILayout.LabelField("Parameters", EditorStyles.boldLabel); + + GUI.backgroundColor = Color.green; + if (EditorGUILayout.DropdownButton(new GUIContent("Preset"), FocusType.Keyboard, GUILayout.Width(70), GUILayout.Height(16))) + { + CreatePresetPopupMenu(cloth, sdata); + GUI.backgroundColor = Color.white; + //GUIUtility.ExitGUI(); + } + GUI.backgroundColor = Color.white; + + if (GUILayout.Button("Save", GUILayout.Width(40), GUILayout.Height(16))) + { + //SavePreset(sdata); + //GUIUtility.ExitGUI(); + save = true; + } + if (GUILayout.Button("Load", GUILayout.Width(40), GUILayout.Height(16))) + { + //LoadPreset(cloth, sdata); + //GUIUtility.ExitGUI(); + load = true; + } + } + if (save) + SavePreset(sdata); + if (load) + LoadPreset(cloth, sdata); + } + + static string GetComponentTypeName(ClothSerializeData sdata) + { + //if (sdata.clothType == ClothProcess.ClothType.BoneCloth) + // return prefix + "BoneCloth"; + //else if (sdata.clothType == ClothProcess.ClothType.MeshCloth) + // return prefix + "MeshCloth"; + //return prefix; + + return prefix; + } + + + class PresetInfo + { + public string presetPath; + public string presetName; + public TextAsset text; + } + + private static void CreatePresetPopupMenu(MagicaCloth cloth, ClothSerializeData sdata) + { + var guidArray = AssetDatabase.FindAssets($"{prefix} t:{nameof(TextAsset)}"); + if (guidArray == null) + return; + + Dictionary> dict = new Dictionary>(); + foreach (var guid in guidArray) + { + var filePath = AssetDatabase.GUIDToAssetPath(guid); + + // json確認 + if (filePath.EndsWith(".json") == false) + continue; + + var text = AssetDatabase.LoadAssetAtPath(filePath); + if (text) + { + var info = new PresetInfo(); + info.presetPath = filePath; + var fname = Path.GetFileNameWithoutExtension(filePath); + fname = fname.Replace(prefix, ""); + if (fname.StartsWith("_")) + fname = fname.Remove(0, 1); // 頭の_は削除する + info.presetName = fname; + info.text = text; + + // ディレクトリごとに記録する + var dirName = Path.GetDirectoryName(filePath); + if (dict.ContainsKey(dirName) == false) + { + dict.Add(dirName, new List()); + } + dict[dirName].Add(info); + } + } + + // ポップアップメニューの作成 + // ディレクトリごとにセパレータで分けて表示する + var menu = new GenericMenu(); + int line = 0; + foreach (var kv in dict) + { + if (line > 0) + { + menu.AddSeparator(""); + } + foreach (var info in kv.Value) + { + var textAsset = info.text; + var presetName = info.presetName; + var presetPath = info.presetPath; + menu.AddItem(new GUIContent(presetName), false, () => + { + // load + Develop.Log("Load preset file:" + presetPath); + if (sdata.ImportJson(textAsset.text)) + Develop.Log("Completed."); + else + Develop.LogError("Preset load error!"); + + LoadPresetFinish(cloth); + }); + } + line++; + } + menu.ShowAsContext(); + } + + /// + /// プリセットファイル保存 + /// + /// + private static void SavePreset(ClothSerializeData sdata) + { + // フォルダを読み込み + string folder = EditorUserSettings.GetConfigValue(configName); + + // 接頭語 + string presetTypeName = GetComponentTypeName(sdata); + + // 保存ダイアログ + string path = EditorUtility.SaveFilePanelInProject( + "Save Preset", + $"{presetTypeName}_(name)", + "json", + "Enter a name for the preset json.", + folder + ); + if (string.IsNullOrEmpty(path)) + return; + + // フォルダを記録 + folder = Path.GetDirectoryName(path); + EditorUserSettings.SetConfigValue(configName, folder); + + Develop.Log("Save preset file:" + path); + + // export json + string json = sdata.ExportJson(); + + // save + File.WriteAllText(path, json); + + AssetDatabase.Refresh(); + + Develop.Log("Completed."); + } + + /// + /// プリセットファイル読み込み + /// + /// + private static void LoadPreset(MagicaCloth cloth, ClothSerializeData sdata) + { + // フォルダを読み込み + string folder = EditorUserSettings.GetConfigValue(configName); + + // 読み込みダイアログ + string path = EditorUtility.OpenFilePanel("Load Preset", folder, "json"); + if (string.IsNullOrEmpty(path)) + return; + + // フォルダを記録 + folder = Path.GetDirectoryName(path); + EditorUserSettings.SetConfigValue(configName, folder); + + // import json + Develop.Log("Load preset file:" + path); + string json = File.ReadAllText(path); + + // load + if (sdata.ImportJson(json)) + Develop.Log("Completed."); + else + Develop.LogError("Preset load error!"); + + LoadPresetFinish(cloth); + } + + /// + /// プリセットファイル読み込み後処理 + /// + /// + private static void LoadPresetFinish(MagicaCloth cloth) + { + if (EditorApplication.isPlaying) + { + // パラメータ更新通知 + cloth.SetParameterChange(); + } + else + { + // シリアライズ変更通知 + EditorUtility.SetDirty(cloth); + } + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Editor/Cloth/ClothPresetUtility.cs.meta b/Assets/MagicaCloth2/Scripts/Editor/Cloth/ClothPresetUtility.cs.meta new file mode 100644 index 00000000..dbc034a9 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Editor/Cloth/ClothPresetUtility.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 92b2c2c365167f34e90c74c01638b1eb +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Editor/Cloth/ClothPresetUtility.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Editor/Cloth/MagicaCapsuleColliderEditor.cs b/Assets/MagicaCloth2/Scripts/Editor/Cloth/MagicaCapsuleColliderEditor.cs new file mode 100644 index 00000000..488c8256 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Editor/Cloth/MagicaCapsuleColliderEditor.cs @@ -0,0 +1,118 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using UnityEditor; +using UnityEngine; + +namespace MagicaCloth2 +{ + /// + /// CapsuleColliderのエディタ拡張 + /// + [CustomEditor(typeof(MagicaCapsuleCollider))] + [CanEditMultipleObjects] + public class MagicaCapsuleColliderEditor : MagicaEditorBase + { + public override void OnInspectorGUI() + { + var scr = target as MagicaCapsuleCollider; + const string undoName = "CapsuleCollider"; + + serializedObject.Update(); + Undo.RecordObject(scr, undoName); + + // separation + var separationValue = serializedObject.FindProperty("radiusSeparation"); + + // direction + var directionValue = serializedObject.FindProperty("direction"); + EditorGUILayout.PropertyField(directionValue); + + // reverse direction + EditorGUILayout.PropertyField(serializedObject.FindProperty("reverseDirection")); + + // aligned on center + var alignedOnCenterValue = serializedObject.FindProperty("alignedOnCenter"); + EditorGUILayout.PropertyField(alignedOnCenterValue); + + var sizeValue = serializedObject.FindProperty("size"); + var size = sizeValue.vector3Value; + + // マルチ選択時について + // CapsuleColliderではEditorGUI.showMixedValueは設定しない + // EditorGUI.showMixedValueを設定すると異なる値の場合は「ー」で表記されるようになるが、 + // カプセルコライダーでは1つのVector3に3つの異なるスライダーを割り当てているため、 + // 各スライダーの値が同じ場合でも「ー」表記になってしまう + // そうならないようにアクティブなコンポーネントの数値のみを表示するように、showMixedValueは常にfalseにしておく + + // length + using (var check = new EditorGUI.ChangeCheckScope()) + { + var newSize = EditorGUILayout.Slider("Length", size.z, 0.0f, 2.0f); + ApplyMultiSelection(check.changed, undoName, x => x.SetSizeZ(newSize)); + } + + // radius + float lineHight = EditorGUIUtility.singleLineHeight; + + // start + { + Rect r = EditorGUILayout.GetControlRect(); + + // ラベルを描画 + var positionA = EditorGUI.PrefixLabel(r, GUIUtility.GetControlID(FocusType.Passive), new GUIContent(scr.radiusSeparation ? "Start Radius" : "Radius")); + + // 矩形を計算 + float w = positionA.width; + var buttonRect = new Rect(positionA.x + w - 30, r.y, 30, lineHight); + var sliderRect = new Rect(positionA.x, r.y, Mathf.Max(w - 35, 0), lineHight); + + // Slider + using (var check = new EditorGUI.ChangeCheckScope()) + { + var newSize = EditorGUI.Slider(sliderRect, size.x, 0.001f, 0.5f); + ApplyMultiSelection(check.changed, undoName, x => x.SetSizeX(newSize)); + } + + // 分割ボタン + if (GUI.Button(buttonRect, scr.radiusSeparation ? "X" : "S")) + { + // 切り替え + separationValue.boolValue = !separationValue.boolValue; + } + } + + // end + if (separationValue.boolValue) + { + Rect r = EditorGUILayout.GetControlRect(); + + // ラベルを描画 + var positionA = EditorGUI.PrefixLabel(r, GUIUtility.GetControlID(FocusType.Passive), new GUIContent("End Radius")); + + // 矩形を計算 + float w = positionA.width; + var sliderRect = new Rect(positionA.x, r.y, Mathf.Max(w - 35, 0), lineHight); + + // Slider + using (var check = new EditorGUI.ChangeCheckScope()) + { + var newSize = EditorGUI.Slider(sliderRect, size.y, 0.001f, 0.5f); + ApplyMultiSelection(check.changed, undoName, x => x.SetSizeY(newSize)); + } + } + + // center + EditorGUILayout.PropertyField(serializedObject.FindProperty("center")); + + // Symmetry + EditorGUILayout.Space(); + var symmetryModeProperty = serializedObject.FindProperty("symmetryMode"); + EditorGUILayout.PropertyField(symmetryModeProperty); + if (symmetryModeProperty.enumValueIndex >= (int)ColliderSymmetryMode.AutomaticTarget) + EditorGUILayout.PropertyField(serializedObject.FindProperty("symmetryTarget")); + + serializedObject.ApplyModifiedProperties(); + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Editor/Cloth/MagicaCapsuleColliderEditor.cs.meta b/Assets/MagicaCloth2/Scripts/Editor/Cloth/MagicaCapsuleColliderEditor.cs.meta new file mode 100644 index 00000000..b53a0f5d --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Editor/Cloth/MagicaCapsuleColliderEditor.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 89239f89e837c394ca8ebe2515680a5e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Editor/Cloth/MagicaCapsuleColliderEditor.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Editor/Cloth/MagicaClothEditor.cs b/Assets/MagicaCloth2/Scripts/Editor/Cloth/MagicaClothEditor.cs new file mode 100644 index 00000000..6a0e6ec4 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Editor/Cloth/MagicaClothEditor.cs @@ -0,0 +1,951 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using UnityEditor; +using UnityEngine; + +namespace MagicaCloth2 +{ + /// + /// MagicaClothコンポーネントのエディタ拡張 + /// + [CustomEditor(typeof(MagicaCloth))] + [CanEditMultipleObjects] + public class MagicaClothEditor : MagicaEditorBase + { + + protected void OnEnable() + { + //Debug.Log("MagicaClothEditor.OnEnable"); + ClothEditorManager.OnEditMeshBuildComplete += OnEditMeshBuildComplete; + } + + protected void OnDisable() + { + //Debug.Log("MagicaClothEditor.OnDisable"); + ClothEditorManager.OnEditMeshBuildComplete -= OnEditMeshBuildComplete; + ClothPainter.ExitPaint(); + } + + //========================================================================================= + int oldAcitve = -1; + + //========================================================================================= + /// + /// 編集用のセレクションデータを取得する + /// + /// + /// + /// + public SelectionData GetSelectionData(MagicaCloth cloth, VirtualMesh editMesh) + { + // すでにセレクションデータが存在し、かつユーザー編集データならばコンバートする + var selectionData = ClothEditorManager.CreateAutoSelectionData(cloth, cloth.SerializeData, editMesh); + if (cloth.GetSerializeData2().selectionData != null && cloth.GetSerializeData2().selectionData.userEdit) + { + //Debug.Log($"セレクションデータコンバート!"); + selectionData.ConvertFrom(cloth.GetSerializeData2().selectionData); + selectionData.userEdit = true; + } + + return selectionData; + } + + /// + /// エディットメッシュの構築完了通知(成否問わず) + /// + void OnEditMeshBuildComplete() + { + //Debug.Log($"MagicaClothInspector. OnEditMeshBuildComplete."); + Repaint(); + } + + /// + /// インスペクターGUI + /// + public override void OnInspectorGUI() + { + var cloth = target as MagicaCloth; + + // 状態 + DispVersion(); + DispStatus(); + DispProxyMesh(); + + // 設定 + serializedObject.Update(); + Undo.RecordObject(cloth, "MagicaCloth2"); + EditorGUILayout.Space(); + ClothMainInspector(); + EditorGUILayout.Space(); + EditorGUILayout.Space(); + EditorGUILayout.Space(); + EditorGUILayout.Space(); + EditorGUILayout.Space(); + ClothParameterInspector(); + EditorGUILayout.Space(); + EditorGUILayout.Space(); + GizmoInspector(); + EditorGUILayout.Space(); + ClothPreBuildInspector(); + serializedObject.ApplyModifiedProperties(); + + //DrawDefaultInspector(); + + // アクティブが変更された場合は編集メッシュを再構築する + int nowActive = cloth.isActiveAndEnabled ? 1 : 0; + if (nowActive != oldAcitve) + { + oldAcitve = nowActive; + + // ただしコンポーネントがProjectビューで選択されている場合は再構築しない + // Hierarchyおよびプレハブモードはこれに該当しない +#if UNITY_6000_3_OR_NEWER + bool inProject = AssetDatabase.Contains(cloth.gameObject.GetEntityId()); +#else + bool inProject = AssetDatabase.Contains(cloth.gameObject.GetInstanceID()); +#endif + if (inProject == false) + { + //Develop.Log($"[{cloth.name}] rebuild. active:{nowActive}, inProject:{inProject}"); + ClothEditorManager.RegisterComponent(cloth, nowActive > 0 ? GizmoType.Active : 0, true); + } + } + } + + /// + /// クロスペイントの適用 + /// + /// + internal void ApplyClothPainter(SelectionData selectionData) + { + if (selectionData == null || selectionData.IsValid() == false) + return; + + var cloth = target as MagicaCloth; + + // セレクションデータ格納 + ClothEditorManager.ApplySelectionData(cloth, selectionData); + } + + /// + /// クロスペイントの変更による編集メッシュの再構築 + /// + internal void UpdateEditMesh() + { + var cloth = target as MagicaCloth; + + // 編集用メッシュの再構築 + ClothEditorManager.RegisterComponent(cloth, GizmoType.Active, true); // 強制更新 + } + + //========================================================================================= + void DispVersion() + { + EditorGUILayout.LabelField($"Version {AboutMenu.MagicaClothVersion}"); + } + + void DispStatus() + { + var cloth = target as MagicaCloth; + + if (EditorApplication.isPlaying) + { + StaticStringBuilder.Clear(); + StaticStringBuilder.AppendLine("[State]"); + StaticStringBuilder.Append(cloth.Process.IsState(ClothProcess.State_UsePreBuild) ? "Pre-Build Construction" : "Runtime Construction"); + DispClothStatus(StaticStringBuilder.ToString(), cloth.Process.Result, true); + } + else + { + var result = ClothEditorManager.GetResultCode(cloth); + var preBuildData = cloth.GetSerializeData2().preBuildData; + if (preBuildData.enabled) + { + // pre-build + if (result.IsError() == false) + result = preBuildData.DataValidate(); + DispClothStatus("[Pre-Build Construction]", result, false); + } + else + { + // runtime + DispClothStatus("[Runtime Construction]", result, true); + } + } + } + + void DispClothStatus(string title, ResultCode result, bool dispWarning) + { + StaticStringBuilder.Clear(); + StaticStringBuilder.AppendLine(title); + + // normal / error + MessageType mtype = MessageType.Info; + if (result.IsError()) + mtype = MessageType.Error; + var infoMessage = result.GetResultInformation(); + if (infoMessage != null) + { + StaticStringBuilder.AppendLine(result.GetResultString()); + StaticStringBuilder.AppendLine(infoMessage); + } + else + { + StaticStringBuilder.AppendLine(result.GetResultString()); + } + EditorGUILayout.HelpBox(StaticStringBuilder.ToString(), mtype); + + // warning + if (dispWarning && result.IsWarning()) + { + mtype = MessageType.Warning; + infoMessage = result.GetWarningInformation(); + if (infoMessage != null) + EditorGUILayout.HelpBox($"{result.GetWarningString()}\n{infoMessage}", mtype); + else + EditorGUILayout.HelpBox(result.GetWarningString(), mtype); + } + } + + void DispProxyMesh() + { + var cloth = target as MagicaCloth; + + VirtualMeshContainer cmesh; + if (EditorApplication.isPlaying) + { + cmesh = cloth.Process?.ProxyMeshContainer; + } + else + { + cmesh = ClothEditorManager.GetEditMeshContainer(cloth); + } + if (cmesh == null || cmesh.shareVirtualMesh == null) + return; + + var vmesh = cmesh.shareVirtualMesh; + + StaticStringBuilder.Clear(); + + // 初期化データ + StaticStringBuilder.AppendLine("[Init Data]"); + int initVersion = cloth.GetSerializeData2().initData?.initVersion ?? 0; + if (initVersion > 0) + { + StaticStringBuilder.Append($"v{initVersion}: "); + } + if (EditorApplication.isPlaying) + { + StaticStringBuilder.Append($"{cloth.Process.InitDataResult.GetResultString()}"); + } + else + { + StaticStringBuilder.Append($"{cloth.GetSerializeData2().initData.HasData()}"); + } + + // Proxyメッシュ + StaticStringBuilder.AppendLine(); + if (EditorApplication.isPlaying) + StaticStringBuilder.AppendLine("[Proxy Mesh]"); + else + StaticStringBuilder.AppendLine("[Edit Mesh]"); + if (EditorApplication.isPlaying) + { + StaticStringBuilder.AppendLine($"Camera Visible: {!cloth.Process.IsCameraCullingInvisible()}"); + StaticStringBuilder.AppendLine($"Distance Visible: {!cloth.Process.IsDistanceCullingInvisible()}"); + } + StaticStringBuilder.AppendLine($"Vertex: {vmesh.VertexCount}"); + StaticStringBuilder.AppendLine($"Edge: {vmesh.EdgeCount}"); + StaticStringBuilder.AppendLine($"Triangle: {vmesh.TriangleCount}"); + StaticStringBuilder.AppendLine($"SkinBoneCount: {vmesh.SkinBoneCount}"); + StaticStringBuilder.Append($"TransformCount: {cmesh.GetTransformCount()}"); + + + EditorGUILayout.HelpBox(StaticStringBuilder.ToString(), MessageType.Info); + } + + + void ClothMainInspector() + { + var cloth = target as MagicaCloth; + var clothType = cloth.SerializeData.clothType; + bool isBoneSpring = clothType == ClothProcess.ClothType.BoneSpring; + + bool runtime = EditorApplication.isPlaying; + + // 同期状態 + bool sync = EditorApplication.isPlaying && cloth.SyncPartnerCloth != null; + + EditorGUILayout.LabelField("Main", EditorStyles.boldLabel); + + // Cloth + { + var clothTypeProperty = serializedObject.FindProperty("serializeData.clothType"); + + using (new EditorGUI.DisabledScope(runtime)) + { + EditorGUILayout.PropertyField(clothTypeProperty, new GUIContent("Cloth Type")); + } + + var paintMode = serializedObject.FindProperty("serializeData.paintMode"); + + using (new EditorGUI.IndentLevelScope()) + { + if (clothType == ClothProcess.ClothType.BoneCloth) + { + EditorGUILayout.PropertyField(serializedObject.FindProperty("serializeData.rootBones")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("serializeData.connectionMode")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("serializeData.rootRotation")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("serializeData.rotationalInterpolation")); + } + else if (clothType == ClothProcess.ClothType.BoneSpring) + { + EditorGUILayout.PropertyField(serializedObject.FindProperty("serializeData.rootBones")); + // BoneSpringでは接続モードは指定させない。内部ではLineで固定される。 + using (new EditorGUILayout.HorizontalScope()) + { + EditorGUILayout.LabelField("ConnectionMode"); + EditorGUILayout.LabelField("[Line]"); + } + EditorGUILayout.PropertyField(serializedObject.FindProperty("serializeData.rootRotation")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("serializeData.rotationalInterpolation")); + } + else if (clothType == ClothProcess.ClothType.MeshCloth) + { + EditorGUILayout.PropertyField(serializedObject.FindProperty("serializeData.sourceRenderers")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("serializeData.meshWriteMode")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("serializeData.reductionSetting")); + } + + EditorGUILayout.Space(); + if (sync == false) + { + EditorGUILayout.PropertyField(serializedObject.FindProperty("serializeData.updateMode")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("serializeData.disableMode")); + } + else + { + // 同期中は操作不可 + using (new EditorGUI.DisabledScope(true)) + { + using (new EditorGUILayout.HorizontalScope()) + { + EditorGUILayout.LabelField("Update Mode"); + EditorGUILayout.LabelField("(Synchronizing)"); + } + using (new EditorGUILayout.HorizontalScope()) + { + EditorGUILayout.LabelField("Disable Mode"); + EditorGUILayout.LabelField("(Synchronizing)"); + } + } + } + EditorGUILayout.PropertyField(serializedObject.FindProperty("serializeData.animationPoseRatio")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("serializeData.blendWeight")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("serializeData.normalAxis")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("serializeData.normalAlignmentSetting.alignmentMode"), new GUIContent("Normal Alignment")); + if (cloth.SerializeData.normalAlignmentSetting.alignmentMode == NormalAlignmentSettings.AlignmentMode.Transform) + { + EditorGUILayout.PropertyField(serializedObject.FindProperty("serializeData.normalAlignmentSetting.adjustmentTransform")); + } + + if (clothType == ClothProcess.ClothType.MeshCloth) + { + EditorGUILayout.Space(); + EditorGUILayout.PropertyField(paintMode); + if (paintMode.enumValueIndex != 0) + { + EditorGUILayout.PropertyField(serializedObject.FindProperty("serializeData.paintMaps")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("serializeData.paintMapUvChannel")); + } + } + } + + // ペイントボタン + if (paintMode.enumValueIndex == 0) + { + EditorGUILayout.Space(); + PaintButton(ClothPainter.PaintMode.Attribute); + } + else + EditorGUILayout.Space(); + } + + // Custom Skinning + if (isBoneSpring == false) + { + Foldout("Custom Skinning", serializedObject.FindProperty("serializeData.customSkinningSetting.enable"), null, () => + { + EditorGUILayout.PropertyField(serializedObject.FindProperty("serializeData.customSkinningSetting.skinningBones")); + }); + } + + // Culling + Foldout("Culling", null, () => + { + if (sync == false) + { + EditorGUILayout.PropertyField(serializedObject.FindProperty("serializeData.cullingSettings.cameraCullingMode")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("serializeData.cullingSettings.cameraCullingMethod")); + if (cloth.SerializeData.cullingSettings.cameraCullingMethod == CullingSettings.CameraCullingMethod.ManualRenderer) + { + EditorGUILayout.PropertyField(serializedObject.FindProperty("serializeData.cullingSettings.cameraCullingRenderers")); + } + EditorGUILayout.Space(); + EditorGUILayout.PropertyField(serializedObject.FindProperty("serializeData.cullingSettings.distanceCullingLength")); + using (new EditorGUI.DisabledScope(cloth.SerializeData.cullingSettings.distanceCullingLength.use == false)) + { + EditorGUILayout.PropertyField(serializedObject.FindProperty("serializeData.cullingSettings.distanceCullingFadeRatio")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("serializeData.cullingSettings.distanceCullingReferenceObject")); + EditorGUILayout.HelpBox("If Reference Object is [None], the main camera is referred.", MessageType.None); + } + } + else + { + // 同期中は操作不可 + using (new EditorGUI.DisabledScope(true)) + { + using (new EditorGUILayout.HorizontalScope()) + { + EditorGUILayout.LabelField("Camera Culling Mode"); + EditorGUILayout.LabelField("(Synchronizing)"); + } + using (new EditorGUILayout.HorizontalScope()) + { + EditorGUILayout.LabelField("Camera Culling Method"); + EditorGUILayout.LabelField("(Synchronizing)"); + } + using (new EditorGUILayout.HorizontalScope()) + { + EditorGUILayout.LabelField("Distance Culling Length"); + EditorGUILayout.LabelField("(Synchronizing)"); + } + using (new EditorGUILayout.HorizontalScope()) + { + EditorGUILayout.LabelField("Distance Culling Fade Ratio"); + EditorGUILayout.LabelField("(Synchronizing)"); + } + using (new EditorGUILayout.HorizontalScope()) + { + EditorGUILayout.LabelField("Distance Culling Reference Object"); + EditorGUILayout.LabelField("(Synchronizing)"); + } + } + } + }); + } + + void ClothPreBuildInspector() + { + var cloth = target as MagicaCloth; + + bool generation = false; + + using (new EditorGUI.DisabledScope(EditorApplication.isPlaying)) + { + Foldout("Pre-Build", serializedObject.FindProperty("serializeData2.preBuildData.enabled"), null, () => + { + // information + var preBuildData = cloth.GetSerializeData2().preBuildData; + if (preBuildData.UsePreBuild()) + { + DispClothStatus("[Pre-Build Construction]", preBuildData.DataValidate(), false); + } + + EditorGUILayout.PropertyField(serializedObject.FindProperty("serializeData2.preBuildData.buildId"), new GUIContent("Build ID")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("serializeData2.preBuildData.preBuildScriptableObject"), new GUIContent("Write Object")); + using (var horizontalScope = new GUILayout.HorizontalScope()) + { + EditorGUILayout.Space(); + GUI.backgroundColor = Color.red; + if (GUILayout.Button("Create PreBuild Data")) + { + generation = true; + } + GUI.backgroundColor = Color.white; + EditorGUILayout.Space(); + } + }); + } + + if (generation) + { + // PreBuildデータ構築実行 + Develop.Log($"Start PreBuild data creation."); + var preBuildResult = PreBuildDataCreation.CreatePreBuildData(cloth); + Develop.Log($"PreBuild data creation completed. [{cloth.GetSerializeData2().preBuildData.buildId}] : {preBuildResult.GetResultString()}"); + } + } + + void ClothParameterInspector() + { + var cloth = target as MagicaCloth; + var clothType = cloth.SerializeData.clothType; + bool isBoneSpring = clothType == ClothProcess.ClothType.BoneSpring; + + // 同期状態 + bool sync = EditorApplication.isPlaying && cloth.SyncPartnerCloth != null; + + ClothPresetUtility.DrawPresetButton(cloth, cloth.SerializeData); + + // Force + Foldout("Force", null, () => + { + if (isBoneSpring == false) + { + EditorGUILayout.PropertyField(serializedObject.FindProperty("serializeData.gravity"), new GUIContent("Gravity")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("serializeData.gravityDirection")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("serializeData.gravityFalloff")); + } + EditorGUILayout.PropertyField(serializedObject.FindProperty("serializeData.damping")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("serializeData.stablizationTimeAfterReset"), new GUIContent("Stablization Time")); + }); + + // Spring + if (isBoneSpring) + { + Foldout("Spring", serializedObject.FindProperty("serializeData.springConstraint.useSpring"), null, () => + { + EditorGUILayout.PropertyField(serializedObject.FindProperty("serializeData.springConstraint.springPower")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("serializeData.springConstraint.limitDistance")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("serializeData.springConstraint.normalLimitRatio")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("serializeData.springConstraint.springNoise")); + }); + } + + // Angle Restoration + Foldout("Angle Restoration", serializedObject.FindProperty("serializeData.angleRestorationConstraint.useAngleRestoration"), null, () => + { + EditorGUILayout.PropertyField(serializedObject.FindProperty("serializeData.angleRestorationConstraint.stiffness")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("serializeData.angleRestorationConstraint.velocityAttenuation")); + if (isBoneSpring == false) + { + EditorGUILayout.PropertyField(serializedObject.FindProperty("serializeData.angleRestorationConstraint.gravityFalloff")); + } + } + ); + + // Angle Limit + Foldout("Angle Limit", serializedObject.FindProperty("serializeData.angleLimitConstraint.useAngleLimit"), null, () => + { + EditorGUILayout.PropertyField(serializedObject.FindProperty("serializeData.angleLimitConstraint.limitAngle")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("serializeData.angleLimitConstraint.stiffness")); + } + ); + + // Shape + // BoneSpringではすべて定数なので隠蔽する + if (isBoneSpring == false) + { + Foldout("Shape Restoration", null, () => + { + EditorGUILayout.PropertyField(serializedObject.FindProperty("serializeData.distanceConstraint.stiffness"), new GUIContent("Distance Stiffness")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("serializeData.tetherConstraint.distanceCompression"), new GUIContent("Tether Compression")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("serializeData.triangleBendingConstraint.stiffness"), new GUIContent("Triangle Bending Stiffness")); + }); + } + + // Inertia + Foldout("Inertia", null, () => + { + if (sync == false) + { + EditorGUILayout.PropertyField(serializedObject.FindProperty("serializeData.inertiaConstraint.anchor")); + if (cloth.SerializeData.inertiaConstraint.anchor != null) + EditorGUILayout.PropertyField(serializedObject.FindProperty("serializeData.inertiaConstraint.anchorInertia")); + EditorGUILayout.Space(); + EditorGUILayout.PropertyField(serializedObject.FindProperty("serializeData.inertiaConstraint.worldInertia")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("serializeData.inertiaConstraint.movementInertiaSmoothing"), new GUIContent("World Inertia Smoothing")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("serializeData.inertiaConstraint.movementSpeedLimit"), new GUIContent("World Movement Speed Limit")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("serializeData.inertiaConstraint.rotationSpeedLimit"), new GUIContent("World Rotation Speed Limit")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("serializeData.inertiaConstraint.teleportMode")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("serializeData.inertiaConstraint.teleportDistance")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("serializeData.inertiaConstraint.teleportRotation")); + } + else + { + // 同期中は操作不可 + using (new EditorGUI.DisabledScope(true)) + { + using (new EditorGUILayout.HorizontalScope()) + { + EditorGUILayout.LabelField("Anchor"); + EditorGUILayout.LabelField("(Synchronizing)"); + } + using (new EditorGUILayout.HorizontalScope()) + { + EditorGUILayout.LabelField("Anchor Inertia"); + EditorGUILayout.LabelField("(Synchronizing)"); + } + EditorGUILayout.Space(); + using (new EditorGUILayout.HorizontalScope()) + { + EditorGUILayout.LabelField("World Inertia"); + EditorGUILayout.LabelField("(Synchronizing)"); + } + using (new EditorGUILayout.HorizontalScope()) + { + EditorGUILayout.LabelField("World Inertia Smoothing"); + EditorGUILayout.LabelField("(Synchronizing)"); + } + using (new EditorGUILayout.HorizontalScope()) + { + EditorGUILayout.LabelField("World Movement Speed Limit"); + EditorGUILayout.LabelField("(Synchronizing)"); + } + using (new EditorGUILayout.HorizontalScope()) + { + EditorGUILayout.LabelField("World Rotation Speed Limit"); + EditorGUILayout.LabelField("(Synchronizing)"); + } + + using (new EditorGUILayout.HorizontalScope()) + { + EditorGUILayout.LabelField("Teleport Mode"); + EditorGUILayout.LabelField("(Synchronizing)"); + } + using (new EditorGUILayout.HorizontalScope()) + { + EditorGUILayout.LabelField("Teleport Distance"); + EditorGUILayout.LabelField("(Synchronizing)"); + } + using (new EditorGUILayout.HorizontalScope()) + { + EditorGUILayout.LabelField("Teleport Rotation"); + EditorGUILayout.LabelField("(Synchronizing)"); + } + } + } + EditorGUILayout.Space(); + EditorGUILayout.PropertyField(serializedObject.FindProperty("serializeData.inertiaConstraint.localInertia"), new GUIContent("Local Inertia")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("serializeData.inertiaConstraint.localMovementSpeedLimit")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("serializeData.inertiaConstraint.localRotationSpeedLimit")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("serializeData.inertiaConstraint.depthInertia"), new GUIContent("Local Depth Inertia")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("serializeData.inertiaConstraint.centrifualAcceleration")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("serializeData.inertiaConstraint.particleSpeedLimit")); + }); + + // Motion + if (isBoneSpring == false) + { + Foldout("Movement Limit", null, () => + { + var useMaxDistance = serializedObject.FindProperty("serializeData.motionConstraint.useMaxDistance"); + var useBackstop = serializedObject.FindProperty("serializeData.motionConstraint.useBackstop"); + EditorGUILayout.PropertyField(useMaxDistance); + using (new EditorGUI.DisabledScope(!useMaxDistance.boolValue)) + { + EditorGUILayout.PropertyField(serializedObject.FindProperty("serializeData.motionConstraint.maxDistance")); + } + EditorGUILayout.PropertyField(useBackstop); + using (new EditorGUI.DisabledScope(!useBackstop.boolValue)) + { + EditorGUILayout.PropertyField(serializedObject.FindProperty("serializeData.motionConstraint.backstopRadius")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("serializeData.motionConstraint.backstopDistance")); + } + EditorGUILayout.PropertyField(serializedObject.FindProperty("serializeData.motionConstraint.stiffness")); + + var paintMode = serializedObject.FindProperty("serializeData.paintMode"); + if (paintMode.enumValueIndex == 0) + PaintButton(ClothPainter.PaintMode.Motion); + } + ); + } + + // Collider Collision + Foldout("Collider Collision", null, () => + { + if (isBoneSpring) + { + using (new EditorGUILayout.HorizontalScope()) + { + EditorGUILayout.LabelField("Mode"); + EditorGUILayout.LabelField("[Point]"); + } + } + else + { + EditorGUILayout.PropertyField(serializedObject.FindProperty("serializeData.colliderCollisionConstraint.mode")); + } + EditorGUILayout.PropertyField(serializedObject.FindProperty("serializeData.radius")); + if (clothType == ClothProcess.ClothType.BoneSpring) + { + EditorGUILayout.PropertyField(serializedObject.FindProperty("serializeData.colliderCollisionConstraint.limitDistance")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("serializeData.colliderCollisionConstraint.collisionBones")); + } + else + { + EditorGUILayout.PropertyField(serializedObject.FindProperty("serializeData.colliderCollisionConstraint.friction")); + } + EditorGUILayout.PropertyField(serializedObject.FindProperty("serializeData.colliderCollisionConstraint.colliderList")); + } + ); + + // Self Collision + if (isBoneSpring == false) + { + Foldout("Self Collision", "Self Collision (Beta2)", () => + { + EditorGUILayout.PropertyField(serializedObject.FindProperty("serializeData.selfCollisionConstraint.selfMode")); + var syncMode = serializedObject.FindProperty("serializeData.selfCollisionConstraint.syncMode"); + EditorGUILayout.PropertyField(syncMode); + if (syncMode.enumValueIndex != 0) + { + EditorGUILayout.PropertyField(serializedObject.FindProperty("serializeData.selfCollisionConstraint.syncPartner")); + } + EditorGUILayout.PropertyField(serializedObject.FindProperty("serializeData.selfCollisionConstraint.surfaceThickness")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("serializeData.selfCollisionConstraint.clothMass")); + } + ); + } + + // Wind + Foldout("Wind", null, () => + { + EditorGUILayout.PropertyField(serializedObject.FindProperty("serializeData.wind.influence")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("serializeData.wind.frequency")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("serializeData.wind.turbulence")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("serializeData.wind.blend"), new GUIContent("Noise Blend")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("serializeData.wind.synchronization")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("serializeData.wind.depthWeight")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("serializeData.wind.movingWind")); + }); + } + + /// + /// 各プロパティの設定範囲.デフォルトは(0.0 ~ 1.0) + /// + /// + /// + public static Vector2 GetPropertyMinMax(string propertyName) + { + var minmax = new Vector2(0.0f, 1.0f); + + switch (propertyName) + { + case "radius": + minmax.Set(0.001f, 0.5f); + break; + case "limitAngle": + minmax.Set(0.0f, 180.0f); + break; + case "maxDistance": + minmax.Set(0.0f, 5.0f); + break; + case "surfaceThickness": + minmax.Set(Define.System.SelfCollisionThicknessMin, Define.System.SelfCollisionThicknessMax); + break; + case "movementSpeedLimit": + case "localMovementSpeedLimit": + minmax.Set(0.0f, Define.System.MaxMovementSpeedLimit); + break; + case "rotationSpeedLimit": + case "localRotationSpeedLimit": + minmax.Set(0.0f, Define.System.MaxRotationSpeedLimit); + break; + case "particleSpeedLimit": + minmax.Set(0.0f, Define.System.MaxParticleSpeedLimit); + break; + case "distanceCullingLength": + minmax.Set(0.0f, Define.System.DistanceCullingMaxLength); + break; + } + + return minmax; + } + + void GizmoInspector() + { +#if MC2_DEBUG + EditorGUILayout.PropertyField(serializedObject.FindProperty("gizmoSerializeData")); +#else + FoldOut("Gizmos", null, () => + { + EditorGUILayout.PropertyField(serializedObject.FindProperty("gizmoSerializeData.always")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("gizmoSerializeData.clothDebugSettings.enable")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("gizmoSerializeData.clothDebugSettings.ztest")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("gizmoSerializeData.clothDebugSettings.position")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("gizmoSerializeData.clothDebugSettings.axis")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("gizmoSerializeData.clothDebugSettings.shape")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("gizmoSerializeData.clothDebugSettings.baseLine")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("gizmoSerializeData.clothDebugSettings.depth")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("gizmoSerializeData.clothDebugSettings.collider")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("gizmoSerializeData.clothDebugSettings.animatedPosition")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("gizmoSerializeData.clothDebugSettings.animatedAxis")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("gizmoSerializeData.clothDebugSettings.animatedShape")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("gizmoSerializeData.clothDebugSettings.inertiaCenter")); + //EditorGUILayout.PropertyField(serializedObject.FindProperty("gizmoSerializeData.clothDebugSettings.basicPosition")); + //EditorGUILayout.PropertyField(serializedObject.FindProperty("gizmoSerializeData.clothDebugSettings.basicAxis")); + //EditorGUILayout.PropertyField(serializedObject.FindProperty("gizmoSerializeData.clothDebugSettings.basicShape")); + }); +#endif + } + + //========================================================================================= + /// + /// 折りたたみ制御 + /// + /// 折りたたみ保存キー + /// + /// 内容描画アクション + /// 有効フラグアクション(null=無効) + /// 現在の有効フラグ + public void Foldout( + string foldKey, + string title = null, + System.Action drawAct = null, + System.Action enableAct = null, + bool enable = true + ) + { + var style = new GUIStyle("ShurikenModuleTitle"); + style.font = new GUIStyle(EditorStyles.label).font; + style.border = new RectOffset(15, 7, 4, 4); + style.fixedHeight = 22; + style.contentOffset = new Vector2(20f, -2f); + + var rect = GUILayoutUtility.GetRect(16f, 22f, style); + + GUI.backgroundColor = Color.white; + GUI.Box(rect, title ?? foldKey, style); + + var e = Event.current; + bool foldOut = EditorPrefs.GetBool(foldKey); + + if (enableAct == null) + { + if (e.type == EventType.Repaint) + { + var arrowRect = new Rect(rect.x + 4f, rect.y + 2f, 13f, 13f); + EditorStyles.foldout.Draw(arrowRect, false, false, foldOut, false); + } + } + else + { + // 有効チェック + var toggleRect = new Rect(rect.x + 4f, rect.y + 4f, 13f, 13f); + bool sw = GUI.Toggle(toggleRect, enable, string.Empty, new GUIStyle("ShurikenCheckMark")); + if (sw != enable) + { + enableAct(sw); + } + } + + if (e.type == EventType.MouseDown && rect.Contains(e.mousePosition)) + { + foldOut = !foldOut; + EditorPrefs.SetBool(foldKey, foldOut); + e.Use(); + } + + if (foldOut && drawAct != null) + { + using (new EditorGUI.IndentLevelScope()) + { + using (new EditorGUI.DisabledScope(!enable)) + { + drawAct(); + } + } + } + } + + /// + /// 折りたたみ制御(Boolプロパティによるチェックあり) + /// + /// + /// + /// + /// + public void Foldout( + string foldKey, + SerializedProperty boolProperty, + string title = null, + System.Action drawAct = null + ) + { + Foldout( + foldKey, title, drawAct, + (sw) => boolProperty.boolValue = sw, + boolProperty.boolValue + ); + } + + void FoldOut(string key, string title = null, System.Action drawAct = null) + { + bool foldOut1 = EditorPrefs.GetBool(key); + bool foldOut2 = EditorGUILayout.Foldout(foldOut1, title ?? key); + if (foldOut2) + { + using (new EditorGUI.IndentLevelScope()) + { + drawAct?.Invoke(); + } + } + if (foldOut1 != foldOut2) + { + EditorPrefs.SetBool(key, foldOut2); + } + } + + void PaintButton(ClothPainter.PaintMode paintMode) + { + if (EditorApplication.isPlaying) + return; + + var cloth = target as MagicaCloth; + + using (new EditorGUILayout.HorizontalScope()) + { + switch (paintMode) + { + case ClothPainter.PaintMode.Attribute: + GUI.backgroundColor = new Color(0.5f, 1.0f, 0.5f); + break; + case ClothPainter.PaintMode.Motion: + GUI.backgroundColor = new Color(0.0f, 1.0f, 1.0f); + break; + } + + EditorGUILayout.Space(); + + bool edit = ClothPainter.HasEditCloth(cloth); + //var icon = edit ? EditorGUIUtility.IconContent("winbtn_win_close") : EditorGUIUtility.IconContent("d_editicon.sml"); + //var icon = EditorGUIUtility.IconContent("d_Grid.PaintTool");// 良い + var icon = EditorGUIUtility.IconContent("d_editicon.sml"); + if (GUILayout.Button(icon, GUILayout.Width(40))) + { + if (edit == false) + { + // 最新の編集メッシュからセレクションデータを生成する + var editMeshContainer = ClothEditorManager.GetEditMeshContainer(cloth); + if (editMeshContainer != null && editMeshContainer.shareVirtualMesh != null) + { + // すでにセレクションデータが存在し、かつユーザー編集データならばコンバートする + var selectionData = GetSelectionData(cloth, editMeshContainer.shareVirtualMesh); + + // セレクションデータにメッシュの最大接続距離を記録する + selectionData.maxConnectionDistance = editMeshContainer.shareVirtualMesh.maxVertexDistance.Value; + + // ペイント開始 + ClothPainter.EnterPaint(paintMode, this, cloth, editMeshContainer, selectionData); + SceneView.RepaintAll(); + } + } + else + { + // 初期化データの保存確認 + ClothEditorManager.ApplyInitData(cloth, global: true); + + ClothPainter.ExitPaint(); + SceneView.RepaintAll(); + } + } + EditorGUILayout.Space(); + GUI.backgroundColor = Color.white; + } + EditorGUILayout.Space(10); + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Editor/Cloth/MagicaClothEditor.cs.meta b/Assets/MagicaCloth2/Scripts/Editor/Cloth/MagicaClothEditor.cs.meta new file mode 100644 index 00000000..a7017b9f --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Editor/Cloth/MagicaClothEditor.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: a43a416802744754899e8dc139f244c7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Editor/Cloth/MagicaClothEditor.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Editor/Cloth/MagicaEditorBase.cs b/Assets/MagicaCloth2/Scripts/Editor/Cloth/MagicaEditorBase.cs new file mode 100644 index 00000000..f8d7ece3 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Editor/Cloth/MagicaEditorBase.cs @@ -0,0 +1,40 @@ +// Magica Cloth 2. +// Copyright (c) 2024 MagicaSoft. +// https://magicasoft.jp +using System; +using UnityEditor; + +namespace MagicaCloth2 +{ + /// + /// インスペクター拡張のベースクラス + /// + public class MagicaEditorBase : Editor + { + /// + /// マルチ選択編集の適用 + /// + /// + /// + /// + protected void ApplyMultiSelection(bool changed, string undoName, Action act) where T : ClothBehaviour + { + if (changed) + { + foreach (var obj in targets) + { + var tscr = obj as T; + + // Undo + Undo.RecordObject(tscr, undoName); + + act(tscr); + EditorUtility.SetDirty(tscr); + + // OnValidate()手動呼び出し + tscr.GetType().GetMethod("OnValidate", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)?.Invoke(tscr, null); + } + } + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Editor/Cloth/MagicaEditorBase.cs.meta b/Assets/MagicaCloth2/Scripts/Editor/Cloth/MagicaEditorBase.cs.meta new file mode 100644 index 00000000..7be2ad8d --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Editor/Cloth/MagicaEditorBase.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 3126cd1eb42b4af4aa38cea3c3836c3e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Editor/Cloth/MagicaEditorBase.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Editor/Cloth/MagicaPlaneColliderEditor.cs b/Assets/MagicaCloth2/Scripts/Editor/Cloth/MagicaPlaneColliderEditor.cs new file mode 100644 index 00000000..f801a448 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Editor/Cloth/MagicaPlaneColliderEditor.cs @@ -0,0 +1,35 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using UnityEditor; + +namespace MagicaCloth2 +{ + /// + /// PlaneColliderのインスペクター拡張 + /// + [CustomEditor(typeof(MagicaPlaneCollider))] + [CanEditMultipleObjects] + public class MagicaPlaneColliderEditor : MagicaEditorBase + { + public override void OnInspectorGUI() + { + var scr = target as MagicaPlaneCollider; + + serializedObject.Update(); + Undo.RecordObject(scr, "PlaneCollider"); + + // center + EditorGUILayout.PropertyField(serializedObject.FindProperty("center")); + + // Symmetry + EditorGUILayout.Space(); + var symmetryModeProperty = serializedObject.FindProperty("symmetryMode"); + EditorGUILayout.PropertyField(symmetryModeProperty); + if (symmetryModeProperty.enumValueIndex >= (int)ColliderSymmetryMode.AutomaticTarget) + EditorGUILayout.PropertyField(serializedObject.FindProperty("symmetryTarget")); + + serializedObject.ApplyModifiedProperties(); + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Editor/Cloth/MagicaPlaneColliderEditor.cs.meta b/Assets/MagicaCloth2/Scripts/Editor/Cloth/MagicaPlaneColliderEditor.cs.meta new file mode 100644 index 00000000..0c9d4f6d --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Editor/Cloth/MagicaPlaneColliderEditor.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 7c2eaf60c91e70a4198cb71bbaf68678 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Editor/Cloth/MagicaPlaneColliderEditor.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Editor/Cloth/MagicaSettingsEditor.cs b/Assets/MagicaCloth2/Scripts/Editor/Cloth/MagicaSettingsEditor.cs new file mode 100644 index 00000000..b6e7d4e5 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Editor/Cloth/MagicaSettingsEditor.cs @@ -0,0 +1,37 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using UnityEditor; + +namespace MagicaCloth2 +{ + [CustomEditor(typeof(MagicaSettings))] + [CanEditMultipleObjects] + public class MagicaSettingsEditor : MagicaEditorBase + { + //========================================================================================= + /// + /// インスペクターGUI + /// + public override void OnInspectorGUI() + { + var comp = target as MagicaSettings; + + serializedObject.Update(); + Undo.RecordObject(comp, "MagicaSettings"); + SettingsInspector(); + serializedObject.ApplyModifiedProperties(); + } + + void SettingsInspector() + { + EditorGUILayout.PropertyField(serializedObject.FindProperty("refreshMode")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("simulationFrequency")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("maxSimulationCountPerFrame")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("initializationLocation")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("updateLocation")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("monitorPlayerLoop")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("splitProxyMeshVertexCount")); + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Editor/Cloth/MagicaSettingsEditor.cs.meta b/Assets/MagicaCloth2/Scripts/Editor/Cloth/MagicaSettingsEditor.cs.meta new file mode 100644 index 00000000..dd89b2dc --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Editor/Cloth/MagicaSettingsEditor.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 53b8f563506b5fa4691d2d29c3d3c185 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Editor/Cloth/MagicaSettingsEditor.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Editor/Cloth/MagicaSphereColliderEditor.cs b/Assets/MagicaCloth2/Scripts/Editor/Cloth/MagicaSphereColliderEditor.cs new file mode 100644 index 00000000..f684c4a2 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Editor/Cloth/MagicaSphereColliderEditor.cs @@ -0,0 +1,50 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using UnityEditor; + +namespace MagicaCloth2 +{ + /// + /// SphereColliderのインスペクター拡張 + /// + [CustomEditor(typeof(MagicaSphereCollider))] + [CanEditMultipleObjects] + public class MagicaSphereColliderEditor : MagicaEditorBase + { + public override void OnInspectorGUI() + { + var scr = target as MagicaSphereCollider; + const string undoName = "SphereCollider"; + + serializedObject.Update(); + Undo.RecordObject(scr, undoName); + + using (var check = new EditorGUI.ChangeCheckScope()) + { + + // radius + var sizeValue = serializedObject.FindProperty("size"); + + //EditorGUI.showMixedValue = sizeValue.hasMultipleDifferentValues; + var size = sizeValue.vector3Value; + float newSize = EditorGUILayout.Slider("Radius", size.x, 0.001f, 0.5f); + //EditorGUI.showMixedValue = false; + + ApplyMultiSelection(check.changed, undoName, x => x.SetSize(newSize)); + } + + // center + EditorGUILayout.PropertyField(serializedObject.FindProperty("center")); + + // Symmetry + EditorGUILayout.Space(); + var symmetryModeProperty = serializedObject.FindProperty("symmetryMode"); + EditorGUILayout.PropertyField(symmetryModeProperty); + if (symmetryModeProperty.enumValueIndex >= (int)ColliderSymmetryMode.AutomaticTarget) + EditorGUILayout.PropertyField(serializedObject.FindProperty("symmetryTarget")); + + serializedObject.ApplyModifiedProperties(); + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Editor/Cloth/MagicaSphereColliderEditor.cs.meta b/Assets/MagicaCloth2/Scripts/Editor/Cloth/MagicaSphereColliderEditor.cs.meta new file mode 100644 index 00000000..7d39c52a --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Editor/Cloth/MagicaSphereColliderEditor.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: d26018c2091e9054ea0bf517157ca1c6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Editor/Cloth/MagicaSphereColliderEditor.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Editor/Cloth/MagicaWindZoneEditor.cs b/Assets/MagicaCloth2/Scripts/Editor/Cloth/MagicaWindZoneEditor.cs new file mode 100644 index 00000000..d579eefd --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Editor/Cloth/MagicaWindZoneEditor.cs @@ -0,0 +1,77 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using UnityEditor; +using UnityEngine; + +namespace MagicaCloth2 +{ + [CustomEditor(typeof(MagicaWindZone))] + [CanEditMultipleObjects] + public class MagicaWindZoneEditor : MagicaEditorBase + { + //========================================================================================= + /// + /// インスペクターGUI + /// + public override void OnInspectorGUI() + { + var wind = target as MagicaWindZone; + + serializedObject.Update(); + Undo.RecordObject(wind, "MagicaWindZone"); + + WindInspector(); + + serializedObject.ApplyModifiedProperties(); + } + + void WindInspector() + { + var wind = target as MagicaWindZone; + + var modeProperty = serializedObject.FindProperty("mode"); + EditorGUILayout.PropertyField(modeProperty); + + //var mode = (MagicaWindZone.Mode)modeProperty.enumValueIndex; + if (wind.mode == MagicaWindZone.Mode.SphereDirection || wind.mode == MagicaWindZone.Mode.SphereRadial) + { + var radiusProperty = serializedObject.FindProperty("radius"); + var radius = radiusProperty.floatValue; + float nr = EditorGUILayout.FloatField(new GUIContent("Radius"), radius); + nr = Mathf.Max(nr, 0.0f); + if (radius != nr) + { + radiusProperty.floatValue = nr; + } + } + else if (wind.mode == MagicaWindZone.Mode.BoxDirection) + { + var sizeProperty = serializedObject.FindProperty("size"); + var size = sizeProperty.vector3Value; + var ns = EditorGUILayout.Vector3Field(new GUIContent("Box Size"), size); + ns = Vector3.Max(ns, Vector3.zero); + if (size != ns) + { + sizeProperty.vector3Value = ns; + } + } + + EditorGUILayout.Space(); + + EditorGUILayout.PropertyField(serializedObject.FindProperty("main")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("turbulence")); + + if (wind.IsDirection()) + { + EditorGUILayout.PropertyField(serializedObject.FindProperty("directionAngleX")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("directionAngleY")); + } + else + { + EditorGUILayout.CurveField(serializedObject.FindProperty("attenuation"), Color.green, new Rect(0, 0, 1, 1)); + } + EditorGUILayout.PropertyField(serializedObject.FindProperty("isAddition")); + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Editor/Cloth/MagicaWindZoneEditor.cs.meta b/Assets/MagicaCloth2/Scripts/Editor/Cloth/MagicaWindZoneEditor.cs.meta new file mode 100644 index 00000000..684b0d73 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Editor/Cloth/MagicaWindZoneEditor.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 56e75137613813345a058b4bb6748854 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Editor/Cloth/MagicaWindZoneEditor.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Editor/Cloth/VirtualMeshEditorUtility.cs b/Assets/MagicaCloth2/Scripts/Editor/Cloth/VirtualMeshEditorUtility.cs new file mode 100644 index 00000000..e9c06c7e --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Editor/Cloth/VirtualMeshEditorUtility.cs @@ -0,0 +1,538 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +#if MC2_DEBUG +using System.Collections.Generic; +using Unity.Collections; +using Unity.Mathematics; +using UnityEditor; +using UnityEngine; +#endif + +namespace MagicaCloth2 +{ +#if MC2_DEBUG + public static partial class VirtualMeshEditorUtility + { + //========================================================================================= + static List positionBuffer0 = new List(1024); + static List positionBuffer1 = new List(1024); + static List positionBuffer2 = new List(1024); + static List segmentBuffer0 = new List(2048); + static List segmentBuffer1 = new List(2048); + static List segmentBuffer2 = new List(2048); + + //========================================================================================= + + /// + /// VirtualMeshのデバッグ表示(編集用) + /// + /// + /// + public static void DrawGizmos(VirtualMeshContainer cmesh, VirtualMeshDebugSettings debugSettings, bool selected, bool useHandles) + { + if (debugSettings.enable == false) + return; + if (cmesh == null || cmesh.shareVirtualMesh == null || cmesh.shareVirtualMesh.IsSuccess == false || cmesh.shareVirtualMesh.VertexCount == 0) + return; + + var vmesh = cmesh.shareVirtualMesh; + var t = cmesh.GetCenterTransform(); + if (t == null) + return; + + using NativeArray dummyRotations = new NativeArray(0, Allocator.TempJob); + DrawGizmosInternal( + useHandles, + true, + selected, + cmesh, + debugSettings, + t, + 0, + vmesh.attributes.GetNativeArray(), + vmesh.localPositions.GetNativeArray(), + dummyRotations, + vmesh.localNormals.GetNativeArray(), + vmesh.localTangents.GetNativeArray(), + 0, + vmesh.boneWeights.GetNativeArray(), + vmesh.skinBoneTransformIndices.GetNativeArray(), + vmesh.uv.GetNativeArray() + ); + } + + + /// + /// Proxy/Mappingメッシュのデバッグ表示(ランタイム用) + /// + /// + /// + /// + public static void DrawRuntimeGizmos(ClothProcess cprocess, bool isMapping, VirtualMeshContainer cmesh, VirtualMeshDebugSettings debugSettings, bool selected, bool useHandles) + { + if (cprocess == null || cprocess.IsValid() == false) + return; + if (debugSettings.enable == false) + return; + if (MagicaManager.Team == null) + return; + if (MagicaManager.Team.ContainsTeamData(cprocess.TeamId) == false) + return; + + if (cmesh == null || cmesh.shareVirtualMesh == null || cmesh.shareVirtualMesh.IsSuccess == false) + return; + + var t = cmesh.GetCenterTransform(); + if (t == null) + return; + + // チームデータ + ref var tdata = ref MagicaManager.Team.GetTeamDataRef(cprocess.TeamId); + + var tm = MagicaManager.Team; + var vm = MagicaManager.VMesh; + + // メッシュタイプにより参照するデータを切り替える + var vmesh = cmesh.shareVirtualMesh; + var attributes = vmesh.IsMapping ? vm.mappingAttributes : vm.attributes; + var positions = vmesh.IsMapping ? vm.mappingPositions : vm.positions; + var rotations = vmesh.IsMapping ? null : vm.rotations; + int boneWeightOffset = vmesh.IsMapping ? 0 : tdata.proxySkinBoneChunk.startIndex + tdata.proxyTransformChunk.startIndex; + var boneWeights = vmesh.IsMapping ? vm.mappingBoneWeights : vm.boneWeights; + var skinBoneTransformIndices = vmesh.IsMapping ? vm.skinBoneTransformIndices : vm.skinBoneTransformIndices; + var uvs = vmesh.IsMapping ? null : vmesh.uv; + int vstart = vmesh.IsMapping ? tm.mappingDataArray[vmesh.mappingId].mappingCommonChunk.startIndex : tdata.proxyCommonChunk.startIndex; + + using NativeArray dummyRotations = new NativeArray(0, Allocator.TempJob); + using NativeArray dummyUvs = new NativeArray(0, Allocator.TempJob); + + DrawGizmosInternal( + useHandles, + isMapping ? true : false, + selected, + cmesh, + debugSettings, + t, + vstart, + attributes.GetNativeArray(), + positions.GetNativeArray(), + rotations != null ? rotations.GetNativeArray() : dummyRotations, + vmesh.localNormals.GetNativeArray(), + vmesh.localTangents.GetNativeArray(), + boneWeightOffset, + boneWeights.GetNativeArray(), + skinBoneTransformIndices.GetNativeArray(), + uvs != null ? uvs.GetNativeArray() : dummyUvs + ); + } + + static void DrawGizmosInternal( + bool useHandles, + bool isLocal, + bool selected, + VirtualMeshContainer cmesh, + VirtualMeshDebugSettings debugSettings, + Transform center, + int vstart, + NativeArray attributes, + NativeArray positions, + NativeArray rotations, + NativeArray normals, + NativeArray tangents, + int boneWeightOffset, + NativeArray boneWeights, + NativeArray skinBoneTransformIndices, + NativeArray uvs + ) + { + // 座標空間に合わせる + if (isLocal) + { + Handles.matrix = center.localToWorldMatrix; + if (useHandles == false) + Gizmos.matrix = center.localToWorldMatrix; + } + else + { + Handles.matrix = Matrix4x4.identity; + Gizmos.matrix = Matrix4x4.identity; + } + + // シーンカメラ + var scam = SceneView.currentDrawingSceneView?.camera; + if (scam == null) + return; + quaternion camRot = scam.transform.rotation; + //quaternion invCamRot = math.inverse(camRot); + var vmesh = cmesh.shareVirtualMesh; + int vcnt = vmesh.VertexCount; + + // 表示スケール調整 + var scl = isLocal ? 1.0f / (center.lossyScale.magnitude / 1.7305f) : 1.0f; + var drawPointSize = debugSettings.pointSize * scl; + float drawAxisSize = debugSettings.lineSize * scl; + + bool hasRotation = rotations.IsCreated && rotations.Length > 0; + bool hasUv = uvs.IsCreated && uvs.Length > 0; + float colorScale = selected ? 1 : 0.5f; + + // position + if (debugSettings.position) + { + for (int i = 0; i < vcnt; i++) + { + if (i < debugSettings.vertexMinIndex || i > debugSettings.vertexMaxIndex) + continue; + + var pos = positions[vstart + i]; + var attr = attributes[vstart + i]; + var col = Color.black; + if (attr.IsFixed()) col = Color.red; + if (attr.IsMove()) col = Color.green; + GizmoUtility.SetColor(col * colorScale, useHandles); + + GizmoUtility.DrawSphere(pos, drawPointSize, useHandles); + } + } + + // rotation axis + if (debugSettings.axis && hasRotation) + { + positionBuffer0.Clear(); + positionBuffer1.Clear(); + positionBuffer2.Clear(); + segmentBuffer0.Clear(); + segmentBuffer1.Clear(); + segmentBuffer2.Clear(); + + for (int i = 0; i < vcnt; i++) + { + if (i < debugSettings.vertexMinIndex || i > debugSettings.vertexMaxIndex) + continue; + + var pos = positions[vstart + i]; + var y = hasRotation ? MathUtility.ToNormal(rotations[vstart + i]) : normals[vstart + i]; + var z = hasRotation ? MathUtility.ToTangent(rotations[vstart + i]) : tangents[vstart + i]; + var x = math.cross(y, z); + + positionBuffer0.Add(pos); + positionBuffer0.Add(pos + x * drawAxisSize); + segmentBuffer0.Add(i * 2); + segmentBuffer0.Add(i * 2 + 1); + + positionBuffer1.Add(pos); + positionBuffer1.Add(pos + y * drawAxisSize); + segmentBuffer1.Add(i * 2); + segmentBuffer1.Add(i * 2 + 1); + + positionBuffer2.Add(pos); + positionBuffer2.Add(pos + z * drawAxisSize); + segmentBuffer2.Add(i * 2); + segmentBuffer2.Add(i * 2 + 1); + } + + // x + Handles.color = Color.red * colorScale; + Handles.DrawLines(positionBuffer0.ToArray(), segmentBuffer0.ToArray()); + // y + Handles.color = Color.green * colorScale; + Handles.DrawLines(positionBuffer1.ToArray(), segmentBuffer1.ToArray()); + // z + Handles.color = Color.blue * colorScale; + Handles.DrawLines(positionBuffer2.ToArray(), segmentBuffer2.ToArray()); + } + + // bone weight + if (debugSettings.boneWeight) + { + for (int i = 0; i < vcnt; i++) + { + if (i < debugSettings.vertexMinIndex || i > debugSettings.vertexMaxIndex) + continue; + var pos = positions[vstart + i]; + var bw = boneWeights[vstart + i]; + bw.boneIndices += boneWeightOffset; // グローバルインデックスに変換 + bw.boneIndices.x = skinBoneTransformIndices[bw.boneIndices.x]; + bw.boneIndices.y = skinBoneTransformIndices[bw.boneIndices.y]; + bw.boneIndices.z = skinBoneTransformIndices[bw.boneIndices.z]; + bw.boneIndices.w = skinBoneTransformIndices[bw.boneIndices.w]; + Handles.Label(pos, $"[{bw.boneIndices.x},{bw.boneIndices.y},{bw.boneIndices.z},{bw.boneIndices.w}] w({bw.weights.x:0.###}, {bw.weights.y:0.###}, {bw.weights.z:0.###}, {bw.weights.w:0.###})"); + } + } + // number + else if (debugSettings.indexNumber) + { + for (int i = 0; i < vcnt; i++) + { + if (i < debugSettings.vertexMinIndex || i > debugSettings.vertexMaxIndex) + continue; + var pos = positions[vstart + i]; + Handles.Label(pos, i.ToString()); + } + } + // uv + else if (debugSettings.uv) + { + if (vmesh.IsProxy) + { + // プロキシのみ + for (int i = 0; i < vcnt; i++) + { + if (i < debugSettings.vertexMinIndex || i > debugSettings.vertexMaxIndex) + continue; + var pos = positions[vstart + i]; + var uv = vmesh.uv[i]; + Handles.Label(pos, $"({uv.x:0.####}, {uv.y:0.####})"); + } + } + } + // depth + else if (debugSettings.depth) + { + if (vmesh.IsProxy) + { + if (vmesh.vertexDepths.IsCreated) + { + for (int i = 0; i < vcnt; i++) + { + if (i < debugSettings.vertexMinIndex || i > debugSettings.vertexMaxIndex) + continue; + var pos = positions[vstart + i]; + var depth = vmesh.vertexDepths[i]; + Handles.Label(pos, $"{depth:0.##}"); + } + } + } + } + // root index + else if (debugSettings.rootIndex) + { + if (vmesh.IsProxy) + { + if (vmesh.vertexRootIndices.IsCreated) + { + for (int i = 0; i < vcnt; i++) + { + if (i < debugSettings.vertexMinIndex || i > debugSettings.vertexMaxIndex) + continue; + var pos = positions[vstart + i]; + int rootIndex = vmesh.vertexRootIndices[i]; + if (rootIndex >= 0) + Handles.Label(pos, $"{rootIndex}"); + } + } + } + } + // parent index + else if (debugSettings.parentIndex) + { + if (vmesh.IsProxy) + { + if (vmesh.vertexParentIndices.IsCreated) + { + for (int i = 0; i < vcnt; i++) + { + if (i < debugSettings.vertexMinIndex || i > debugSettings.vertexMaxIndex) + continue; + var pos = positions[vstart + i]; + int parentIndex = vmesh.vertexParentIndices[i]; + //if (parentIndex < 0) + Handles.Label(pos, $"{parentIndex}"); + } + } + } + } + + // triangls + if (debugSettings.triangle) + { + positionBuffer0.Clear(); + segmentBuffer0.Clear(); + + switch (vmesh.meshType) + { + case VirtualMesh.MeshType.NormalMesh: + GizmoUtility.SetColor(Color.magenta * colorScale, useHandles); + break; + case VirtualMesh.MeshType.NormalBoneMesh: + GizmoUtility.SetColor(Color.magenta * colorScale, useHandles); + break; + case VirtualMesh.MeshType.ProxyMesh: + GizmoUtility.SetColor(new Color(0.8666f, 0.627f, 0.8666f) * colorScale, useHandles); + break; + case VirtualMesh.MeshType.ProxyBoneMesh: + GizmoUtility.SetColor(new Color(0.8666f, 0.627f, 0.8666f) * colorScale, useHandles); + break; + case VirtualMesh.MeshType.Mapping: + GizmoUtility.SetColor(new Color(0.851f, 0.644f, 0.125f) * colorScale, useHandles); + break; + } + for (int i = 0; i < vmesh.TriangleCount; i++) + { + if (i < debugSettings.triangleMinIndex || i > debugSettings.triangleMaxIndex) + continue; + int3 tri = vmesh.triangles[i]; + var pos1 = positions[vstart + tri.x]; + var pos2 = positions[vstart + tri.y]; + var pos3 = positions[vstart + tri.z]; + int index = positionBuffer0.Count; + positionBuffer0.Add(pos1); + positionBuffer0.Add(pos2); + positionBuffer0.Add(pos3); + segmentBuffer0.Add(index); + segmentBuffer0.Add(index + 1); + segmentBuffer0.Add(index + 1); + segmentBuffer0.Add(index + 2); + segmentBuffer0.Add(index + 2); + segmentBuffer0.Add(index); + } + Handles.DrawLines(positionBuffer0.ToArray(), segmentBuffer0.ToArray()); + } + + // line + if (debugSettings.line) + { + positionBuffer0.Clear(); + segmentBuffer0.Clear(); + + GizmoUtility.SetColor(Color.cyan * colorScale, useHandles); + for (int i = 0; i < vmesh.LineCount; i++) + { + int2 line = vmesh.lines[i]; + var pos1 = positions[vstart + line.x]; + var pos2 = positions[vstart + line.y]; + positionBuffer0.Add(pos1); + positionBuffer0.Add(pos2); + segmentBuffer0.Add(i * 2); + segmentBuffer0.Add(i * 2 + 1); + } + Handles.DrawLines(positionBuffer0.ToArray(), segmentBuffer0.ToArray()); + } + + // edge number + if (debugSettings.edgeNumber) + { + int ecnt = vmesh.EdgeCount; + for (int i = 0; i < ecnt; i++) + { + if (i < debugSettings.edgeMinIndex || i > debugSettings.edgeMaxIndex) + continue; + int2 edge = vmesh.edges[i]; + var pos1 = positions[vstart + edge.x]; + var pos2 = positions[vstart + edge.y]; + var c = (pos1 + pos2) * 0.5f; + Handles.Label(c, i.ToString()); + } + } + + // triangle normal + if (debugSettings.triangleNormal || debugSettings.triangleNumber || debugSettings.triangleTangent) + { + positionBuffer0.Clear(); + segmentBuffer0.Clear(); + positionBuffer1.Clear(); + segmentBuffer1.Clear(); + + Color colF = Color.yellow; + Color colB = new Color(1.0f, 0.3f, 0.3f, 1.0f); + for (int i = 0; i < vmesh.TriangleCount; i++) + { + if (i < debugSettings.triangleMinIndex || i > debugSettings.triangleMaxIndex) + continue; + int3 tri = vmesh.triangles[i]; + var pos1 = positions[vstart + tri.x]; + var pos2 = positions[vstart + tri.y]; + var pos3 = positions[vstart + tri.z]; + var n = MathUtility.TriangleNormal(pos1, pos2, pos3); + var c = MathUtility.TriangleCenter(pos1, pos2, pos3); + if (debugSettings.triangleNormal) + { + //var dir = math.mul(invCamRot, n); + //GizmoUtility.SetColor((dir.z < 0.0f ? colF : colB) * colorScale, useHandles); + //GizmoUtility.DrawLine(c, c + n * drawAxisSize, useHandles); + positionBuffer0.Add(c); + positionBuffer0.Add(c + n * drawAxisSize); + segmentBuffer0.Add(i * 2); + segmentBuffer0.Add(i * 2 + 1); + } + if (debugSettings.triangleTangent && hasUv) + { + var uv1 = uvs[vstart + tri.x]; + var uv2 = uvs[vstart + tri.y]; + var uv3 = uvs[vstart + tri.z]; + var tn = MathUtility.TriangleTangent(pos1, pos2, pos3, uv1, uv2, uv3); + positionBuffer1.Add(c); + positionBuffer1.Add(c + tn * drawAxisSize); + segmentBuffer1.Add(i * 2); + segmentBuffer1.Add(i * 2 + 1); + } + if (debugSettings.triangleNumber) + Handles.Label(c, i.ToString()); + } + + if (debugSettings.triangleNormal) + { + GizmoUtility.SetColor(colF * colorScale, useHandles); + Handles.DrawLines(positionBuffer0.ToArray(), segmentBuffer0.ToArray()); + } + if (debugSettings.triangleTangent && hasUv) + { + GizmoUtility.SetColor(colB * colorScale, useHandles); + Handles.DrawLines(positionBuffer1.ToArray(), segmentBuffer1.ToArray()); + } + } + + // base line + if (vmesh.IsProxy) + { + // プロキシのみ + if (debugSettings.baseLine && vmesh.BaseLineCount > 0) + { + GizmoUtility.SetColor(new Color(1.0f, 0.27f, 0.0f) * colorScale, useHandles); + positionBuffer0.Clear(); + segmentBuffer0.Clear(); + + for (int i = 0; i < vcnt; i++) + { + int pindex = vmesh.vertexParentIndices[i]; + if (pindex >= 0) + { + var pos = positions[vstart + i]; + var ppos = positions[vstart + pindex]; + //GizmoUtility.DrawLine(pos, ppos, useHandles); + positionBuffer0.Add(pos); + positionBuffer0.Add(ppos); + segmentBuffer0.Add(i * 2); + segmentBuffer0.Add(i * 2 + 1); + } + } + Handles.DrawLines(positionBuffer0.ToArray(), segmentBuffer0.ToArray()); + } + } + + // 空間を戻す + Handles.matrix = Matrix4x4.identity; + if (useHandles == false) + Gizmos.matrix = Matrix4x4.identity; + + // bone name + if (debugSettings.boneName) + { + //int cnt = vmesh.transformData.Count; + int cnt = cmesh.GetTransformCount(); + for (int i = 0; i < cnt; i++) + { + //var t = vmesh.transformData.GetTransformFromIndex(i); + var t = cmesh.GetTransformFromIndex(i); + if (t) + { + var pos = t.position; + Handles.Label(pos, $"[{i}] {t.name}"); + } + } + } + } + } +#endif // MC_DEBUG +} diff --git a/Assets/MagicaCloth2/Scripts/Editor/Cloth/VirtualMeshEditorUtility.cs.meta b/Assets/MagicaCloth2/Scripts/Editor/Cloth/VirtualMeshEditorUtility.cs.meta new file mode 100644 index 00000000..ef05183f --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Editor/Cloth/VirtualMeshEditorUtility.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 2e052cf3e2e3eca4f9c71f84cb7712ab +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Editor/Cloth/VirtualMeshEditorUtility.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Editor/EditorExtension.meta b/Assets/MagicaCloth2/Scripts/Editor/EditorExtension.meta new file mode 100644 index 00000000..ff4c5c50 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Editor/EditorExtension.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: f7c6c164b13cbbe43afc71f44eaac1e2 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/MagicaCloth2/Scripts/Editor/EditorExtension/AboutMenu.cs b/Assets/MagicaCloth2/Scripts/Editor/EditorExtension/AboutMenu.cs new file mode 100644 index 00000000..8145c04c --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Editor/EditorExtension/AboutMenu.cs @@ -0,0 +1,96 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using UnityEditor; +using UnityEngine; + +namespace MagicaCloth2 +{ + /// + /// Aboutダイアログ + /// + public class AboutMenu : EditorWindow + { + [SerializeField] + private Texture2D image = null; + + public const string MagicaClothVersion = "2.18.1"; + + public static AboutMenu AboutWindow { get; set; } + private const float windowWidth = 300; + private const float windowHeight = 220; + + private const string webUrl = "https://magicasoft.jp/en/magica-cloth-2-2/"; + + //========================================================================================= + [MenuItem("Tools/Magica Cloth2/About", false)] + static void InitWindow() + { + if (AboutWindow) + return; + AboutWindow = CreateInstance(); + AboutWindow.position = new Rect(Screen.width / 2, Screen.height / 2, windowWidth, windowHeight); + AboutWindow.minSize = new Vector2(windowWidth, windowHeight); + AboutWindow.maxSize = new Vector2(windowWidth, windowHeight); + AboutWindow.titleContent.text = "About Magica Cloth 2"; + AboutWindow.ShowUtility(); + } + + protected void OnGUI() + { + EditorGUILayout.Space(); + EditorGUILayout.Space(); + EditorGUILayout.Space(); + + GUIStyle myStyle = new GUIStyle(); + myStyle.alignment = TextAnchor.MiddleCenter; + myStyle.fontSize = 20; + myStyle.normal.textColor = Color.white; + + GUILayout.Box(image, myStyle); + + EditorGUILayout.Space(); + + EditorGUILayout.LabelField("Magica Cloth 2", myStyle); + + EditorGUILayout.Space(5); + myStyle.fontSize = 16; + EditorGUILayout.LabelField($"version {MagicaClothVersion}", myStyle); + + EditorGUILayout.Space(); + EditorGUILayout.Space(); + EditorGUILayout.Space(); + myStyle.fontSize = 12; + EditorGUILayout.LabelField("Copyright © Magica Soft", myStyle); + EditorGUILayout.LabelField("All Rights Reserved", myStyle); + + //EditorGUILayout.LabelField(webUrl, myStyle); + + EditorGUILayout.Space(); + EditorGUILayout.Space(); + + using (var h = new EditorGUILayout.HorizontalScope()) + { + EditorGUILayout.Space(); + if (GUILayout.Button("Website")) + { + Application.OpenURL(webUrl); + } + + EditorGUILayout.Space(); + + if (GUILayout.Button("Close")) + { + Close(); + } + + EditorGUILayout.Space(); + } + } + + protected void OnInspectorUpdate() + { + Repaint(); + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Editor/EditorExtension/AboutMenu.cs.meta b/Assets/MagicaCloth2/Scripts/Editor/EditorExtension/AboutMenu.cs.meta new file mode 100644 index 00000000..c482a2db --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Editor/EditorExtension/AboutMenu.cs.meta @@ -0,0 +1,20 @@ +fileFormatVersion: 2 +guid: 059c4023f8428864e994f30573930854 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: + - m_ViewDataDictionary: {instanceID: 0} + - image: {fileID: 2800000, guid: cf7e3400035e987478c3a19e57b4cf75, type: 3} + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Editor/EditorExtension/AboutMenu.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Editor/EditorExtension/CheckSliderSerializeDataDrawer.cs b/Assets/MagicaCloth2/Scripts/Editor/EditorExtension/CheckSliderSerializeDataDrawer.cs new file mode 100644 index 00000000..60209a51 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Editor/EditorExtension/CheckSliderSerializeDataDrawer.cs @@ -0,0 +1,60 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using UnityEditor; +using UnityEngine; + +namespace MagicaCloth2 +{ + /// + /// CheckSliderSerializeDataプロパティのカスタムGUI描画 + /// + [CustomPropertyDrawer(typeof(CheckSliderSerializeData))] + public class CheckSliderSerializeDataDrawer : PropertyDrawer + { + public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) + { + // サイズ + float lineHight = EditorGUIUtility.singleLineHeight; + float y = position.y; + + EditorGUI.BeginProperty(position, label, property); + + // プロパティ + var useProperty = property.FindPropertyRelative("use"); + var valueProperty = property.FindPropertyRelative("value"); + + // ラベルを描画 + Rect positionA; + using (new EditorGUI.DisabledScope(!useProperty.boolValue)) + { + positionA = EditorGUI.PrefixLabel(position, GUIUtility.GetControlID(FocusType.Passive), label); + } + + // 子のフィールドをインデントしない + var indent = EditorGUI.indentLevel; + EditorGUI.indentLevel = 0; + + // 設定値の範囲。プロパティ名から判定する + var minmax = MagicaClothEditor.GetPropertyMinMax(property.name); + + // 矩形を計算 + float w = positionA.width; + const float toggleSize = 20; + var buttonRect = new Rect(positionA.x, y, toggleSize, lineHight); + var sliderRect = new Rect(positionA.x + toggleSize, y, Mathf.Max(w - toggleSize, 0), lineHight); + + // GUIContent.none をそれぞれに渡すと、ラベルなしに描画されます + EditorGUI.PropertyField(buttonRect, useProperty, GUIContent.none); + using (new EditorGUI.DisabledScope(!useProperty.boolValue)) + { + EditorGUI.Slider(sliderRect, valueProperty, minmax.x, minmax.y, GUIContent.none); + } + + // インデントを元通りに戻します + EditorGUI.indentLevel = indent; + + EditorGUI.EndProperty(); + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Editor/EditorExtension/CheckSliderSerializeDataDrawer.cs.meta b/Assets/MagicaCloth2/Scripts/Editor/EditorExtension/CheckSliderSerializeDataDrawer.cs.meta new file mode 100644 index 00000000..00a84283 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Editor/EditorExtension/CheckSliderSerializeDataDrawer.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: b3fa2fcfdd75dbb48b7566213e81bb9a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Editor/EditorExtension/CheckSliderSerializeDataDrawer.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Editor/EditorExtension/CurveSerializeDataDrawer.cs b/Assets/MagicaCloth2/Scripts/Editor/EditorExtension/CurveSerializeDataDrawer.cs new file mode 100644 index 00000000..7bbdb198 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Editor/EditorExtension/CurveSerializeDataDrawer.cs @@ -0,0 +1,80 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using UnityEditor; +using UnityEngine; + +namespace MagicaCloth2 +{ + /// + /// CurveSerializeDataプロパティのカスタムGUI描画 + /// + [CustomPropertyDrawer(typeof(CurveSerializeData))] + public class CurveSerializeDataDrawer : PropertyDrawer + { + public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) + { + // サイズ + float lineHight = EditorGUIUtility.singleLineHeight; + float y = position.y; + + EditorGUI.BeginProperty(position, label, property); + + // ラベルを描画 + var positionA = EditorGUI.PrefixLabel(position, GUIUtility.GetControlID(FocusType.Passive), label); + + // 子のフィールドをインデントしない + var indent = EditorGUI.indentLevel; + EditorGUI.indentLevel = 0; + + // プロパティ + var useProperty = property.FindPropertyRelative("useCurve"); + var valueProperty = property.FindPropertyRelative("value"); + bool useCurve = useProperty.boolValue; + + // 設定値の範囲。プロパティ名から判定する + //var minmax = ClothSerializeData.GetMinMax(property.name); + var minmax = MagicaClothEditor.GetPropertyMinMax(property.name); + + // 矩形を計算 + float w = positionA.width; + var buttonRect = new Rect(positionA.x + w - 30, y, 30, lineHight); + var sliderRect = new Rect(positionA.x, y, Mathf.Max(w - 35, 0), lineHight); + + // GUIContent.none をそれぞれに渡すと、ラベルなしに描画されます + EditorGUI.Slider(sliderRect, valueProperty, minmax.x, minmax.y, GUIContent.none); + if (GUI.Button(buttonRect, useProperty.boolValue ? "X" : "C")) + { + // カーブ切り替え + useProperty.boolValue = !useProperty.boolValue; + } + + // カーブ + if (useCurve) + { + // カーブプロパティ + var curveProperty = property.FindPropertyRelative("curve"); + y += lineHight + 3; + //var curveRect = new Rect(positionA.x - 15, y, w + 15, lineHight); + var curveRect = new Rect(positionA.x, y, w, lineHight); + EditorGUI.CurveField(curveRect, curveProperty, Color.green, new Rect(0, 0, 1, 1), GUIContent.none); + } + + // インデントを元通りに戻します + EditorGUI.indentLevel = indent; + + EditorGUI.EndProperty(); + } + + public override float GetPropertyHeight(SerializedProperty property, GUIContent label) + { + float h = EditorGUIUtility.singleLineHeight; + + var useProperty = property.FindPropertyRelative("useCurve"); + if (useProperty.boolValue) + h += (h + 3 + 2); + + return h; + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Editor/EditorExtension/CurveSerializeDataDrawer.cs.meta b/Assets/MagicaCloth2/Scripts/Editor/EditorExtension/CurveSerializeDataDrawer.cs.meta new file mode 100644 index 00000000..489c3f37 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Editor/EditorExtension/CurveSerializeDataDrawer.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: a43f33abae2910246b917331abff6706 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Editor/EditorExtension/CurveSerializeDataDrawer.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Editor/EditorExtension/DrawIconInHierarchy.cs b/Assets/MagicaCloth2/Scripts/Editor/EditorExtension/DrawIconInHierarchy.cs new file mode 100644 index 00000000..6cf496ba --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Editor/EditorExtension/DrawIconInHierarchy.cs @@ -0,0 +1,75 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using UnityEditor; +using UnityEngine; + +namespace MagicaCloth2 +{ + /// + /// ヒエラルキーへアイコンの表示 + /// + [InitializeOnLoad] + public class DrawIconInHierarchy + { + const int iconSize = 16; + + static DrawIconInHierarchy() + { +#if UNITY_6000_4_OR_NEWER + EditorApplication.hierarchyWindowItemByEntityIdOnGUI += DrawIcon; +#else + EditorApplication.hierarchyWindowItemOnGUI += DrawIcon; +#endif + } + + //static void DrawIcon(int instanceId, Rect rect) +#if UNITY_6000_4_OR_NEWER + static void DrawIcon(EntityId instanceId, Rect rect) +#else + static void DrawIcon(int instanceId, Rect rect) +#endif + { + rect.width = iconSize; +#if UNITY_6000_3_OR_NEWER + GameObject obj = UnityEditor.EditorUtility.EntityIdToObject(instanceId) as GameObject; +#else + GameObject obj = UnityEditor.EditorUtility.InstanceIDToObject(instanceId) as GameObject; +#endif + if (obj == null) + return; + rect.x += EditorStyles.label.CalcSize(obj.name).x; + rect.y += -1; + rect.x += iconSize + 4; + + foreach (var component in obj.GetComponents()) + { + if (component is MagicaSphereCollider + || component is MagicaCapsuleCollider + || component is MagicaPlaneCollider + || component is MagicaCloth + || component is MagicaWindZone + || component is MagicaSettings + ) + { + var icon = AssetPreview.GetMiniThumbnail(component); + GUI.Label(rect, icon); + rect.x += iconSize; + } + } + } + } + + /// + /// テキストのサイズを取得 + /// + public static class GUIStyleExtensions + { + public static Vector2 CalcSize(this GUIStyle self, string text) + { + var content = new GUIContent(text); + var size = self.CalcSize(content); + return size; + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Editor/EditorExtension/DrawIconInHierarchy.cs.meta b/Assets/MagicaCloth2/Scripts/Editor/EditorExtension/DrawIconInHierarchy.cs.meta new file mode 100644 index 00000000..4b4ec45e --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Editor/EditorExtension/DrawIconInHierarchy.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 3c7a0c2cbd41e2a4b93ab9b238dfcf08 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Editor/EditorExtension/DrawIconInHierarchy.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Editor/EditorExtension/MenuItemScript.cs b/Assets/MagicaCloth2/Scripts/Editor/EditorExtension/MenuItemScript.cs new file mode 100644 index 00000000..10fa83d2 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Editor/EditorExtension/MenuItemScript.cs @@ -0,0 +1,222 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using System; +using System.IO; +using System.Text; +using UnityEditor; +using UnityEngine; + +namespace MagicaCloth2 +{ + public class MenuItemScript + { + //========================================================================================= + [MenuItem("GameObject/Create Other/Magica Cloth2/Magica Cloth", priority = 200)] + static void AddMagicaCloth() + { + var obj = AddObject("Magica Cloth", false, false); + var comp = obj.AddComponent(); + Selection.activeGameObject = obj; + } + + [MenuItem("GameObject/Create Other/Magica Cloth2/Magica Sphere Collider", priority = 200)] + static void AddSphereCollider() + { + var obj = AddObject("Magica Sphere Collider", true, true); + var comp = obj.AddComponent(); + //comp.size = new Vector3(0.1f, 0.1f, 0.1f); + comp.SetSize(new Vector3(0.1f, 0.1f, 0.1f)); + Selection.activeGameObject = obj; + } + + [MenuItem("GameObject/Create Other/Magica Cloth2/Magica Capsule Collider", priority = 200)] + static void AddCapsuleCollider() + { + var obj = AddObject("Magica Capsule Collider", true, true); + var comp = obj.AddComponent(); + //comp.size = new Vector3(0.05f, 0.05f, 0.3f); + comp.SetSize(new Vector3(0.05f, 0.05f, 0.3f)); + comp.direction = MagicaCapsuleCollider.Direction.Y; + comp.radiusSeparation = false; + Selection.activeGameObject = obj; + } + + [MenuItem("GameObject/Create Other/Magica Cloth2/Magica Plane Collider", priority = 200)] + static void AddPlaneCollider() + { + var obj = AddObject("Magica Plane Collider", true, true); + var comp = obj.AddComponent(); + Selection.activeGameObject = obj; + } + + [MenuItem("GameObject/Create Other/Magica Cloth2/Magica Wind Zone", priority = 200)] + static void AddWindZone() + { + var obj = AddObject("Magica Wind Zone", false, true); + var comp = obj.AddComponent(); + Selection.activeGameObject = obj; + } + + [MenuItem("GameObject/Create Other/Magica Cloth2/Magica Settings", priority = 200)] + static void AddSettings() + { + var obj = AddObject("Magica Settings", false, true); + var comp = obj.AddComponent(); + Selection.activeGameObject = obj; + } + + /// + /// ヒエラルキーにオブジェクトを1つ追加する + /// + /// + /// + static GameObject AddObject(string objName, bool addParentName, bool autoScale = false) + { + var parent = Selection.activeGameObject; + + GameObject obj = new GameObject(addParentName && parent ? objName + " (" + parent.name + ")" : objName); + if (parent) + { + obj.transform.parent = parent.transform; + } + obj.transform.SetLocalPositionAndRotation(Vector3.zero, Quaternion.identity); + + if (autoScale && parent) + { + var scl = parent.transform.lossyScale; + obj.transform.localScale = new Vector3(1.0f / scl.x, 1.0f / scl.y, 1.0f / scl.z); + } + else + obj.transform.localScale = Vector3.one; + + return obj; + } + + //========================================================================================= + [MenuItem("Tools/Magica Cloth2/Manager information", false)] + static async void DispClothManagerInfo() + { + StringBuilder allsb = new StringBuilder(); + + await ClothEditorManager.InformationLog(allsb); + + var timeManager = MagicaManager.Time; + if (timeManager == null) + { + Debug.LogWarning("Time Manager is null!"); + } + else + { + timeManager.InformationLog(allsb); + } + + var teamManager = MagicaManager.Team; + if (teamManager == null) + { + Debug.LogWarning("Team Manager is null!"); + } + else + { + teamManager.InformationLog(allsb); + } + + var vmeshManager = MagicaManager.VMesh; + if (vmeshManager == null) + { + Debug.LogWarning("VMesh Manager is null!"); + } + else + { + vmeshManager.InformationLog(allsb); + } + + var transformManager = MagicaManager.Bone; + if (transformManager == null) + { + Debug.LogWarning("Transform Manager is null!"); + } + else + { + transformManager.InformationLog(allsb); + } + + var simulationManager = MagicaManager.Simulation; + if (simulationManager == null) + { + Debug.LogWarning("Simulation Manager is null!"); + } + else + { + simulationManager.InformationLog(allsb); + } + + var colliderManager = MagicaManager.Collider; + if (colliderManager == null) + { + Debug.LogWarning("Collider Manager is null!"); + } + else + { + colliderManager.InformationLog(allsb); + } + + var windManager = MagicaManager.Wind; + if (windManager == null) + { + Debug.LogWarning("Wind Manager is null!"); + } + else + { + windManager.InformationLog(allsb); + } + + var renderManager = MagicaManager.Render; + if (renderManager == null) + { + Debug.LogWarning("Renderer Manager is null!"); + } + else + { + renderManager.InformationLog(allsb); + } + + var preBuildManager = MagicaManager.PreBuild; + if (preBuildManager == null) + { + Debug.LogWarning("PreBuild Manager is null!"); + } + else + { + preBuildManager.InformationLog(allsb); + } + + // file + DateTime dt = DateTime.Now; + var filename = dt.ToString("yyyy-MM-dd-HHmm-ss"); + StreamWriter sw = new StreamWriter($"./MagicaCloth2_SysInfo_{filename}.txt", false); + sw.WriteLine(allsb.ToString()); + sw.Flush(); + sw.Close(); + } + + //========================================================================================= + // インスペクターのコンテキストメニュー + [MenuItem("CONTEXT/MagicaCloth/Rebuild InitData")] + private static void SampleMenu(MenuCommand menuCommand) + { + // 初期化データをクリアして再構築する + var cloth = menuCommand.context as MagicaCloth; + if (cloth) + { + cloth.GetSerializeData2().initData.Clear(); + EditorUtility.SetDirty(cloth); + + // 編集用メッシュの再構築 + ClothEditorManager.RegisterComponent(cloth, GizmoType.Active, true); // 強制更新 + + Develop.Log($"[{cloth.name}] Initialization data rebuilt."); + } + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Editor/EditorExtension/MenuItemScript.cs.meta b/Assets/MagicaCloth2/Scripts/Editor/EditorExtension/MenuItemScript.cs.meta new file mode 100644 index 00000000..655d50c4 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Editor/EditorExtension/MenuItemScript.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 160a2e4af5a88d34695643fc38100749 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Editor/EditorExtension/MenuItemScript.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Editor/EditorExtension/SharePreBuildDataDrawer.cs b/Assets/MagicaCloth2/Scripts/Editor/EditorExtension/SharePreBuildDataDrawer.cs new file mode 100644 index 00000000..8812fcb0 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Editor/EditorExtension/SharePreBuildDataDrawer.cs @@ -0,0 +1,76 @@ +// Magica Cloth 2. +// Copyright (c) 2024 MagicaSoft. +// https://magicasoft.jp +using UnityEditor; +using UnityEngine; + +namespace MagicaCloth2 +{ + [CustomPropertyDrawer(typeof(SharePreBuildData))] + public class SharePreBuildDataDrawer : PropertyDrawer + { + public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) + { + EditorGUI.BeginProperty(position, label, property); + + // サイズ + float lineHight = EditorGUIUtility.singleLineHeight; + + // 子のフィールドをインデントしない + var indent = EditorGUI.indentLevel; + EditorGUI.indentLevel = 0; + + var buildIdProperty = property.FindPropertyRelative("buildId"); + var versionProperty = property.FindPropertyRelative("version"); + var resultProperty = property.FindPropertyRelative("buildResult.result"); + + // テキスト幅調整 + EditorGUIUtility.labelWidth = position.width; + + // build Id + string buildId = string.IsNullOrEmpty(buildIdProperty.stringValue) ? "(Empty)" : buildIdProperty.stringValue; + EditorGUI.PrefixLabel(position, GUIUtility.GetControlID(FocusType.Passive), new GUIContent(buildId)); + position.y += lineHight; + + // インデント+1 + EditorGUI.indentLevel = indent + 1; + + // result + Define.Result ret = (Define.Result)resultProperty.enumValueIndex; + var result = new ResultCode(ret); + if (result.IsFaild() == false) + { + // バージョン確認 + if (versionProperty.intValue != Define.System.LatestPreBuildVersion) + result.SetError(Define.Result.PreBuildData_VersionMismatch); + } + + // result text + var backColor = GUI.color; + if (result.IsSuccess()) + { + GUI.color = Color.green; + EditorGUI.PrefixLabel(position, GUIUtility.GetControlID(FocusType.Passive), new GUIContent($"{result.Result}")); + } + else + { + GUI.color = Color.red; + EditorGUI.PrefixLabel(position, GUIUtility.GetControlID(FocusType.Passive), new GUIContent($"Error: {result.Result}")); + } + GUI.color = backColor; + + // インデントを元通りに戻します + EditorGUI.indentLevel = indent; + + EditorGUI.EndProperty(); + } + + public override float GetPropertyHeight(SerializedProperty property, GUIContent label) + { + float h = EditorGUIUtility.singleLineHeight; + h *= 2; + + return h; + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Editor/EditorExtension/SharePreBuildDataDrawer.cs.meta b/Assets/MagicaCloth2/Scripts/Editor/EditorExtension/SharePreBuildDataDrawer.cs.meta new file mode 100644 index 00000000..c5290e18 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Editor/EditorExtension/SharePreBuildDataDrawer.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: c6706416db7bdd14cb7ed3f5195d6498 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Editor/EditorExtension/SharePreBuildDataDrawer.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Editor/Gizmos.meta b/Assets/MagicaCloth2/Scripts/Editor/Gizmos.meta new file mode 100644 index 00000000..c422cca1 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Editor/Gizmos.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: babc161c3f4373948b6d24be361d41e2 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/MagicaCloth2/Scripts/Editor/Gizmos/GizmoUtility.cs b/Assets/MagicaCloth2/Scripts/Editor/Gizmos/GizmoUtility.cs new file mode 100644 index 00000000..4acc4bb5 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Editor/Gizmos/GizmoUtility.cs @@ -0,0 +1,693 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using Unity.Mathematics; +using UnityEditor; +using UnityEngine; + +namespace MagicaCloth2 +{ + public static class GizmoUtility + { + // ギズモカラー定義 + public static readonly Color ColorCollider = new Color(0.0f, 1.0f, 0.0f); + public static readonly Color ColorSymmetryCollider = new Color(0.0f, 1.0f, 1.0f); + public static readonly Color ColorNonSelectedCollider = new Color(0.5f, 0.3f, 0.0f); + public static readonly Color ColorSkinningBone = new Color(1.0f, 0.5f, 0.0f); + public static readonly Color ColorWindZone = new Color(1f, 1f, 1f); + public static readonly Color ColorWindArrow = new Color(1f, 1f, 0f); + + public static readonly Quaternion FlipZ = Quaternion.AngleAxis(180.0f, Vector3.up); + + //========================================================================================= + public static void SetColor(Color col, bool useHandles) + { + if (useHandles) + Handles.color = col; + else + Gizmos.color = col; + } + + public static void DrawSphere(Vector3 pos, float radius, bool useHandles) + { + if (useHandles) + { + // ソリッド球のサイズ指定は半径ではなく直径なので2倍する + Handles.SphereHandleCap(0, pos, Quaternion.identity, radius * 2, EventType.Repaint); + } + else + Gizmos.DrawSphere(pos, radius); + } + + public static void DrawWireSphere(Vector3 pos, Quaternion rot, float radius, Quaternion camRot, bool useHandles) + { + if (useHandles) + { + Handles.CircleHandleCap(0, pos, camRot, radius, EventType.Repaint); + Handles.CircleHandleCap(0, pos, rot, radius, EventType.Repaint); + Handles.CircleHandleCap(0, pos, rot * Quaternion.Euler(90, 0, 0), radius, EventType.Repaint); + Handles.CircleHandleCap(0, pos, rot * Quaternion.Euler(0, 90, 0), radius, EventType.Repaint); + } + else + Gizmos.DrawWireSphere(pos, radius); + } + + public static void DrawSimpleWireSphere(Vector3 pos, float radius, Quaternion camRot, bool useHandles) + { + if (useHandles) + { + Handles.CircleHandleCap(0, pos, camRot, radius, EventType.Repaint); + //Handles.CircleHandleCap(0, pos, rot, radius, EventType.Repaint); + //Handles.CircleHandleCap(0, pos, rot * Quaternion.Euler(90, 0, 0), radius, EventType.Repaint); + //Handles.CircleHandleCap(0, pos, rot * Quaternion.Euler(0, 90, 0), radius, EventType.Repaint); + } + else + Gizmos.DrawWireSphere(pos, radius); + } + + public static void DrawLine(Vector3 from, Vector3 to, bool useHandles) + { + if (useHandles) + Handles.DrawLine(from, to); + else + Gizmos.DrawLine(from, to); + } + + public static void DrawWireCapsule(Vector3 pos, Quaternion rot, Vector3 dir, Vector3 up, float sradius, float eradius, float len, bool alignedCenter, Quaternion camRot, bool useHandles) + { + if (useHandles) + { + //float slen = len * 0.5f; + //float elen = len * 0.5f; + float slen = alignedCenter ? len * 0.5f : 0.0f; + float elen = alignedCenter ? len * 0.5f : (len - sradius); + slen = Mathf.Max(slen - sradius, 0.0f); + elen = Mathf.Max(elen - eradius, 0.0f); + Vector3 sl = dir * slen; + Vector3 el = -dir * elen; + + var spos = pos + rot * sl; + var epos = pos + rot * el; + + DrawWireSphere(spos, rot, sradius, camRot, true); + DrawWireSphere(epos, rot, eradius, camRot, true); + + for (int i = 0; i < 360; i += 45) + { + var q = Quaternion.AngleAxis(i, dir); + var up1 = q * (up * sradius); + var up2 = q * (up * eradius); + Handles.DrawLine(spos + up1, epos + up2); + } + } + else + { + + } + } + //public static void DrawWireCapsule(Vector3 spos, Vector3 epos, Quaternion rot, float sradius, float eradius, Quaternion camRot, bool useHandles) + //{ + // if (useHandles) + // { + // DrawWireSphere(spos, rot, sradius, camRot, true); + // DrawWireSphere(epos, rot, eradius, camRot, true); + + // var ps = spos + camRot * Vector3.up * sradius; + // var es = epos + camRot * Vector3.up * eradius; + // Handles.DrawLine(ps, es); + // } + // else + // { + + // } + //} + + /// + /// ワイヤーボックスを描画する + /// + /// + /// + /// + /// + public static void DrawWireCube(Vector3 pos, Quaternion rot, Vector3 size, bool useHandles) + { + if (useHandles) + { + Handles.DrawWireCube(pos, size); // 何故かカラーが反映しない!バグっぽい + } + else + { + Gizmos.DrawWireCube(pos, size); + } + } + + public static void DrawCross(Vector3 pos, Quaternion rot, float size, bool useHandles) + { + if (useHandles) + { + Handles.color = Color.red; + Handles.DrawLine(pos, pos + rot * Vector3.right * size); + Handles.color = Color.green; + Handles.DrawLine(pos, pos + rot * Vector3.up * size); + Handles.color = Color.blue; + Handles.DrawLine(pos, pos + rot * Vector3.forward * size); + } + else + { + Gizmos.color = Color.red; + Gizmos.DrawLine(pos, pos + rot * Vector3.right * size); + Gizmos.color = Color.green; + Gizmos.DrawLine(pos, pos + rot * Vector3.up * size); + Gizmos.color = Color.blue; + Gizmos.DrawLine(pos, pos + rot * Vector3.forward * size); + } + } + + //========================================================================================= + public static void DrawCollider(ColliderComponent collider, Quaternion camRot, bool selected) + { + if (collider == null) + return; + + Handles.color = selected ? ColorCollider : ColorCollider * 0.5f; + + // Main + var ct = collider.transform; + //var cpos = ct.TransformPoint(collider.center); + float3 cpos = ct.position; + quaternion crot = ct.rotation; + float3 cscl = ct.lossyScale; + // マイナススケール + float3 sclSign = math.sign(cscl); + // オフセット + cpos += math.mul(crot, collider.center * sclSign) * cscl * sclSign; + // カメラ回転をコライダーのローカル回転に変換 + var camRotN = Quaternion.Inverse(crot) * camRot; + DrawColliderInternal(collider, camRotN, cpos, crot, cscl, 1.0f); + + // Symmetry + // 実行時と同じ計算をして表示 + ColliderSymmetryMode? smode = ColliderSymmetryMode.None; + Transform symmetryParent = null; + if (EditorApplication.isPlaying) + { + smode = collider.ActiveSymmetryMode; + symmetryParent = collider.ActiveSymmetryTarget; + } + if (smode.HasValue == false || smode == ColliderSymmetryMode.None) + smode = collider.CalcSymmetryMode(out symmetryParent); + if (smode != ColliderSymmetryMode.None && symmetryParent) + { + float3 lpos = ct.localPosition; + //float3 lerot = ct.localEulerAngles; + float3 lerot = MathUtility.ToEuler(ct.localRotation); + float3 lscl = ct.localScale; + float3 center = collider.center; + switch (smode) + { + case ColliderSymmetryMode.X_Symmetry: + lpos.x = -lpos.x; + center.x = -center.x; + lerot.y = -lerot.y; + lerot.z = -lerot.z; + break; + case ColliderSymmetryMode.Y_Symmetry: + lpos.y = -lpos.y; + center.y = -center.y; + lerot.x = -lerot.x; + lerot.z = -lerot.z; + break; + case ColliderSymmetryMode.Z_Symmetry: + lpos.z = -lpos.z; + center.z = -center.z; + lerot.x = -lerot.x; + lerot.y = -lerot.y; + break; + case ColliderSymmetryMode.XYZ_Symmetry: + lpos = -lpos; + center = -center; + break; + default: + return; + } + + // 方向性 + float direction = 1.0f; + if (collider is MagicaCapsuleCollider) + { + var ccol = collider as MagicaCapsuleCollider; + if (smode == ColliderSymmetryMode.X_Symmetry && ccol.direction == MagicaCapsuleCollider.Direction.X) + direction = -1.0f; + else if (smode == ColliderSymmetryMode.Y_Symmetry && ccol.direction == MagicaCapsuleCollider.Direction.Y) + direction = -1.0f; + else if (smode == ColliderSymmetryMode.Z_Symmetry && ccol.direction == MagicaCapsuleCollider.Direction.Z) + direction = -1.0f; + else if (smode == ColliderSymmetryMode.XYZ_Symmetry) + direction = -1.0f; + } + else if (collider is MagicaPlaneCollider) + { + switch (smode) + { + case ColliderSymmetryMode.Y_Symmetry: + case ColliderSymmetryMode.XYZ_Symmetry: + direction = -1.0f; + break; + } + } + + // シンメトリーの親 + float3 ppos = symmetryParent.position; + quaternion prot = symmetryParent.rotation; + float3 pscl = symmetryParent.lossyScale; + + // マイナススケール + sclSign = math.sign(pscl); + float3 sclEulerSign = 1; + if (pscl.x < 0 || pscl.y < 0 || pscl.z < 0) + sclEulerSign = sclSign * -1; + + // シンメトリーコライダーの姿勢 + float3 wpos = MathUtility.TransformPoint(lpos, ppos, prot, pscl); + quaternion wrot = math.mul(prot, quaternion.Euler(math.radians(lerot * sclEulerSign))); + float3 wscl = pscl * lscl; + wpos += math.mul(wrot, center * sclSign) * wscl * sclSign; + + // カメラ回転をコライダーのローカル回転に変換 + var camRotS = Quaternion.Inverse(wrot) * camRot; + + Handles.color = selected ? ColorSymmetryCollider : ColorSymmetryCollider * 0.5f; + DrawColliderInternal(collider, camRotS, wpos, wrot, wscl, direction); + } + } + + static void DrawColliderInternal(ColliderComponent collider, Quaternion camRot, Vector3 cpos, Quaternion crot, Vector3 cscl, float direction) + { + var size = collider.GetSize(); + Handles.matrix = Matrix4x4.TRS(cpos, crot, cscl); + if (collider is MagicaSphereCollider) + { + DrawWireSphere(Vector3.zero, Quaternion.identity, size.x, camRot, true); + } + else if (collider is MagicaPlaneCollider) + { + DrawWireCube(Vector3.zero, Quaternion.identity, new Vector3(1.0f, 0.0f, 1.0f) * 1.0f, true); + DrawLine(Vector3.zero, 0.25f * direction * Vector3.up, true); + } + else if (collider is MagicaCapsuleCollider) + { + var c = collider as MagicaCapsuleCollider; + var ldir = c.GetLocalDir() * direction; + var lup = c.GetLocalUp(); + DrawWireCapsule(Vector3.zero, Quaternion.identity, ldir, lup, size.x, size.y, size.z, c.alignedOnCenter, camRot, true); + } + } + + /// + /// ワイヤーカプセルを描画する + /// UnityのCapsuleColliderと同じ + /// + /// 基準座標 + /// 基準回転 + /// カプセルの方向 + /// カプセルの上方向 + /// カプセルの長さ + /// 始点の半径 + /// 終点の半径 + public static void DrawWireCapsule( + Vector3 pos, Quaternion rot, Vector3 scl, + Vector3 ldir, Vector3 lup, + float length, float startRadius, float endRadius, + bool resetMatrix = true + ) + { + Gizmos.matrix = Matrix4x4.TRS(pos, rot, scl); + float slen = length * 0.5f; + float elen = length * 0.5f; + slen = Mathf.Max(slen - startRadius, 0.0f); + elen = Mathf.Max(elen - endRadius, 0.0f); + var sl = ldir * slen; + var el = -ldir * elen; + Gizmos.DrawWireSphere(sl, startRadius); + Gizmos.DrawWireSphere(el, endRadius); + + for (int i = 0; i < 360; i += 45) + { + var q = Quaternion.AngleAxis(i, ldir); + var up1 = q * (lup * startRadius); + var up2 = q * (lup * endRadius); + Gizmos.DrawLine(sl + up1, el + up2); + } + + // 45度ずらしてもう1回球を描く + Gizmos.matrix = Matrix4x4.TRS(pos, rot * Quaternion.AngleAxis(45, ldir), scl); + Gizmos.DrawWireSphere(sl, startRadius); + Gizmos.DrawWireSphere(el, endRadius); + + if (resetMatrix) + Gizmos.matrix = Matrix4x4.identity; + } + + /// + /// ワイヤー球を描画する + /// UnityのSphereColliderと同じ + /// + /// 基準座標 + /// 基準回転 + /// 半径 + /// + public static void DrawWireSphere( + Vector3 pos, Quaternion rot, Vector3 scl, float radius, + bool drawSphere, bool drawAxis, + bool resetMatrix = true) + { + //Gizmos.matrix = Matrix4x4.TRS(pos, rot, Vector3.one); + Gizmos.matrix = Matrix4x4.TRS(pos, rot, scl); + + // 球 + if (drawSphere) + Gizmos.DrawWireSphere(Vector3.zero, radius); + + // 軸 + if (drawAxis) + { + const float axisRadius = 0.03f; + Gizmos.color = Color.red; + Gizmos.DrawLine(Vector3.zero, Vector3.right * axisRadius); + Gizmos.color = Color.green; + Gizmos.DrawLine(Vector3.zero, Vector3.up * axisRadius); + Gizmos.color = Color.blue; + Gizmos.DrawLine(Vector3.zero, Vector3.forward * axisRadius); + } + + // 45度ずらしてもう1回球を描く + //Gizmos.matrix = Matrix4x4.TRS(pos, rot * Quaternion.AngleAxis(45, Vector3.up), Vector3.one); + //Gizmos.DrawWireSphere(Vector3.zero, radius); + + if (resetMatrix) + Gizmos.matrix = Matrix4x4.identity; + } + +#if false + /// + /// ワイヤーボックスを描画する + /// + /// + /// + /// + /// + public static void DrawWireCube(Vector3 pos, Quaternion rot, Vector3 size, bool resetMatrix = true) + { + Gizmos.matrix = Matrix4x4.TRS(pos, rot, Vector3.one); + Gizmos.DrawWireCube(Vector3.zero, size); + if (resetMatrix) + Gizmos.matrix = Matrix4x4.identity; + } +#endif + + public static void DrawWireCone(Vector3 pos, Quaternion rot, float length, float radius, int div = 8) + { + Gizmos.matrix = Matrix4x4.TRS(pos, rot, Vector3.one); + var epos = Vector3.forward * length; + Vector3 oldpos = epos; + for (int i = 0; i < div; i++) + { + float t = (float)i / (float)div; + var q = Quaternion.AngleAxis(t * 360.0f, Vector3.forward); + var x = q * Vector3.right * radius; + Gizmos.DrawLine(Vector3.zero, epos + x); + Gizmos.DrawLine(epos, epos + x); + + if (i > 0) + Gizmos.DrawLine(oldpos, epos + x); + + oldpos = epos + x; + } + + Gizmos.DrawLine(oldpos, epos + Vector3.right * radius); + + + Gizmos.matrix = Matrix4x4.identity; + } + + /// + /// ワイヤー矢印を描画する + /// + /// + /// + /// + /// 十字描画 + public static void DrawWireArrow(Vector3 pos, Quaternion rot, Vector3 size, bool cross = false) + { + //Gizmos.matrix = Matrix4x4.TRS(pos, rot, size); + Handles.matrix = Matrix4x4.TRS(pos, rot, size); + + Vector3[] points = new Vector3[] + { + new Vector3(0.0f, 0.0f, -1.0f), + new Vector3(0.0f, 0.5f, -1.0f), + new Vector3(0.0f, 0.5f, 0.0f), + new Vector3(0.0f, 1.0f, 0.0f), + new Vector3(0.0f, 0.0f, 1.0f), + }; + + float addAngle = cross ? 90.0f : 180.0f; + int loop = cross ? 4 : 2; + + for (int j = 0; j < loop; j++) + { + for (int i = 0; i < points.Length - 1; i++) + { + //Gizmos.DrawLine(points[i], points[i + 1]); + Handles.DrawLine(points[i], points[i + 1]); + } + + rot = rot * Quaternion.AngleAxis(addAngle, Vector3.forward); + //Gizmos.matrix = Matrix4x4.TRS(pos, rot, size); + Handles.matrix = Matrix4x4.TRS(pos, rot, size); + } + + //Gizmos.matrix = Matrix4x4.identity; + Handles.matrix = Matrix4x4.identity; + } + + /// + /// XYZ軸を描画する + /// + /// + /// + /// + /// + public static void DrawAxis(Vector3 pos, Quaternion rot, float size, bool resetMatrix = true) + { + Gizmos.matrix = Matrix4x4.TRS(pos, rot, Vector3.one); + Gizmos.color = Color.red; + Gizmos.DrawRay(Vector3.zero, Vector3.right * size); + Gizmos.color = Color.green; + Gizmos.DrawRay(Vector3.zero, Vector3.up * size); + Gizmos.color = Color.blue; + Gizmos.DrawRay(Vector3.zero, Vector3.forward * size); + if (resetMatrix) + Gizmos.matrix = Matrix4x4.identity; + } + + /// + /// ボーン形状を描画する + /// + /// + /// + /// + public static void DrawBone(Vector3 pos, Vector3 tpos, float size) + { + var v = tpos - pos; + var rot = Quaternion.FromToRotation(Vector3.forward, v); + + Gizmos.matrix = Matrix4x4.TRS(pos, rot, Vector3.one); + Gizmos.color = ColorSkinningBone; + + Gizmos.DrawWireSphere(Vector3.zero, size); + + //Gizmos.DrawLine(Vector3.zero, Vector3.forward * v.magnitude); + float bsize = size * 0.8f; + float zoff = size; + var gpos = Vector3.forward * v.magnitude; + var p0 = new Vector3(bsize, bsize, zoff); + var p1 = new Vector3(bsize, -bsize, zoff); + var p2 = new Vector3(-bsize, -bsize, zoff); + var p3 = new Vector3(-bsize, bsize, zoff); + + Gizmos.DrawLine(p0, gpos); + Gizmos.DrawLine(p1, gpos); + Gizmos.DrawLine(p2, gpos); + Gizmos.DrawLine(p3, gpos); + + Gizmos.DrawLine(p0, p1); + Gizmos.DrawLine(p1, p2); + Gizmos.DrawLine(p2, p3); + Gizmos.DrawLine(p3, p0); + + Gizmos.matrix = Matrix4x4.identity; + } + + //========================================================================================= + /// + /// Handlesによるコーンの描画 + /// + /// + /// + /// + /// 角度(deg) + /// + /// + /// + public static void ConeHandle( + Vector3 pos, Quaternion rot, float size, float angle, + Color coneColor, Color wireColor, float wireThickness = 1.0f, + int controllId = 0 + ) + { + // デフォルトのコーン描画は角度や直径が決まっているので描画角度によりそれをスケーリングさせる + // サイズ1のオリジナルコーンの情報 + // 底面の半径0.4, 直径0.8 + // 高さ1.2(中心から底面まで0.5, 中心から始点まで0.7) + // 角度18.434948度 + + //float size = scr.size; + float rad = Mathf.Deg2Rad * angle; + float z = Mathf.Cos(rad); + float xy = Mathf.Sin(rad); + + // 角度18.434948の倍率 + const float cosBaseScl = 1.0f / 0.94868329f; + const float sinBaseScl = 1.0f / 0.31622775f; + z *= cosBaseScl; + xy *= sinBaseScl; + //Debug.Log(z); + + float zoffset = size * 0.7f; + + //readonly Quaternion flipQ = Quaternion.AngleAxis(180.0f, Vector3.up); + + //Handles.matrix = Matrix4x4.TRS(Vector3.zero, rot, new Vector3(xy, xy, z)); + Handles.matrix = Matrix4x4.TRS(pos, rot * FlipZ, new Vector3(xy, xy, z)); + //var pos = transform.position; + + // cone + Handles.color = coneColor; + Vector3 offset = new Vector3(0.0f, 0.0f, -zoffset); + Handles.ConeHandleCap( + controllId, + //pos + offset, + offset, + Quaternion.identity, + size, + EventType.Repaint + ); + + // wire dist + Handles.color = wireColor; + Handles.DrawWireDisc( + //pos + new Vector3(0.0f, 0.0f, -size * 1.2f), + new Vector3(0.0f, 0.0f, -size * 1.2f), + Vector3.forward, + size * (0.4f / 1.0f), + wireThickness + ); + + // wire + //Handles.color = scr.wireColor; + //var spos = pos; + const int div = 6; + const float angStep = 360.0f / div; + for (int i = 0; i < div; i++) + { + float ang = Mathf.Deg2Rad * i * angStep; + float x = Mathf.Sin(ang); + float y = Mathf.Cos(ang); + x *= size * (0.4f / 1.0f); + y *= size * (0.4f / 1.0f); + //Handles.DrawLine(spos, new Vector3(x, y, -size * 1.2f), wireThickness); + Handles.DrawLine(Vector3.zero, new Vector3(x, y, -size * 1.2f), wireThickness); + } + + Handles.matrix = Matrix4x4.identity; + } + + /// + /// 扇を描画する + /// + /// + /// + /// + /// + /// + /// + /// + /// + public static void ArcHandle( + Vector3 pos, Quaternion rot, float angle, float size, float wireThickness, + Color arcColor1, Color arcColor2, Color wireColor + ) + { + var up = rot * Vector3.up; + var right = rot * Vector3.right; + var forward = rot * Vector3.forward; + + Handles.color = arcColor1; + Handles.DrawSolidArc(pos, up, forward, angle, size); + Handles.DrawSolidArc(pos, -up, forward, angle, size); + + Handles.color = arcColor2; + Handles.DrawSolidArc(pos, right, forward, angle, size); + Handles.DrawSolidArc(pos, -right, forward, angle, size); + + Handles.color = wireColor; + Handles.DrawLine(pos, pos + forward * size, wireThickness); + + } + + //========================================================================================= + public static void DrawWindZone(MagicaWindZone windZone, Quaternion camRot, bool selected) + { + if (windZone == null) + return; + + // ゾーン + Handles.matrix = windZone.transform.localToWorldMatrix; + Handles.color = selected ? ColorWindZone : ColorWindZone * 0.5f; + + switch (windZone.mode) + { + case MagicaWindZone.Mode.GlobalDirection: + break; + case MagicaWindZone.Mode.BoxDirection: + DrawWireCube(Vector3.zero, Quaternion.identity, windZone.size, true); + break; + case MagicaWindZone.Mode.SphereDirection: + case MagicaWindZone.Mode.SphereRadial: + // カメラ回転をコライダーのローカル回転に変換 + camRot = Quaternion.Inverse(windZone.transform.rotation) * camRot; + DrawWireSphere(Vector3.zero, Quaternion.identity, windZone.radius, camRot, true); + break; + } + + // 方向 + Handles.color = selected ? ColorWindArrow : ColorWindArrow * 0.5f; + var pos = windZone.transform.position; + const float gsize = 0.5f; + if (windZone.IsDirection()) + { + var rot = MathUtility.AxisQuaternion(windZone.GetWindDirection()); + DrawWireArrow(pos, rot, new Vector3(gsize, gsize, gsize * 2), true); + } + else if (windZone.IsRadial()) + { + DrawLine(new Vector3(0, -gsize, 0), new Vector3(0, gsize, 0), true); + DrawLine(new Vector3(-gsize, 0, 0), new Vector3(gsize, 0, 0), true); + DrawLine(new Vector3(0, 0, -gsize), new Vector3(0, 0, gsize), true); + } + + Handles.matrix = Matrix4x4.identity; + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Editor/Gizmos/GizmoUtility.cs.meta b/Assets/MagicaCloth2/Scripts/Editor/Gizmos/GizmoUtility.cs.meta new file mode 100644 index 00000000..0a285dfc --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Editor/Gizmos/GizmoUtility.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: d09127cc59c08ae44aeeee33f206f227 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Editor/Gizmos/GizmoUtility.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Editor/Gizmos/MagicaCapsuleColliderGizmoDrawer.cs b/Assets/MagicaCloth2/Scripts/Editor/Gizmos/MagicaCapsuleColliderGizmoDrawer.cs new file mode 100644 index 00000000..89cb51ea --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Editor/Gizmos/MagicaCapsuleColliderGizmoDrawer.cs @@ -0,0 +1,19 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using UnityEditor; + +namespace MagicaCloth2 +{ + /// + /// MagicaCapsuleColliderのギズモ表示 + /// + public class MagicaCapsuleColliderGizmoDrawer + { + [DrawGizmo(GizmoType.Active | GizmoType.NonSelected | GizmoType.InSelectionHierarchy)] + static void DrawGizmo(MagicaCapsuleCollider scr, GizmoType gizmoType) + { + ClothEditorManager.RegisterComponent(scr, gizmoType); + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Editor/Gizmos/MagicaCapsuleColliderGizmoDrawer.cs.meta b/Assets/MagicaCloth2/Scripts/Editor/Gizmos/MagicaCapsuleColliderGizmoDrawer.cs.meta new file mode 100644 index 00000000..9266767d --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Editor/Gizmos/MagicaCapsuleColliderGizmoDrawer.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 7b1758b936826f64fbd4ccf459e1b4dd +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Editor/Gizmos/MagicaCapsuleColliderGizmoDrawer.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Editor/Gizmos/MagicaClothGizmoDrawer.cs b/Assets/MagicaCloth2/Scripts/Editor/Gizmos/MagicaClothGizmoDrawer.cs new file mode 100644 index 00000000..1ccedb28 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Editor/Gizmos/MagicaClothGizmoDrawer.cs @@ -0,0 +1,19 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using UnityEditor; + +namespace MagicaCloth2 +{ + /// + /// MagicaClothコンポーネントのギズモ表示 + /// + public class MagicaClothGizmoDrawer + { + [DrawGizmo(GizmoType.Active | GizmoType.NonSelected | GizmoType.InSelectionHierarchy)] + static void DrawGizmo(MagicaCloth cloth, GizmoType gizmoType) + { + ClothEditorManager.RegisterComponent(cloth, gizmoType); + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Editor/Gizmos/MagicaClothGizmoDrawer.cs.meta b/Assets/MagicaCloth2/Scripts/Editor/Gizmos/MagicaClothGizmoDrawer.cs.meta new file mode 100644 index 00000000..b1627295 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Editor/Gizmos/MagicaClothGizmoDrawer.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 74bd6289c38f5474b8b019772117a679 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Editor/Gizmos/MagicaClothGizmoDrawer.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Editor/Gizmos/MagicaPlaneColliderGizmoDrawer.cs b/Assets/MagicaCloth2/Scripts/Editor/Gizmos/MagicaPlaneColliderGizmoDrawer.cs new file mode 100644 index 00000000..5be19274 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Editor/Gizmos/MagicaPlaneColliderGizmoDrawer.cs @@ -0,0 +1,19 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using UnityEditor; + +namespace MagicaCloth2 +{ + /// + /// MagicaPlaneColliderのギズモ表示 + /// + public class MagicaPlaneColliderGizmoDrawer + { + [DrawGizmo(GizmoType.Active | GizmoType.NonSelected | GizmoType.InSelectionHierarchy)] + static void DrawGizmo(MagicaPlaneCollider scr, GizmoType gizmoType) + { + ClothEditorManager.RegisterComponent(scr, gizmoType); + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Editor/Gizmos/MagicaPlaneColliderGizmoDrawer.cs.meta b/Assets/MagicaCloth2/Scripts/Editor/Gizmos/MagicaPlaneColliderGizmoDrawer.cs.meta new file mode 100644 index 00000000..92c74226 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Editor/Gizmos/MagicaPlaneColliderGizmoDrawer.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 4ca64167845464543866cbfb4e1bfede +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Editor/Gizmos/MagicaPlaneColliderGizmoDrawer.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Editor/Gizmos/MagicaSphereColliderGizmoDrawer.cs b/Assets/MagicaCloth2/Scripts/Editor/Gizmos/MagicaSphereColliderGizmoDrawer.cs new file mode 100644 index 00000000..db7ea69a --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Editor/Gizmos/MagicaSphereColliderGizmoDrawer.cs @@ -0,0 +1,19 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using UnityEditor; + +namespace MagicaCloth2 +{ + /// + /// MagicaSphereColliderのギズモ表示 + /// + public class MagicaSphereColliderGizmoDrawer + { + [DrawGizmo(GizmoType.Active | GizmoType.NonSelected | GizmoType.InSelectionHierarchy)] + static void DrawGizmo(MagicaSphereCollider scr, GizmoType gizmoType) + { + ClothEditorManager.RegisterComponent(scr, gizmoType); + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Editor/Gizmos/MagicaSphereColliderGizmoDrawer.cs.meta b/Assets/MagicaCloth2/Scripts/Editor/Gizmos/MagicaSphereColliderGizmoDrawer.cs.meta new file mode 100644 index 00000000..83a8386a --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Editor/Gizmos/MagicaSphereColliderGizmoDrawer.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 0200526b5666bc94bb5b3f16765a1b96 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Editor/Gizmos/MagicaSphereColliderGizmoDrawer.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Editor/Gizmos/MagicaWindZoneGizmoDrawer.cs b/Assets/MagicaCloth2/Scripts/Editor/Gizmos/MagicaWindZoneGizmoDrawer.cs new file mode 100644 index 00000000..12bd93f7 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Editor/Gizmos/MagicaWindZoneGizmoDrawer.cs @@ -0,0 +1,16 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using UnityEditor; + +namespace MagicaCloth2 +{ + public class MagicaWindZoneGizmoDrawer + { + [DrawGizmo(GizmoType.Active | GizmoType.NonSelected | GizmoType.InSelectionHierarchy)] + static void DrawGizmo(MagicaWindZone scr, GizmoType gizmoType) + { + ClothEditorManager.RegisterComponent(scr, gizmoType); + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Editor/Gizmos/MagicaWindZoneGizmoDrawer.cs.meta b/Assets/MagicaCloth2/Scripts/Editor/Gizmos/MagicaWindZoneGizmoDrawer.cs.meta new file mode 100644 index 00000000..a17bd052 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Editor/Gizmos/MagicaWindZoneGizmoDrawer.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 4ad4eda344968ea4ab9b9f512b8c7278 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Editor/Gizmos/MagicaWindZoneGizmoDrawer.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Editor/MagicaCloth2.Editor.asmdef b/Assets/MagicaCloth2/Scripts/Editor/MagicaCloth2.Editor.asmdef new file mode 100644 index 00000000..7b3f9332 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Editor/MagicaCloth2.Editor.asmdef @@ -0,0 +1,35 @@ +{ + "name": "MagicaClothV2.Editor", + "rootNamespace": "", + "references": [ + "Unity.Mathematics", + "Unity.Collections", + "Unity.Burst", + "MagicaClothV2" + ], + "includePlatforms": [ + "Editor" + ], + "excludePlatforms": [], + "allowUnsafeCode": false, + "overrideReferences": false, + "precompiledReferences": [], + "autoReferenced": true, + "defineConstraints": [ + "MC2_BURST", + "MC2_COLLECTIONS" + ], + "versionDefines": [ + { + "name": "com.unity.burst", + "expression": "1.8.1", + "define": "MC2_BURST" + }, + { + "name": "com.unity.collections", + "expression": "1.4.0", + "define": "MC2_COLLECTIONS" + } + ], + "noEngineReferences": false +} \ No newline at end of file diff --git a/Assets/MagicaCloth2/Scripts/Editor/MagicaCloth2.Editor.asmdef.meta b/Assets/MagicaCloth2/Scripts/Editor/MagicaCloth2.Editor.asmdef.meta new file mode 100644 index 00000000..bfdde843 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Editor/MagicaCloth2.Editor.asmdef.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: 4c01641db757d0e4f85a4358c823601a +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Editor/MagicaCloth2.Editor.asmdef + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Editor/PreBuild.meta b/Assets/MagicaCloth2/Scripts/Editor/PreBuild.meta new file mode 100644 index 00000000..bbbd80b8 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Editor/PreBuild.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: d09f86fb6833fb048935d02b3254e292 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/MagicaCloth2/Scripts/Editor/PreBuild/PreBuildDataCreation.cs b/Assets/MagicaCloth2/Scripts/Editor/PreBuild/PreBuildDataCreation.cs new file mode 100644 index 00000000..9f14b404 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Editor/PreBuild/PreBuildDataCreation.cs @@ -0,0 +1,514 @@ +// Magica Cloth 2. +// Copyright (c) 2024 MagicaSoft. +// https://magicasoft.jp +using System; +using System.Collections.Generic; +using Unity.Mathematics; +using UnityEditor; +using UnityEngine; + +namespace MagicaCloth2 +{ + /// + /// PreBuildDataの作成 + /// + public static class PreBuildDataCreation + { + /// + /// PreBuildDataを作成しアセットとして保存する. + /// Create PreBuildData and save it as an asset. + /// + /// + /// Show save dialog if ScriptableObject does not exist. + /// + public static ResultCode CreatePreBuildData(MagicaCloth cloth, bool useNewSaveDialog = true) + { + var sdata = cloth.SerializeData; + var preBuildData = cloth.GetSerializeData2().preBuildData; + string buildId = preBuildData.buildId; + + // ビルドIDが存在しない場合はここで新規作成する + if (string.IsNullOrEmpty(buildId)) + { + buildId = PreBuildSerializeData.GenerateBuildID(); + } + + // スクリプタブルオブジェクトへ保存 + if (preBuildData.preBuildScriptableObject == null && useNewSaveDialog) + { + string assetName = $"MagicaPreBuild_{buildId}"; + + // 保存フォルダ読み込み + const string StateKey = "MagicaCloth2_PreBuild_Folder"; + string path = SessionState.GetString(StateKey, "Assets/"); + + string assetPath = EditorUtility.SaveFilePanelInProject("Saving MagicaCloth pre-build data", assetName, "asset", "MagicaCloth pre-build data name", path); + //Debug.Log($"AssetPath:{assetPath}"); + if (string.IsNullOrEmpty(assetPath)) + return new ResultCode(Define.Result.Cancel); + + // 保存フォルダ書き込み + SessionState.SetString(StateKey, System.IO.Path.GetDirectoryName(assetPath)); + + var sobj = ScriptableObject.CreateInstance(); + AssetDatabase.CreateAsset(sobj, assetPath); + AssetDatabase.Refresh(); + + preBuildData.preBuildScriptableObject = sobj; + } + + var preBuildScriptableObject = preBuildData.preBuildScriptableObject; + if (preBuildScriptableObject == null) + return new ResultCode(Define.Result.PreBuild_InvalidPreBuildData); + + // 構築 + var sharePreBuildData = new SharePreBuildData(); + var uniquePreBuildData = new UniquePreBuildData(); + if (sdata.IsValid()) + { + MakePreBuildData(cloth, buildId, sharePreBuildData, uniquePreBuildData); + } + else + { + sharePreBuildData.buildResult.SetError(Define.Result.PreBuildData_InvalidClothData); + } + + // データシリアライズ + preBuildData.buildId = buildId; + preBuildScriptableObject.AddPreBuildData(sharePreBuildData); + preBuildData.uniquePreBuildData = uniquePreBuildData; + + EditorUtility.SetDirty(preBuildScriptableObject); + EditorUtility.SetDirty(cloth); + AssetDatabase.Refresh(); + + return sharePreBuildData.buildResult; + } + + static void MakePreBuildData(MagicaCloth cloth, string buildId, SharePreBuildData sharePreBuildData, UniquePreBuildData uniquePreBuildData) + { + //Debug.Log($"MakePreBuildData().start"); + //var span = new TimeSpan("PreBuild"); + + sharePreBuildData.version = Define.System.LatestPreBuildVersion; + sharePreBuildData.buildId = buildId; + sharePreBuildData.buildResult.SetProcess(); + uniquePreBuildData.version = Define.System.LatestPreBuildVersion; + uniquePreBuildData.buildResult.SetProcess(); + + var setupDataList = new List(); + VirtualMesh proxyMesh = null; + var renderMeshList = new List(); + + try + { + var sdata = cloth.SerializeData; + var sdata2 = cloth.GetSerializeData2(); + var clothType = sdata.clothType; + + //======================== Initialize ============================ + // クロスを生成するための最低限の情報が揃っているかチェックする + if (sdata.IsValid() == false) + { + sharePreBuildData.buildResult.SetResult(sdata.VerificationResult); + throw new MagicaClothProcessingException(); + } + + // 初期トランスフォーム状態 + var clothTransformRecord = new TransformRecord(cloth.ClothTransform, read: true); + + // 法線調整用トランスフォーム + var normalAdjustmentTransformRecord = new TransformRecord( + sdata.normalAlignmentSetting.adjustmentTransform ? + sdata.normalAlignmentSetting.adjustmentTransform : + cloth.ClothTransform, read: true); + + // セットアップ情報の初期化 + if (clothType == ClothProcess.ClothType.MeshCloth) + { + foreach (var ren in sdata.sourceRenderers) + { + if (ren) + { + var setupData = new RenderSetupData(null, ren); + if (setupData.IsFaild()) + { + sharePreBuildData.buildResult.Merge(setupData.result); + throw new MagicaClothProcessingException(); + } + setupDataList.Add(setupData); + + // セットアップ情報のシリアライズ + sharePreBuildData.renderSetupDataList.Add(setupData.ShareSerialize()); + uniquePreBuildData.renderSetupDataList.Add(setupData.UniqueSerialize()); + } + } + } + else if (clothType == ClothProcess.ClothType.BoneCloth || clothType == ClothProcess.ClothType.BoneSpring) + { + var setupData = new RenderSetupData( + null, + clothType == ClothProcess.ClothType.BoneCloth ? RenderSetupData.SetupType.BoneCloth : RenderSetupData.SetupType.BoneSpring, + clothTransformRecord.transform, + sdata.rootBones, + clothType == ClothProcess.ClothType.BoneCloth ? null : sdata.colliderCollisionConstraint.collisionBones, + clothType == ClothProcess.ClothType.BoneCloth ? sdata.connectionMode : RenderSetupData.BoneConnectionMode.Line, + cloth.name + ); + if (setupData.IsFaild()) + { + sharePreBuildData.buildResult.Merge(setupData.result); + throw new MagicaClothProcessingException(); + } + setupDataList.Add(setupData); + } + + // カスタムスキニングのボーン情報 + List customSkinningBoneRecords = new List(); + int bcnt = sdata.customSkinningSetting.skinningBones.Count; + for (int i = 0; i < bcnt; i++) + { + customSkinningBoneRecords.Add(new TransformRecord(sdata.customSkinningSetting.skinningBones[i], read: true)); + } + + //======================== Proxy/Mapping Mesh ============================ + // ペイントマップ情報 + bool usePaintMap = false; + var paintMapDataList = new List(); + if (clothType == ClothProcess.ClothType.MeshCloth && sdata.paintMode != ClothSerializeData.PaintMode.Manual) + { + var ret = cloth.Process.GeneratePaintMapDataList(paintMapDataList); + Develop.DebugLog($"Generate paint map data list. {ret.GetResultString()}"); + if (ret.IsError()) + { + sharePreBuildData.buildResult.Merge(ret); + throw new MagicaClothProcessingException(); + } + //if (paintMapDataList.Count != renderHandleList.Count) + if (paintMapDataList.Count != setupDataList.Count) + { + sharePreBuildData.buildResult.SetError(Define.Result.CreateCloth_PaintMapCountMismatch); + throw new MagicaClothProcessingException(); + } + usePaintMap = true; + } + + // セレクションデータ + SelectionData selectionData = usePaintMap ? new SelectionData() : sdata2.selectionData.Clone(); + bool isValidSelection = selectionData?.IsValid() ?? false; + + // プロキシメッシュ作成 + proxyMesh = new VirtualMesh("Proxy"); + proxyMesh.result.SetProcess(); + if (clothType == ClothProcess.ClothType.MeshCloth) + { + + // MeshClothではクロストランスフォームを追加しておく + proxyMesh.SetTransform(clothTransformRecord); + + if (setupDataList.Count == 0) + { + sharePreBuildData.buildResult.SetError(Define.Result.ClothProcess_InvalidRenderHandleList); + throw new MagicaClothProcessingException(); + } + + // render mesh import + selection + merge + for (int i = 0; i < setupDataList.Count; i++) + { + VirtualMesh renderMesh = null; + try + { + // レンダーメッシュ作成 + var renderSetupData = setupDataList[i]; + renderMesh = new VirtualMesh($"[{renderSetupData.name}]"); + renderMesh.result.SetProcess(); + + // import ------------------------------------------------- + renderMesh.ImportFrom(renderSetupData, sdata.GetUvChannel()); + if (renderMesh.IsError) + { + sharePreBuildData.buildResult.Merge(renderMesh.result); + throw new MagicaClothProcessingException(); + } + Develop.DebugLog($"(IMPORT) {renderMesh}"); + + // selection ---------------------------------------------- + // MeshClothでペイントテクスチャ指定の場合はセレクションデータを生成する + SelectionData renderSelectionData = selectionData; + if (usePaintMap) + { + // セレクションデータ生成 + var ret = cloth.Process.GenerateSelectionDataFromPaintMap(clothTransformRecord, renderMesh, paintMapDataList[i], out renderSelectionData); + Develop.DebugLog($"Generate selection from paint map. {ret.GetResultString()}"); + if (ret.IsError()) + { + sharePreBuildData.buildResult.Merge(ret); + throw new MagicaClothProcessingException(); + } + + // セレクションデータ結合 + selectionData.Merge(renderSelectionData); + } + isValidSelection = selectionData?.IsValid() ?? false; + + // メッシュの切り取り + if (renderSelectionData?.IsValid() ?? false) + { + // 余白 + float mergin = renderMesh.CalcSelectionMergin(sdata.reductionSetting); + mergin = math.max(mergin, Define.System.MinimumGridSize); + + // セレクション情報から切り取りの実行 + // ペイントマップの場合はレンダラーごとのセレクションデータで切り取り + renderMesh.SelectionMesh(renderSelectionData, clothTransformRecord.localToWorldMatrix, mergin); + if (renderMesh.IsError) + { + sharePreBuildData.buildResult.Merge(renderMesh.result); + throw new MagicaClothProcessingException(); + } + Develop.DebugLog($"(SELECTION) {renderMesh}"); + } + + // レンダーメッシュの作成完了 + renderMesh.result.SetSuccess(); + + // merge -------------------------------------------------- + proxyMesh.AddMesh(renderMesh); + + // レンダーメッシュ情報を記録 + renderMeshList.Add(renderMesh); + renderMesh = null; + } + catch (MagicaClothProcessingException) + { + throw; + } + catch (Exception exception) + { + Debug.LogException(exception); + sharePreBuildData.buildResult.SetError(Define.Result.ClothProcess_Exception); + throw; + } + finally + { + // この時点で作業用renderMeshが存在する場合は中断されているので開放する + renderMesh?.Dispose(); + } + } + Develop.DebugLog($"(MERGE) {proxyMesh}"); + + // リダクション + if (proxyMesh.VertexCount > 1) + { + if (sdata.reductionSetting.IsEnabled) + { + proxyMesh.Reduction(sdata.reductionSetting, System.Threading.CancellationToken.None); + if (proxyMesh.IsError) + { + sharePreBuildData.buildResult.Merge(proxyMesh.result); + throw new MagicaClothProcessingException(); + } + + Develop.DebugLog($"(REDUCTION) {proxyMesh}"); + } + } + } + else if (clothType == ClothProcess.ClothType.BoneCloth || clothType == ClothProcess.ClothType.BoneSpring) + { + // import + var boneClothSetupData = setupDataList[0]; + proxyMesh.ImportFrom(boneClothSetupData, 0); + if (proxyMesh.IsError) + { + sharePreBuildData.buildResult.Merge(proxyMesh.result); + throw new MagicaClothProcessingException(); + } + Develop.DebugLog($"(IMPORT) {proxyMesh}"); + + // セレクションデータが存在しない場合は簡易作成する + if (isValidSelection == false) + { + selectionData = new SelectionData(proxyMesh, float4x4.identity); + if (selectionData.Count > 0) + { + // まずすべて移動設定 + selectionData.Fill(VertexAttribute.Move); + + // 次にルートのみ固定 + foreach (MagicaObjectId id in boneClothSetupData.rootTransformIdList) + { + int rootIndex = boneClothSetupData.GetTransformIndexFromId(id); + selectionData.attributes[rootIndex] = VertexAttribute.Fixed; + } + isValidSelection = selectionData.IsValid(); + } + } + } + + // 元の頂点から結合頂点へのインデックスを初期化 + if (proxyMesh.joinIndices.IsCreated == false) + { + proxyMesh.joinIndices = new Unity.Collections.NativeArray(proxyMesh.VertexCount, Unity.Collections.Allocator.Persistent); + JobUtility.SerialNumberRun(proxyMesh.joinIndices, proxyMesh.VertexCount); // 連番をつける + } + + // optimization + proxyMesh.Optimization(); + if (proxyMesh.IsError) + { + sharePreBuildData.buildResult.Merge(proxyMesh.result); + throw new MagicaClothProcessingException(); + } + Develop.DebugLog($"(OPTIMIZE) {proxyMesh}"); + + // attribute + if (isValidSelection) + { + // セレクションデータから頂点属性を付与する + proxyMesh.ApplySelectionAttribute(selectionData); + if (proxyMesh.IsError) + { + sharePreBuildData.buildResult.Merge(proxyMesh.result); + throw new MagicaClothProcessingException(); + } + } + + // proxy mesh(属性決定後に実行) + proxyMesh.ConvertProxyMesh(sdata, clothTransformRecord, customSkinningBoneRecords, normalAdjustmentTransformRecord); + if (proxyMesh.IsError) + { + sharePreBuildData.buildResult.Merge(proxyMesh.result); + throw new MagicaClothProcessingException(); + } + Develop.DebugLog($"(PROXY) {proxyMesh}"); + + // ProxyMeshの最終チェック + if (proxyMesh.VertexCount > Define.System.MaxProxyMeshVertexCount) + { + sharePreBuildData.buildResult.SetError(Define.Result.ProxyMesh_Over32767Vertices); + throw new MagicaClothProcessingException(); + } + if (proxyMesh.EdgeCount > Define.System.MaxProxyMeshEdgeCount) + { + sharePreBuildData.buildResult.SetError(Define.Result.ProxyMesh_Over32767Edges); + throw new MagicaClothProcessingException(); + } + if (proxyMesh.TriangleCount > Define.System.MaxProxyMeshTriangleCount) + { + sharePreBuildData.buildResult.SetError(Define.Result.ProxyMesh_Over32767Triangles); + throw new MagicaClothProcessingException(); + } + + // finish + if (proxyMesh.IsError) + { + sharePreBuildData.buildResult.Merge(proxyMesh.result); + throw new MagicaClothProcessingException(); + } + proxyMesh.result.SetSuccess(); + Develop.DebugLog("CreateProxyMesh finish!"); + + // Mapping(MeshClothのみ) + if (clothType == ClothProcess.ClothType.MeshCloth) + { + foreach (VirtualMesh renderMesh in renderMeshList) + { + renderMesh.Mapping(proxyMesh); + if (renderMesh.IsError) + { + sharePreBuildData.buildResult.Merge(renderMesh.result); + throw new MagicaClothProcessingException(); + } + Develop.DebugLog($"(MAPPING) {renderMesh}"); + } + } + + // ======================= Cloth Data =============================== + // クロスデータ作成 + var parameters = cloth.SerializeData.GetClothParameters(); + var distanceConstraintData = DistanceConstraint.CreateData(proxyMesh, parameters); + if (distanceConstraintData != null) + { + if (distanceConstraintData.result.IsSuccess()) + { + sharePreBuildData.distanceConstraintData = distanceConstraintData; + } + else + { + sharePreBuildData.buildResult.Merge(distanceConstraintData.result); + throw new MagicaClothProcessingException(); + } + } + var bendingConstraintData = TriangleBendingConstraint.CreateData(proxyMesh, parameters); + if (bendingConstraintData != null) + { + if (bendingConstraintData.result.IsSuccess()) + { + sharePreBuildData.bendingConstraintData = bendingConstraintData; + } + else + { + sharePreBuildData.buildResult.Merge(bendingConstraintData.result); + throw new MagicaClothProcessingException(); + } + } + var inertiaConstraintData = InertiaConstraint.CreateData(proxyMesh, parameters); + if (inertiaConstraintData != null) + { + if (inertiaConstraintData.result.IsSuccess()) + { + sharePreBuildData.inertiaConstraintData = inertiaConstraintData; + } + else + { + sharePreBuildData.buildResult.Merge(inertiaConstraintData.result); + throw new MagicaClothProcessingException(); + } + } + + // ======================= Serialize =============================== + sharePreBuildData.buildScale = clothTransformRecord.scale; + sharePreBuildData.proxyMesh = proxyMesh.ShareSerialize(); + uniquePreBuildData.proxyMesh = proxyMesh.UniqueSerialize(); + foreach (VirtualMesh renderMesh in renderMeshList) + { + sharePreBuildData.renderMeshList.Add(renderMesh.ShareSerialize()); + uniquePreBuildData.renderMeshList.Add(renderMesh.UniqueSerialize()); + } + + // 成功 + sharePreBuildData.buildResult.SetSuccess(); + + Develop.DebugLog(sharePreBuildData); + } + catch (MagicaClothProcessingException) + { + if (sharePreBuildData.buildResult.IsError() == false) + sharePreBuildData.buildResult.SetError(Define.Result.PreBuildData_MagicaClothException); + sharePreBuildData.buildResult.DebugLog(); + } + catch (Exception exception) + { + Debug.LogException(exception); + sharePreBuildData.buildResult.SetError(Define.Result.PreBuildData_UnknownError); + } + finally + { + setupDataList.ForEach(x => x.Dispose()); + setupDataList.Clear(); + + renderMeshList.ForEach(x => x?.Dispose()); + renderMeshList.Clear(); + + proxyMesh?.Dispose(); + proxyMesh = null; + + // 内部情報は外部情報の結果をコピー + uniquePreBuildData.buildResult = sharePreBuildData.buildResult; + } + + //Debug.Log(span); + //Debug.Log($"MakePreBuildData().end"); + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Editor/PreBuild/PreBuildDataCreation.cs.meta b/Assets/MagicaCloth2/Scripts/Editor/PreBuild/PreBuildDataCreation.cs.meta new file mode 100644 index 00000000..80d8253b --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Editor/PreBuild/PreBuildDataCreation.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: d37ab6d9c5e31034a9503a7cedd96ee3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Editor/PreBuild/PreBuildDataCreation.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Editor/UnityPackageImporter.meta b/Assets/MagicaCloth2/Scripts/Editor/UnityPackageImporter.meta new file mode 100644 index 00000000..9f660c40 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Editor/UnityPackageImporter.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: b220f0001485e184bb3dd8e27c9854b0 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/MagicaCloth2/Scripts/Editor/UnityPackageImporter/Burst.meta b/Assets/MagicaCloth2/Scripts/Editor/UnityPackageImporter/Burst.meta new file mode 100644 index 00000000..ff8866d9 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Editor/UnityPackageImporter/Burst.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 232f688d5a1b6c04e91d6dca950b394e +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/MagicaCloth2/Scripts/Editor/UnityPackageImporter/Burst/MagicaCloth2UPMImporterBurst.asmdef b/Assets/MagicaCloth2/Scripts/Editor/UnityPackageImporter/Burst/MagicaCloth2UPMImporterBurst.asmdef new file mode 100644 index 00000000..ef00e6f6 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Editor/UnityPackageImporter/Burst/MagicaCloth2UPMImporterBurst.asmdef @@ -0,0 +1,24 @@ +{ + "name": "MagicaClothV2UPMImporterBurst", + "rootNamespace": "", + "references": [], + "includePlatforms": [ + "Editor" + ], + "excludePlatforms": [], + "allowUnsafeCode": false, + "overrideReferences": false, + "precompiledReferences": [], + "autoReferenced": true, + "defineConstraints": [ + "!MC2_BURST" + ], + "versionDefines": [ + { + "name": "com.unity.burst", + "expression": "1.8.1", + "define": "MC2_BURST" + } + ], + "noEngineReferences": false +} \ No newline at end of file diff --git a/Assets/MagicaCloth2/Scripts/Editor/UnityPackageImporter/Burst/MagicaCloth2UPMImporterBurst.asmdef.meta b/Assets/MagicaCloth2/Scripts/Editor/UnityPackageImporter/Burst/MagicaCloth2UPMImporterBurst.asmdef.meta new file mode 100644 index 00000000..776f5d1e --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Editor/UnityPackageImporter/Burst/MagicaCloth2UPMImporterBurst.asmdef.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: 3a07ec506f9f4a6488a05f2691638ef3 +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Editor/UnityPackageImporter/Burst/MagicaCloth2UPMImporterBurst.asmdef + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Editor/UnityPackageImporter/Burst/UnityPackageImporter.cs b/Assets/MagicaCloth2/Scripts/Editor/UnityPackageImporter/Burst/UnityPackageImporter.cs new file mode 100644 index 00000000..a20ea8b9 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Editor/UnityPackageImporter/Burst/UnityPackageImporter.cs @@ -0,0 +1,33 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using UnityEditor; +using UnityEditor.PackageManager; +using UnityEngine; + +namespace MagicaCloth2UPMImporterBurst +{ + /// + /// 必要なUnityPackageの自動インストール + /// + [InitializeOnLoad] + public static class UnityPackageImporter + { + static UnityPackageImporter() + { + Install("com.unity.burst"); + Install("com.unity.mathematics"); + Install("com.unity.collections"); + //Install("com.unity.burst@1.4.11"); + } + + public static bool Install(string id) + { + Debug.Log($"Install...{id}"); + var request = Client.Add(id); + while (!request.IsCompleted) { }; + if (request.Error != null) Debug.LogError(request.Error.message); + return request.Error == null; + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Editor/UnityPackageImporter/Burst/UnityPackageImporter.cs.meta b/Assets/MagicaCloth2/Scripts/Editor/UnityPackageImporter/Burst/UnityPackageImporter.cs.meta new file mode 100644 index 00000000..a6c71b82 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Editor/UnityPackageImporter/Burst/UnityPackageImporter.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 0303ccf5b5b37f24783c499f80d88363 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Editor/UnityPackageImporter/Burst/UnityPackageImporter.cs + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Editor/UnityPackageImporter/Collections.meta b/Assets/MagicaCloth2/Scripts/Editor/UnityPackageImporter/Collections.meta new file mode 100644 index 00000000..ff400120 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Editor/UnityPackageImporter/Collections.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 22dca49adfb21a644b1bed79da0080a7 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/MagicaCloth2/Scripts/Editor/UnityPackageImporter/Collections/MagicaCloth2UPMImporterCollections.asmdef b/Assets/MagicaCloth2/Scripts/Editor/UnityPackageImporter/Collections/MagicaCloth2UPMImporterCollections.asmdef new file mode 100644 index 00000000..17ab9263 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Editor/UnityPackageImporter/Collections/MagicaCloth2UPMImporterCollections.asmdef @@ -0,0 +1,24 @@ +{ + "name": "MagicaClothV2UPMImporterCollections", + "rootNamespace": "", + "references": [], + "includePlatforms": [ + "Editor" + ], + "excludePlatforms": [], + "allowUnsafeCode": false, + "overrideReferences": false, + "precompiledReferences": [], + "autoReferenced": true, + "defineConstraints": [ + "!MC2_COLLECTIONS" + ], + "versionDefines": [ + { + "name": "com.unity.collections", + "expression": "1.4.0", + "define": "MC2_COLLECTIONS" + } + ], + "noEngineReferences": false +} \ No newline at end of file diff --git a/Assets/MagicaCloth2/Scripts/Editor/UnityPackageImporter/Collections/MagicaCloth2UPMImporterCollections.asmdef.meta b/Assets/MagicaCloth2/Scripts/Editor/UnityPackageImporter/Collections/MagicaCloth2UPMImporterCollections.asmdef.meta new file mode 100644 index 00000000..06e203d0 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Editor/UnityPackageImporter/Collections/MagicaCloth2UPMImporterCollections.asmdef.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: 084a8eed0c5e5a84fa6a7cd543c50d8a +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Editor/UnityPackageImporter/Collections/MagicaCloth2UPMImporterCollections.asmdef + uploadId: 893596 diff --git a/Assets/MagicaCloth2/Scripts/Editor/UnityPackageImporter/Collections/UnityPackageImporter.cs b/Assets/MagicaCloth2/Scripts/Editor/UnityPackageImporter/Collections/UnityPackageImporter.cs new file mode 100644 index 00000000..46647f10 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Editor/UnityPackageImporter/Collections/UnityPackageImporter.cs @@ -0,0 +1,33 @@ +// Magica Cloth 2. +// Copyright (c) 2023 MagicaSoft. +// https://magicasoft.jp +using UnityEditor; +using UnityEditor.PackageManager; +using UnityEngine; + +namespace MagicaCloth2UPMImporterCollections +{ + /// + /// 必要なUnityPackageの自動インストール + /// + [InitializeOnLoad] + public static class UnityPackageImporter + { + static UnityPackageImporter() + { + Install("com.unity.burst"); + Install("com.unity.mathematics"); + Install("com.unity.collections"); + //Install("com.unity.burst@1.4.11"); + } + + public static bool Install(string id) + { + Debug.Log($"Install...{id}"); + var request = Client.Add(id); + while (!request.IsCompleted) { }; + if (request.Error != null) Debug.LogError(request.Error.message); + return request.Error == null; + } + } +} diff --git a/Assets/MagicaCloth2/Scripts/Editor/UnityPackageImporter/Collections/UnityPackageImporter.cs.meta b/Assets/MagicaCloth2/Scripts/Editor/UnityPackageImporter/Collections/UnityPackageImporter.cs.meta new file mode 100644 index 00000000..da5c21c3 --- /dev/null +++ b/Assets/MagicaCloth2/Scripts/Editor/UnityPackageImporter/Collections/UnityPackageImporter.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: c49cd9494a8e6374eb04a10242c258e3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 242307 + packageName: Magica Cloth 2 + packageVersion: 2.18.1 + assetPath: Assets/MagicaCloth2/Scripts/Editor/UnityPackageImporter/Collections/UnityPackageImporter.cs + uploadId: 893596 diff --git a/ProjectSettings/ProjectSettings.asset b/ProjectSettings/ProjectSettings.asset index bc69ef54..03363233 100644 --- a/ProjectSettings/ProjectSettings.asset +++ b/ProjectSettings/ProjectSettings.asset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:738abead11762d0468a65a889adcecf9f16e7a0c56e8ce03a618bedee60dcd31 -size 28100 +oid sha256:87718b14f88a5f893b5f109c236d208b8984fa7985c0699ec63dccd6d60386fe +size 28113