diff --git a/Assets/External/Fantasy Skybox.meta b/Assets/External/Fantasy Skybox.meta
new file mode 100644
index 000000000..5e6bd2c20
--- /dev/null
+++ b/Assets/External/Fantasy Skybox.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: ef1cb0fe8d3d5584d968a603ac0bde56
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/External/Fantasy Skybox/ReleaseNotes.txt b/Assets/External/Fantasy Skybox/ReleaseNotes.txt
new file mode 100644
index 000000000..b4d47111d
--- /dev/null
+++ b/Assets/External/Fantasy Skybox/ReleaseNotes.txt
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:662b405c9bb5f9eda217ceb19b6e0de80b4c3e23621c950e3f754b26404db156
+size 3122
diff --git a/Assets/External/Fantasy Skybox/ReleaseNotes.txt.meta b/Assets/External/Fantasy Skybox/ReleaseNotes.txt.meta
new file mode 100644
index 000000000..9942622e0
--- /dev/null
+++ b/Assets/External/Fantasy Skybox/ReleaseNotes.txt.meta
@@ -0,0 +1,15 @@
+fileFormatVersion: 2
+guid: f14307b5201ecdf4e89f2c843bdec16c
+timeCreated: 1434912371
+licenseType: Store
+TextScriptImporter:
+ userData:
+ assetBundleName:
+ assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 18216
+ packageName: Fantasy Skybox
+ packageVersion: 1.6.7
+ assetPath: Assets/Fantasy Skybox/ReleaseNotes.txt
+ uploadId: 709120
diff --git a/Assets/External/Free Stylized Hand-Painted Skybox.meta b/Assets/External/Free Stylized Hand-Painted Skybox.meta
new file mode 100644
index 000000000..dfcf7461b
--- /dev/null
+++ b/Assets/External/Free Stylized Hand-Painted Skybox.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 617f13ee40e80a14f839790660d6261c
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/External/Free Stylized Hand-Painted Skybox/BD Studios Post-Processing Profile.asset b/Assets/External/Free Stylized Hand-Painted Skybox/BD Studios Post-Processing Profile.asset
new file mode 100644
index 000000000..f135814bb
--- /dev/null
+++ b/Assets/External/Free Stylized Hand-Painted Skybox/BD Studios Post-Processing Profile.asset
@@ -0,0 +1,1522 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!114 &-6121356625829328324
+MonoBehaviour:
+ m_ObjectHideFlags: 3
+ 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: 40b924e2dad56384a8df2a1e111bb675, type: 3}
+ m_Name: Vignette
+ m_EditorClassIdentifier:
+ active: 1
+ enabled:
+ overrideState: 1
+ value: 1
+ mode:
+ overrideState: 0
+ value: 0
+ color:
+ overrideState: 0
+ value: {r: 0, g: 0, b: 0, a: 1}
+ center:
+ overrideState: 0
+ value: {x: 0.5, y: 0.5}
+ intensity:
+ overrideState: 1
+ value: 0.26
+ smoothness:
+ overrideState: 1
+ value: 0.128
+ roundness:
+ overrideState: 0
+ value: 1
+ rounded:
+ overrideState: 0
+ value: 0
+ mask:
+ overrideState: 0
+ value: {fileID: 0}
+ defaultState: 1
+ opacity:
+ overrideState: 0
+ value: 1
+--- !u!114 &-6114600444338696570
+MonoBehaviour:
+ m_ObjectHideFlags: 3
+ 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: 48a79b01ea5641d4aa6daa2e23605641, type: 3}
+ m_Name: Bloom
+ m_EditorClassIdentifier:
+ active: 1
+ enabled:
+ overrideState: 1
+ value: 1
+ intensity:
+ overrideState: 1
+ value: 0.4
+ threshold:
+ overrideState: 1
+ value: 0.73
+ softKnee:
+ overrideState: 0
+ value: 0.5
+ clamp:
+ overrideState: 0
+ value: 65472
+ diffusion:
+ overrideState: 0
+ value: 7
+ anamorphicRatio:
+ overrideState: 0
+ value: 0
+ color:
+ overrideState: 1
+ value: {r: 1, g: 0.9494407, b: 0.9103774, a: 1}
+ fastMode:
+ overrideState: 0
+ value: 0
+ dirtTexture:
+ overrideState: 0
+ value: {fileID: 0}
+ defaultState: 1
+ dirtIntensity:
+ overrideState: 0
+ value: 0
+--- !u!114 &-5399058212381721059
+MonoBehaviour:
+ m_ObjectHideFlags: 3
+ 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: c1cb7e9e120078f43bce4f0b1be547a7, type: 3}
+ m_Name: AmbientOcclusion
+ m_EditorClassIdentifier:
+ active: 1
+ enabled:
+ overrideState: 1
+ value: 1
+ mode:
+ overrideState: 1
+ value: 1
+ intensity:
+ overrideState: 1
+ value: 1.19
+ color:
+ overrideState: 1
+ value: {r: 0, g: 0, b: 0, a: 1}
+ ambientOnly:
+ overrideState: 1
+ value: 0
+ noiseFilterTolerance:
+ overrideState: 0
+ value: 0
+ blurTolerance:
+ overrideState: 0
+ value: -4.6
+ upsampleTolerance:
+ overrideState: 0
+ value: -12
+ thicknessModifier:
+ overrideState: 1
+ value: 1
+ directLightingStrength:
+ overrideState: 0
+ value: 0
+ radius:
+ overrideState: 0
+ value: 0.25
+ quality:
+ overrideState: 0
+ value: 2
+--- !u!114 &-270372995244880535
+MonoBehaviour:
+ m_ObjectHideFlags: 3
+ 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: 556797029e73b2347956b6579e77e05b, type: 3}
+ m_Name: DepthOfField
+ m_EditorClassIdentifier:
+ active: 0
+ enabled:
+ overrideState: 1
+ value: 1
+ focusDistance:
+ overrideState: 1
+ value: 4.2
+ aperture:
+ overrideState: 0
+ value: 5.6
+ focalLength:
+ overrideState: 0
+ value: 50
+ kernelSize:
+ overrideState: 0
+ value: 1
+--- !u!114 &11400000
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ 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: 8e6292b2c06870d4495f009f912b9600, type: 3}
+ m_Name: BD Studios Post-Processing Profile
+ m_EditorClassIdentifier:
+ settings:
+ - {fileID: -5399058212381721059}
+ - {fileID: -6114600444338696570}
+ - {fileID: 7703522721035351794}
+ - {fileID: -270372995244880535}
+ - {fileID: 154684449965798654}
+ - {fileID: -6121356625829328324}
+--- !u!114 &154684449965798654
+MonoBehaviour:
+ m_ObjectHideFlags: 3
+ 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: b94fcd11afffcb142908bfcb1e261fba, type: 3}
+ m_Name: MotionBlur
+ m_EditorClassIdentifier:
+ active: 1
+ enabled:
+ overrideState: 1
+ value: 1
+ shutterAngle:
+ overrideState: 1
+ value: 270
+ sampleCount:
+ overrideState: 1
+ value: 10
+--- !u!114 &7703522721035351794
+MonoBehaviour:
+ m_ObjectHideFlags: 3
+ 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: adb84e30e02715445aeb9959894e3b4d, type: 3}
+ m_Name: ColorGrading
+ m_EditorClassIdentifier:
+ active: 1
+ enabled:
+ overrideState: 1
+ value: 1
+ gradingMode:
+ overrideState: 1
+ value: 1
+ externalLut:
+ overrideState: 0
+ value: {fileID: 0}
+ defaultState: 1
+ tonemapper:
+ overrideState: 1
+ value: 2
+ toneCurveToeStrength:
+ overrideState: 0
+ value: 0
+ toneCurveToeLength:
+ overrideState: 0
+ value: 0.5
+ toneCurveShoulderStrength:
+ overrideState: 0
+ value: 0
+ toneCurveShoulderLength:
+ overrideState: 0
+ value: 0.5
+ toneCurveShoulderAngle:
+ overrideState: 0
+ value: 0
+ toneCurveGamma:
+ overrideState: 0
+ value: 1
+ ldrLut:
+ overrideState: 0
+ value: {fileID: 0}
+ defaultState: 4
+ ldrLutContribution:
+ overrideState: 0
+ value: 1
+ temperature:
+ overrideState: 1
+ value: 5
+ tint:
+ overrideState: 1
+ value: 0
+ colorFilter:
+ overrideState: 0
+ value: {r: 1, g: 1, b: 1, a: 1}
+ hueShift:
+ overrideState: 0
+ value: 0
+ saturation:
+ overrideState: 1
+ value: 18.4
+ brightness:
+ overrideState: 0
+ value: 0
+ postExposure:
+ overrideState: 1
+ value: 0.37
+ contrast:
+ overrideState: 1
+ value: 18.5
+ mixerRedOutRedIn:
+ overrideState: 0
+ value: 100
+ mixerRedOutGreenIn:
+ overrideState: 0
+ value: 0
+ mixerRedOutBlueIn:
+ overrideState: 0
+ value: 0
+ mixerGreenOutRedIn:
+ overrideState: 0
+ value: 0
+ mixerGreenOutGreenIn:
+ overrideState: 0
+ value: 100
+ mixerGreenOutBlueIn:
+ overrideState: 0
+ value: 0
+ mixerBlueOutRedIn:
+ overrideState: 0
+ value: 0
+ mixerBlueOutGreenIn:
+ overrideState: 0
+ value: 0
+ mixerBlueOutBlueIn:
+ overrideState: 0
+ value: 100
+ lift:
+ overrideState: 0
+ value: {x: 0.98793775, y: 1, z: 0.9846576, w: 0}
+ gamma:
+ overrideState: 0
+ value: {x: 0.9592483, y: 0.9712873, z: 1, w: 0}
+ gain:
+ overrideState: 0
+ value: {x: 1, y: 0.97258776, z: 0.996861, w: 0}
+ masterCurve:
+ overrideState: 0
+ value:
+ curve:
+ serializedVersion: 2
+ m_Curve:
+ - serializedVersion: 3
+ time: 0
+ value: 0
+ inSlope: 1
+ outSlope: 1
+ tangentMode: 0
+ weightedMode: 0
+ inWeight: 0
+ outWeight: 0
+ - serializedVersion: 3
+ time: 1
+ value: 1
+ inSlope: 1
+ outSlope: 1
+ tangentMode: 0
+ weightedMode: 0
+ inWeight: 0
+ outWeight: 0
+ m_PreInfinity: 2
+ m_PostInfinity: 2
+ m_RotationOrder: 4
+ m_Loop: 0
+ m_ZeroValue: 0
+ m_Range: 1
+ cachedData:
+ - 0
+ - 0.0078125
+ - 0.015625
+ - 0.0234375
+ - 0.03125
+ - 0.0390625
+ - 0.046875
+ - 0.0546875
+ - 0.0625
+ - 0.0703125
+ - 0.078125
+ - 0.0859375
+ - 0.09375
+ - 0.1015625
+ - 0.109375
+ - 0.1171875
+ - 0.125
+ - 0.1328125
+ - 0.140625
+ - 0.1484375
+ - 0.15625
+ - 0.1640625
+ - 0.171875
+ - 0.1796875
+ - 0.1875
+ - 0.1953125
+ - 0.203125
+ - 0.2109375
+ - 0.21875
+ - 0.2265625
+ - 0.234375
+ - 0.2421875
+ - 0.25
+ - 0.2578125
+ - 0.265625
+ - 0.2734375
+ - 0.28125
+ - 0.2890625
+ - 0.296875
+ - 0.3046875
+ - 0.3125
+ - 0.3203125
+ - 0.328125
+ - 0.3359375
+ - 0.34375
+ - 0.3515625
+ - 0.359375
+ - 0.3671875
+ - 0.375
+ - 0.3828125
+ - 0.390625
+ - 0.3984375
+ - 0.40625
+ - 0.4140625
+ - 0.421875
+ - 0.4296875
+ - 0.4375
+ - 0.4453125
+ - 0.453125
+ - 0.4609375
+ - 0.46875
+ - 0.4765625
+ - 0.484375
+ - 0.4921875
+ - 0.5
+ - 0.5078125
+ - 0.515625
+ - 0.5234375
+ - 0.53125
+ - 0.5390625
+ - 0.546875
+ - 0.5546875
+ - 0.5625
+ - 0.5703125
+ - 0.578125
+ - 0.5859375
+ - 0.59375
+ - 0.6015625
+ - 0.609375
+ - 0.6171875
+ - 0.625
+ - 0.6328125
+ - 0.640625
+ - 0.6484375
+ - 0.65625
+ - 0.6640625
+ - 0.671875
+ - 0.6796875
+ - 0.6875
+ - 0.6953125
+ - 0.703125
+ - 0.7109375
+ - 0.71875
+ - 0.7265625
+ - 0.734375
+ - 0.7421875
+ - 0.75
+ - 0.7578125
+ - 0.765625
+ - 0.7734375
+ - 0.78125
+ - 0.7890625
+ - 0.796875
+ - 0.8046875
+ - 0.8125
+ - 0.8203125
+ - 0.828125
+ - 0.8359375
+ - 0.84375
+ - 0.8515625
+ - 0.859375
+ - 0.8671875
+ - 0.875
+ - 0.8828125
+ - 0.890625
+ - 0.8984375
+ - 0.90625
+ - 0.9140625
+ - 0.921875
+ - 0.9296875
+ - 0.9375
+ - 0.9453125
+ - 0.953125
+ - 0.9609375
+ - 0.96875
+ - 0.9765625
+ - 0.984375
+ - 0.9921875
+ redCurve:
+ overrideState: 0
+ value:
+ curve:
+ serializedVersion: 2
+ m_Curve:
+ - serializedVersion: 3
+ time: 0
+ value: 0
+ inSlope: 1
+ outSlope: 1
+ tangentMode: 0
+ weightedMode: 0
+ inWeight: 0
+ outWeight: 0
+ - serializedVersion: 3
+ time: 1
+ value: 1
+ inSlope: 1
+ outSlope: 1
+ tangentMode: 0
+ weightedMode: 0
+ inWeight: 0
+ outWeight: 0
+ m_PreInfinity: 2
+ m_PostInfinity: 2
+ m_RotationOrder: 4
+ m_Loop: 0
+ m_ZeroValue: 0
+ m_Range: 1
+ cachedData:
+ - 0
+ - 0.0078125
+ - 0.015625
+ - 0.0234375
+ - 0.03125
+ - 0.0390625
+ - 0.046875
+ - 0.0546875
+ - 0.0625
+ - 0.0703125
+ - 0.078125
+ - 0.0859375
+ - 0.09375
+ - 0.1015625
+ - 0.109375
+ - 0.1171875
+ - 0.125
+ - 0.1328125
+ - 0.140625
+ - 0.1484375
+ - 0.15625
+ - 0.1640625
+ - 0.171875
+ - 0.1796875
+ - 0.1875
+ - 0.1953125
+ - 0.203125
+ - 0.2109375
+ - 0.21875
+ - 0.2265625
+ - 0.234375
+ - 0.2421875
+ - 0.25
+ - 0.2578125
+ - 0.265625
+ - 0.2734375
+ - 0.28125
+ - 0.2890625
+ - 0.296875
+ - 0.3046875
+ - 0.3125
+ - 0.3203125
+ - 0.328125
+ - 0.3359375
+ - 0.34375
+ - 0.3515625
+ - 0.359375
+ - 0.3671875
+ - 0.375
+ - 0.3828125
+ - 0.390625
+ - 0.3984375
+ - 0.40625
+ - 0.4140625
+ - 0.421875
+ - 0.4296875
+ - 0.4375
+ - 0.4453125
+ - 0.453125
+ - 0.4609375
+ - 0.46875
+ - 0.4765625
+ - 0.484375
+ - 0.4921875
+ - 0.5
+ - 0.5078125
+ - 0.515625
+ - 0.5234375
+ - 0.53125
+ - 0.5390625
+ - 0.546875
+ - 0.5546875
+ - 0.5625
+ - 0.5703125
+ - 0.578125
+ - 0.5859375
+ - 0.59375
+ - 0.6015625
+ - 0.609375
+ - 0.6171875
+ - 0.625
+ - 0.6328125
+ - 0.640625
+ - 0.6484375
+ - 0.65625
+ - 0.6640625
+ - 0.671875
+ - 0.6796875
+ - 0.6875
+ - 0.6953125
+ - 0.703125
+ - 0.7109375
+ - 0.71875
+ - 0.7265625
+ - 0.734375
+ - 0.7421875
+ - 0.75
+ - 0.7578125
+ - 0.765625
+ - 0.7734375
+ - 0.78125
+ - 0.7890625
+ - 0.796875
+ - 0.8046875
+ - 0.8125
+ - 0.8203125
+ - 0.828125
+ - 0.8359375
+ - 0.84375
+ - 0.8515625
+ - 0.859375
+ - 0.8671875
+ - 0.875
+ - 0.8828125
+ - 0.890625
+ - 0.8984375
+ - 0.90625
+ - 0.9140625
+ - 0.921875
+ - 0.9296875
+ - 0.9375
+ - 0.9453125
+ - 0.953125
+ - 0.9609375
+ - 0.96875
+ - 0.9765625
+ - 0.984375
+ - 0.9921875
+ greenCurve:
+ overrideState: 0
+ value:
+ curve:
+ serializedVersion: 2
+ m_Curve:
+ - serializedVersion: 3
+ time: 0
+ value: 0
+ inSlope: 1
+ outSlope: 1
+ tangentMode: 0
+ weightedMode: 0
+ inWeight: 0
+ outWeight: 0
+ - serializedVersion: 3
+ time: 1
+ value: 1
+ inSlope: 1
+ outSlope: 1
+ tangentMode: 0
+ weightedMode: 0
+ inWeight: 0
+ outWeight: 0
+ m_PreInfinity: 2
+ m_PostInfinity: 2
+ m_RotationOrder: 4
+ m_Loop: 0
+ m_ZeroValue: 0
+ m_Range: 1
+ cachedData:
+ - 0
+ - 0.0078125
+ - 0.015625
+ - 0.0234375
+ - 0.03125
+ - 0.0390625
+ - 0.046875
+ - 0.0546875
+ - 0.0625
+ - 0.0703125
+ - 0.078125
+ - 0.0859375
+ - 0.09375
+ - 0.1015625
+ - 0.109375
+ - 0.1171875
+ - 0.125
+ - 0.1328125
+ - 0.140625
+ - 0.1484375
+ - 0.15625
+ - 0.1640625
+ - 0.171875
+ - 0.1796875
+ - 0.1875
+ - 0.1953125
+ - 0.203125
+ - 0.2109375
+ - 0.21875
+ - 0.2265625
+ - 0.234375
+ - 0.2421875
+ - 0.25
+ - 0.2578125
+ - 0.265625
+ - 0.2734375
+ - 0.28125
+ - 0.2890625
+ - 0.296875
+ - 0.3046875
+ - 0.3125
+ - 0.3203125
+ - 0.328125
+ - 0.3359375
+ - 0.34375
+ - 0.3515625
+ - 0.359375
+ - 0.3671875
+ - 0.375
+ - 0.3828125
+ - 0.390625
+ - 0.3984375
+ - 0.40625
+ - 0.4140625
+ - 0.421875
+ - 0.4296875
+ - 0.4375
+ - 0.4453125
+ - 0.453125
+ - 0.4609375
+ - 0.46875
+ - 0.4765625
+ - 0.484375
+ - 0.4921875
+ - 0.5
+ - 0.5078125
+ - 0.515625
+ - 0.5234375
+ - 0.53125
+ - 0.5390625
+ - 0.546875
+ - 0.5546875
+ - 0.5625
+ - 0.5703125
+ - 0.578125
+ - 0.5859375
+ - 0.59375
+ - 0.6015625
+ - 0.609375
+ - 0.6171875
+ - 0.625
+ - 0.6328125
+ - 0.640625
+ - 0.6484375
+ - 0.65625
+ - 0.6640625
+ - 0.671875
+ - 0.6796875
+ - 0.6875
+ - 0.6953125
+ - 0.703125
+ - 0.7109375
+ - 0.71875
+ - 0.7265625
+ - 0.734375
+ - 0.7421875
+ - 0.75
+ - 0.7578125
+ - 0.765625
+ - 0.7734375
+ - 0.78125
+ - 0.7890625
+ - 0.796875
+ - 0.8046875
+ - 0.8125
+ - 0.8203125
+ - 0.828125
+ - 0.8359375
+ - 0.84375
+ - 0.8515625
+ - 0.859375
+ - 0.8671875
+ - 0.875
+ - 0.8828125
+ - 0.890625
+ - 0.8984375
+ - 0.90625
+ - 0.9140625
+ - 0.921875
+ - 0.9296875
+ - 0.9375
+ - 0.9453125
+ - 0.953125
+ - 0.9609375
+ - 0.96875
+ - 0.9765625
+ - 0.984375
+ - 0.9921875
+ blueCurve:
+ overrideState: 0
+ value:
+ curve:
+ serializedVersion: 2
+ m_Curve:
+ - serializedVersion: 3
+ time: 0
+ value: 0
+ inSlope: 1
+ outSlope: 1
+ tangentMode: 0
+ weightedMode: 0
+ inWeight: 0
+ outWeight: 0
+ - serializedVersion: 3
+ time: 1
+ value: 1
+ inSlope: 1
+ outSlope: 1
+ tangentMode: 0
+ weightedMode: 0
+ inWeight: 0
+ outWeight: 0
+ m_PreInfinity: 2
+ m_PostInfinity: 2
+ m_RotationOrder: 4
+ m_Loop: 0
+ m_ZeroValue: 0
+ m_Range: 1
+ cachedData:
+ - 0
+ - 0.0078125
+ - 0.015625
+ - 0.0234375
+ - 0.03125
+ - 0.0390625
+ - 0.046875
+ - 0.0546875
+ - 0.0625
+ - 0.0703125
+ - 0.078125
+ - 0.0859375
+ - 0.09375
+ - 0.1015625
+ - 0.109375
+ - 0.1171875
+ - 0.125
+ - 0.1328125
+ - 0.140625
+ - 0.1484375
+ - 0.15625
+ - 0.1640625
+ - 0.171875
+ - 0.1796875
+ - 0.1875
+ - 0.1953125
+ - 0.203125
+ - 0.2109375
+ - 0.21875
+ - 0.2265625
+ - 0.234375
+ - 0.2421875
+ - 0.25
+ - 0.2578125
+ - 0.265625
+ - 0.2734375
+ - 0.28125
+ - 0.2890625
+ - 0.296875
+ - 0.3046875
+ - 0.3125
+ - 0.3203125
+ - 0.328125
+ - 0.3359375
+ - 0.34375
+ - 0.3515625
+ - 0.359375
+ - 0.3671875
+ - 0.375
+ - 0.3828125
+ - 0.390625
+ - 0.3984375
+ - 0.40625
+ - 0.4140625
+ - 0.421875
+ - 0.4296875
+ - 0.4375
+ - 0.4453125
+ - 0.453125
+ - 0.4609375
+ - 0.46875
+ - 0.4765625
+ - 0.484375
+ - 0.4921875
+ - 0.5
+ - 0.5078125
+ - 0.515625
+ - 0.5234375
+ - 0.53125
+ - 0.5390625
+ - 0.546875
+ - 0.5546875
+ - 0.5625
+ - 0.5703125
+ - 0.578125
+ - 0.5859375
+ - 0.59375
+ - 0.6015625
+ - 0.609375
+ - 0.6171875
+ - 0.625
+ - 0.6328125
+ - 0.640625
+ - 0.6484375
+ - 0.65625
+ - 0.6640625
+ - 0.671875
+ - 0.6796875
+ - 0.6875
+ - 0.6953125
+ - 0.703125
+ - 0.7109375
+ - 0.71875
+ - 0.7265625
+ - 0.734375
+ - 0.7421875
+ - 0.75
+ - 0.7578125
+ - 0.765625
+ - 0.7734375
+ - 0.78125
+ - 0.7890625
+ - 0.796875
+ - 0.8046875
+ - 0.8125
+ - 0.8203125
+ - 0.828125
+ - 0.8359375
+ - 0.84375
+ - 0.8515625
+ - 0.859375
+ - 0.8671875
+ - 0.875
+ - 0.8828125
+ - 0.890625
+ - 0.8984375
+ - 0.90625
+ - 0.9140625
+ - 0.921875
+ - 0.9296875
+ - 0.9375
+ - 0.9453125
+ - 0.953125
+ - 0.9609375
+ - 0.96875
+ - 0.9765625
+ - 0.984375
+ - 0.9921875
+ hueVsHueCurve:
+ overrideState: 0
+ value:
+ curve:
+ serializedVersion: 2
+ m_Curve: []
+ m_PreInfinity: 2
+ m_PostInfinity: 2
+ m_RotationOrder: 4
+ m_Loop: 1
+ m_ZeroValue: 0.5
+ m_Range: 1
+ cachedData:
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ hueVsSatCurve:
+ overrideState: 0
+ value:
+ curve:
+ serializedVersion: 2
+ m_Curve: []
+ m_PreInfinity: 2
+ m_PostInfinity: 2
+ m_RotationOrder: 4
+ m_Loop: 1
+ m_ZeroValue: 0.5
+ m_Range: 1
+ cachedData:
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ satVsSatCurve:
+ overrideState: 0
+ value:
+ curve:
+ serializedVersion: 2
+ m_Curve: []
+ m_PreInfinity: 2
+ m_PostInfinity: 2
+ m_RotationOrder: 4
+ m_Loop: 0
+ m_ZeroValue: 0.5
+ m_Range: 1
+ cachedData:
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ lumVsSatCurve:
+ overrideState: 0
+ value:
+ curve:
+ serializedVersion: 2
+ m_Curve: []
+ m_PreInfinity: 2
+ m_PostInfinity: 2
+ m_RotationOrder: 4
+ m_Loop: 0
+ m_ZeroValue: 0.5
+ m_Range: 1
+ cachedData:
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
+ - 0.5
diff --git a/Assets/External/Free Stylized Hand-Painted Skybox/BD Studios Post-Processing Profile.asset.meta b/Assets/External/Free Stylized Hand-Painted Skybox/BD Studios Post-Processing Profile.asset.meta
new file mode 100644
index 000000000..6561f4e7f
--- /dev/null
+++ b/Assets/External/Free Stylized Hand-Painted Skybox/BD Studios Post-Processing Profile.asset.meta
@@ -0,0 +1,16 @@
+fileFormatVersion: 2
+guid: 06cf16cc9cc7a4f4ca46f643b3c176a9
+NativeFormatImporter:
+ externalObjects: {}
+ mainObjectFileID: 0
+ userData:
+ assetBundleName:
+ assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 265475
+ packageName: Free Stylized Hand-Painted Skybox
+ packageVersion: 1.0
+ assetPath: Assets/Free Stylized Hand-Painted Skybox/BD Studios Post-Processing
+ Profile.asset
+ uploadId: 627812
diff --git a/Assets/External/Free Stylized Hand-Painted Skybox/BD_Lighting.lighting b/Assets/External/Free Stylized Hand-Painted Skybox/BD_Lighting.lighting
new file mode 100644
index 000000000..88a3fa5dc
--- /dev/null
+++ b/Assets/External/Free Stylized Hand-Painted Skybox/BD_Lighting.lighting
@@ -0,0 +1,64 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!850595691 &4890085278179872738
+LightingSettings:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_Name: BD_Lighting
+ serializedVersion: 4
+ m_GIWorkflowMode: 1
+ m_EnableBakedLightmaps: 1
+ m_EnableRealtimeLightmaps: 0
+ m_RealtimeEnvironmentLighting: 1
+ m_BounceScale: 1
+ m_AlbedoBoost: 1
+ m_IndirectOutputScale: 1
+ m_UsingShadowmask: 0
+ m_BakeBackend: 2
+ m_LightmapMaxSize: 1024
+ m_BakeResolution: 20
+ m_Padding: 2
+ m_LightmapCompression: 3
+ m_AO: 0
+ m_AOMaxDistance: 1
+ m_CompAOExponent: 1
+ m_CompAOExponentDirect: 0
+ m_ExtractAO: 0
+ m_MixedBakeMode: 0
+ m_LightmapsBakeMode: 1
+ m_FilterMode: 1
+ m_LightmapParameters: {fileID: 15204, guid: 0000000000000000f000000000000000, type: 0}
+ m_ExportTrainingData: 0
+ m_TrainingDataDestination: TrainingData
+ m_RealtimeResolution: 2
+ m_ForceWhiteAlbedo: 0
+ m_ForceUpdates: 0
+ m_FinalGather: 0
+ m_FinalGatherRayCount: 256
+ m_FinalGatherFiltering: 1
+ m_PVRCulling: 1
+ m_PVRSampling: 1
+ m_PVRDirectSampleCount: 32
+ m_PVRSampleCount: 256
+ m_PVREnvironmentSampleCount: 256
+ m_PVREnvironmentReferencePointCount: 2048
+ m_LightProbeSampleCountMultiplier: 4
+ m_PVRBounces: 2
+ m_PVRMinBounces: 2
+ m_PVREnvironmentMIS: 1
+ m_PVRFilteringMode: 1
+ m_PVRDenoiserTypeDirect: 1
+ m_PVRDenoiserTypeIndirect: 1
+ m_PVRDenoiserTypeAO: 1
+ m_PVRFilterTypeDirect: 0
+ m_PVRFilterTypeIndirect: 0
+ m_PVRFilterTypeAO: 0
+ m_PVRFilteringGaussRadiusDirect: 1
+ m_PVRFilteringGaussRadiusIndirect: 5
+ m_PVRFilteringGaussRadiusAO: 2
+ m_PVRFilteringAtrousPositionSigmaDirect: 0.5
+ m_PVRFilteringAtrousPositionSigmaIndirect: 2
+ m_PVRFilteringAtrousPositionSigmaAO: 1
+ m_PVRTiledBaking: 0
diff --git a/Assets/External/Free Stylized Hand-Painted Skybox/BD_Lighting.lighting.meta b/Assets/External/Free Stylized Hand-Painted Skybox/BD_Lighting.lighting.meta
new file mode 100644
index 000000000..b9f07b96a
--- /dev/null
+++ b/Assets/External/Free Stylized Hand-Painted Skybox/BD_Lighting.lighting.meta
@@ -0,0 +1,15 @@
+fileFormatVersion: 2
+guid: 187345041fe57664fae2aa351414b6b6
+NativeFormatImporter:
+ externalObjects: {}
+ mainObjectFileID: 4890085278179872738
+ userData:
+ assetBundleName:
+ assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 265475
+ packageName: Free Stylized Hand-Painted Skybox
+ packageVersion: 1.0
+ assetPath: Assets/Free Stylized Hand-Painted Skybox/BD_Lighting.lighting
+ uploadId: 627812
diff --git a/Assets/External/Free Stylized Hand-Painted Skybox/Demo.unity b/Assets/External/Free Stylized Hand-Painted Skybox/Demo.unity
new file mode 100644
index 000000000..bb5de33ca
--- /dev/null
+++ b/Assets/External/Free Stylized Hand-Painted Skybox/Demo.unity
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:d340095d6c5f504dd2232c9ac1d422e68422ba0e7b7f8c88ba62fead7c200969
+size 12013
diff --git a/Assets/External/Free Stylized Hand-Painted Skybox/Demo.unity.meta b/Assets/External/Free Stylized Hand-Painted Skybox/Demo.unity.meta
new file mode 100644
index 000000000..380e77b32
--- /dev/null
+++ b/Assets/External/Free Stylized Hand-Painted Skybox/Demo.unity.meta
@@ -0,0 +1,14 @@
+fileFormatVersion: 2
+guid: f976c0a276862634f8b6bf2eaff818fb
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 265475
+ packageName: Free Stylized Hand-Painted Skybox
+ packageVersion: 1.0
+ assetPath: Assets/Free Stylized Hand-Painted Skybox/Demo.unity
+ uploadId: 627812
diff --git a/Assets/External/Free Stylized Hand-Painted Skybox/Materials.meta b/Assets/External/Free Stylized Hand-Painted Skybox/Materials.meta
new file mode 100644
index 000000000..1438b814f
--- /dev/null
+++ b/Assets/External/Free Stylized Hand-Painted Skybox/Materials.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: e5cf77ccbc4290e4ca42aa61959b9d79
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/External/Free Stylized Hand-Painted Skybox/Materials/Cloudy01.mat b/Assets/External/Free Stylized Hand-Painted Skybox/Materials/Cloudy01.mat
new file mode 100644
index 000000000..cf32b26fc
--- /dev/null
+++ b/Assets/External/Free Stylized Hand-Painted Skybox/Materials/Cloudy01.mat
@@ -0,0 +1,33 @@
+%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: Cloudy01
+ m_Shader: {fileID: 103, guid: 0000000000000000f000000000000000, type: 0}
+ m_ValidKeywords: []
+ m_InvalidKeywords: []
+ m_LightmapFlags: 4
+ m_EnableInstancingVariants: 0
+ m_DoubleSidedGI: 0
+ m_CustomRenderQueue: -1
+ stringTagMap: {}
+ disabledShaderPasses: []
+ m_SavedProperties:
+ serializedVersion: 3
+ m_TexEnvs:
+ - _Tex:
+ m_Texture: {fileID: 8900000, guid: e31e2fa4fd8bdaa478f1675cf5762fd7, type: 3}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ m_Ints: []
+ m_Floats:
+ - _Exposure: 1
+ - _Rotation: 0
+ m_Colors:
+ - _Tint: {r: 0.5, g: 0.5, b: 0.5, a: 0.5}
+ m_BuildTextureStacks: []
diff --git a/Assets/External/Free Stylized Hand-Painted Skybox/Materials/Cloudy01.mat.meta b/Assets/External/Free Stylized Hand-Painted Skybox/Materials/Cloudy01.mat.meta
new file mode 100644
index 000000000..6b244b7b2
--- /dev/null
+++ b/Assets/External/Free Stylized Hand-Painted Skybox/Materials/Cloudy01.mat.meta
@@ -0,0 +1,15 @@
+fileFormatVersion: 2
+guid: da04fb2a289ef1b47bf5b07b9285dd70
+NativeFormatImporter:
+ externalObjects: {}
+ mainObjectFileID: 2100000
+ userData:
+ assetBundleName:
+ assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 265475
+ packageName: Free Stylized Hand-Painted Skybox
+ packageVersion: 1.0
+ assetPath: Assets/Free Stylized Hand-Painted Skybox/Materials/Cloudy01.mat
+ uploadId: 627812
diff --git a/Assets/External/Free Stylized Hand-Painted Skybox/Materials/Cloudy02.mat b/Assets/External/Free Stylized Hand-Painted Skybox/Materials/Cloudy02.mat
new file mode 100644
index 000000000..920f7a0c9
--- /dev/null
+++ b/Assets/External/Free Stylized Hand-Painted Skybox/Materials/Cloudy02.mat
@@ -0,0 +1,33 @@
+%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: Cloudy02
+ m_Shader: {fileID: 103, guid: 0000000000000000f000000000000000, type: 0}
+ m_ValidKeywords: []
+ m_InvalidKeywords: []
+ m_LightmapFlags: 4
+ m_EnableInstancingVariants: 0
+ m_DoubleSidedGI: 0
+ m_CustomRenderQueue: -1
+ stringTagMap: {}
+ disabledShaderPasses: []
+ m_SavedProperties:
+ serializedVersion: 3
+ m_TexEnvs:
+ - _Tex:
+ m_Texture: {fileID: 8900000, guid: f1b504bff46c95346b5b1e99fd731eff, type: 3}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ m_Ints: []
+ m_Floats:
+ - _Exposure: 1
+ - _Rotation: 0
+ m_Colors:
+ - _Tint: {r: 0.5, g: 0.5, b: 0.5, a: 0.5}
+ m_BuildTextureStacks: []
diff --git a/Assets/External/Free Stylized Hand-Painted Skybox/Materials/Cloudy02.mat.meta b/Assets/External/Free Stylized Hand-Painted Skybox/Materials/Cloudy02.mat.meta
new file mode 100644
index 000000000..62f626edd
--- /dev/null
+++ b/Assets/External/Free Stylized Hand-Painted Skybox/Materials/Cloudy02.mat.meta
@@ -0,0 +1,15 @@
+fileFormatVersion: 2
+guid: d4393bf45f92e74499f230d78e8cab9f
+NativeFormatImporter:
+ externalObjects: {}
+ mainObjectFileID: 2100000
+ userData:
+ assetBundleName:
+ assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 265475
+ packageName: Free Stylized Hand-Painted Skybox
+ packageVersion: 1.0
+ assetPath: Assets/Free Stylized Hand-Painted Skybox/Materials/Cloudy02.mat
+ uploadId: 627812
diff --git a/Assets/External/Free Stylized Hand-Painted Skybox/Materials/Cloudy03.mat b/Assets/External/Free Stylized Hand-Painted Skybox/Materials/Cloudy03.mat
new file mode 100644
index 000000000..8b19c3963
--- /dev/null
+++ b/Assets/External/Free Stylized Hand-Painted Skybox/Materials/Cloudy03.mat
@@ -0,0 +1,33 @@
+%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: Cloudy03
+ m_Shader: {fileID: 103, guid: 0000000000000000f000000000000000, type: 0}
+ m_ValidKeywords: []
+ m_InvalidKeywords: []
+ m_LightmapFlags: 4
+ m_EnableInstancingVariants: 0
+ m_DoubleSidedGI: 0
+ m_CustomRenderQueue: -1
+ stringTagMap: {}
+ disabledShaderPasses: []
+ m_SavedProperties:
+ serializedVersion: 3
+ m_TexEnvs:
+ - _Tex:
+ m_Texture: {fileID: 8900000, guid: 3d60c74e415eb044cb7c63f12a1d955e, type: 3}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ m_Ints: []
+ m_Floats:
+ - _Exposure: 1
+ - _Rotation: 0
+ m_Colors:
+ - _Tint: {r: 0.5, g: 0.5, b: 0.5, a: 0.5}
+ m_BuildTextureStacks: []
diff --git a/Assets/External/Free Stylized Hand-Painted Skybox/Materials/Cloudy03.mat.meta b/Assets/External/Free Stylized Hand-Painted Skybox/Materials/Cloudy03.mat.meta
new file mode 100644
index 000000000..9f1a9c580
--- /dev/null
+++ b/Assets/External/Free Stylized Hand-Painted Skybox/Materials/Cloudy03.mat.meta
@@ -0,0 +1,15 @@
+fileFormatVersion: 2
+guid: 896fe09c49b73a44ead00a982ee46e6b
+NativeFormatImporter:
+ externalObjects: {}
+ mainObjectFileID: 2100000
+ userData:
+ assetBundleName:
+ assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 265475
+ packageName: Free Stylized Hand-Painted Skybox
+ packageVersion: 1.0
+ assetPath: Assets/Free Stylized Hand-Painted Skybox/Materials/Cloudy03.mat
+ uploadId: 627812
diff --git a/Assets/External/Free Stylized Hand-Painted Skybox/Materials/Cloudy04.mat b/Assets/External/Free Stylized Hand-Painted Skybox/Materials/Cloudy04.mat
new file mode 100644
index 000000000..854239449
--- /dev/null
+++ b/Assets/External/Free Stylized Hand-Painted Skybox/Materials/Cloudy04.mat
@@ -0,0 +1,33 @@
+%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: Cloudy04
+ m_Shader: {fileID: 103, guid: 0000000000000000f000000000000000, type: 0}
+ m_ValidKeywords: []
+ m_InvalidKeywords: []
+ m_LightmapFlags: 4
+ m_EnableInstancingVariants: 0
+ m_DoubleSidedGI: 0
+ m_CustomRenderQueue: -1
+ stringTagMap: {}
+ disabledShaderPasses: []
+ m_SavedProperties:
+ serializedVersion: 3
+ m_TexEnvs:
+ - _Tex:
+ m_Texture: {fileID: 8900000, guid: 663e4e044569d5d4fab103ab8ae7719c, type: 3}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ m_Ints: []
+ m_Floats:
+ - _Exposure: 1
+ - _Rotation: 0
+ m_Colors:
+ - _Tint: {r: 0.5, g: 0.5, b: 0.5, a: 0.5}
+ m_BuildTextureStacks: []
diff --git a/Assets/External/Free Stylized Hand-Painted Skybox/Materials/Cloudy04.mat.meta b/Assets/External/Free Stylized Hand-Painted Skybox/Materials/Cloudy04.mat.meta
new file mode 100644
index 000000000..de626fb38
--- /dev/null
+++ b/Assets/External/Free Stylized Hand-Painted Skybox/Materials/Cloudy04.mat.meta
@@ -0,0 +1,15 @@
+fileFormatVersion: 2
+guid: b01d8a5305a527c4daeab5318708e238
+NativeFormatImporter:
+ externalObjects: {}
+ mainObjectFileID: 2100000
+ userData:
+ assetBundleName:
+ assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 265475
+ packageName: Free Stylized Hand-Painted Skybox
+ packageVersion: 1.0
+ assetPath: Assets/Free Stylized Hand-Painted Skybox/Materials/Cloudy04.mat
+ uploadId: 627812
diff --git a/Assets/External/Free Stylized Hand-Painted Skybox/Materials/Dawn.mat b/Assets/External/Free Stylized Hand-Painted Skybox/Materials/Dawn.mat
new file mode 100644
index 000000000..96a7eb14b
--- /dev/null
+++ b/Assets/External/Free Stylized Hand-Painted Skybox/Materials/Dawn.mat
@@ -0,0 +1,33 @@
+%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: Dawn
+ m_Shader: {fileID: 103, guid: 0000000000000000f000000000000000, type: 0}
+ m_ValidKeywords: []
+ m_InvalidKeywords: []
+ m_LightmapFlags: 4
+ m_EnableInstancingVariants: 0
+ m_DoubleSidedGI: 0
+ m_CustomRenderQueue: -1
+ stringTagMap: {}
+ disabledShaderPasses: []
+ m_SavedProperties:
+ serializedVersion: 3
+ m_TexEnvs:
+ - _Tex:
+ m_Texture: {fileID: 8900000, guid: 41662f129e3c1054392aed1755433fd5, type: 3}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ m_Ints: []
+ m_Floats:
+ - _Exposure: 1
+ - _Rotation: 0
+ m_Colors:
+ - _Tint: {r: 0.5, g: 0.5, b: 0.5, a: 0.5}
+ m_BuildTextureStacks: []
diff --git a/Assets/External/Free Stylized Hand-Painted Skybox/Materials/Dawn.mat.meta b/Assets/External/Free Stylized Hand-Painted Skybox/Materials/Dawn.mat.meta
new file mode 100644
index 000000000..b828f887b
--- /dev/null
+++ b/Assets/External/Free Stylized Hand-Painted Skybox/Materials/Dawn.mat.meta
@@ -0,0 +1,15 @@
+fileFormatVersion: 2
+guid: b73dc2c0c9eceae4486bdb5b744fceb9
+NativeFormatImporter:
+ externalObjects: {}
+ mainObjectFileID: 2100000
+ userData:
+ assetBundleName:
+ assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 265475
+ packageName: Free Stylized Hand-Painted Skybox
+ packageVersion: 1.0
+ assetPath: Assets/Free Stylized Hand-Painted Skybox/Materials/Dawn.mat
+ uploadId: 627812
diff --git a/Assets/External/Free Stylized Hand-Painted Skybox/Materials/Dawn_Cloudy.mat b/Assets/External/Free Stylized Hand-Painted Skybox/Materials/Dawn_Cloudy.mat
new file mode 100644
index 000000000..b55d9fbba
--- /dev/null
+++ b/Assets/External/Free Stylized Hand-Painted Skybox/Materials/Dawn_Cloudy.mat
@@ -0,0 +1,33 @@
+%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: Dawn_Cloudy
+ m_Shader: {fileID: 103, guid: 0000000000000000f000000000000000, type: 0}
+ m_ValidKeywords: []
+ m_InvalidKeywords: []
+ m_LightmapFlags: 4
+ m_EnableInstancingVariants: 0
+ m_DoubleSidedGI: 0
+ m_CustomRenderQueue: -1
+ stringTagMap: {}
+ disabledShaderPasses: []
+ m_SavedProperties:
+ serializedVersion: 3
+ m_TexEnvs:
+ - _Tex:
+ m_Texture: {fileID: 8900000, guid: eb2951db9066f984f85ff41f6e9525f7, type: 3}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ m_Ints: []
+ m_Floats:
+ - _Exposure: 1
+ - _Rotation: 0
+ m_Colors:
+ - _Tint: {r: 0.5, g: 0.5, b: 0.5, a: 0.5}
+ m_BuildTextureStacks: []
diff --git a/Assets/External/Free Stylized Hand-Painted Skybox/Materials/Dawn_Cloudy.mat.meta b/Assets/External/Free Stylized Hand-Painted Skybox/Materials/Dawn_Cloudy.mat.meta
new file mode 100644
index 000000000..e55d8571f
--- /dev/null
+++ b/Assets/External/Free Stylized Hand-Painted Skybox/Materials/Dawn_Cloudy.mat.meta
@@ -0,0 +1,15 @@
+fileFormatVersion: 2
+guid: 3776415b8d326db4cb696fe00db0540e
+NativeFormatImporter:
+ externalObjects: {}
+ mainObjectFileID: 2100000
+ userData:
+ assetBundleName:
+ assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 265475
+ packageName: Free Stylized Hand-Painted Skybox
+ packageVersion: 1.0
+ assetPath: Assets/Free Stylized Hand-Painted Skybox/Materials/Dawn_Cloudy.mat
+ uploadId: 627812
diff --git a/Assets/External/Free Stylized Hand-Painted Skybox/Materials/Day_Clear.mat b/Assets/External/Free Stylized Hand-Painted Skybox/Materials/Day_Clear.mat
new file mode 100644
index 000000000..15abce43d
--- /dev/null
+++ b/Assets/External/Free Stylized Hand-Painted Skybox/Materials/Day_Clear.mat
@@ -0,0 +1,33 @@
+%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: Day_Clear
+ m_Shader: {fileID: 103, guid: 0000000000000000f000000000000000, type: 0}
+ m_ValidKeywords: []
+ m_InvalidKeywords: []
+ m_LightmapFlags: 4
+ m_EnableInstancingVariants: 0
+ m_DoubleSidedGI: 0
+ m_CustomRenderQueue: -1
+ stringTagMap: {}
+ disabledShaderPasses: []
+ m_SavedProperties:
+ serializedVersion: 3
+ m_TexEnvs:
+ - _Tex:
+ m_Texture: {fileID: 8900000, guid: 4c6e3caff9a2c00459a8805bc96f8f69, type: 3}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ m_Ints: []
+ m_Floats:
+ - _Exposure: 1
+ - _Rotation: 0
+ m_Colors:
+ - _Tint: {r: 0.5, g: 0.5, b: 0.5, a: 0.5}
+ m_BuildTextureStacks: []
diff --git a/Assets/External/Free Stylized Hand-Painted Skybox/Materials/Day_Clear.mat.meta b/Assets/External/Free Stylized Hand-Painted Skybox/Materials/Day_Clear.mat.meta
new file mode 100644
index 000000000..9f26fb853
--- /dev/null
+++ b/Assets/External/Free Stylized Hand-Painted Skybox/Materials/Day_Clear.mat.meta
@@ -0,0 +1,15 @@
+fileFormatVersion: 2
+guid: 1e5e82b01cae80b44b78975b9c2d7741
+NativeFormatImporter:
+ externalObjects: {}
+ mainObjectFileID: 2100000
+ userData:
+ assetBundleName:
+ assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 265475
+ packageName: Free Stylized Hand-Painted Skybox
+ packageVersion: 1.0
+ assetPath: Assets/Free Stylized Hand-Painted Skybox/Materials/Day_Clear.mat
+ uploadId: 627812
diff --git a/Assets/External/Free Stylized Hand-Painted Skybox/Materials/Midnight.mat b/Assets/External/Free Stylized Hand-Painted Skybox/Materials/Midnight.mat
new file mode 100644
index 000000000..877c149e8
--- /dev/null
+++ b/Assets/External/Free Stylized Hand-Painted Skybox/Materials/Midnight.mat
@@ -0,0 +1,33 @@
+%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: Midnight
+ m_Shader: {fileID: 103, guid: 0000000000000000f000000000000000, type: 0}
+ m_ValidKeywords: []
+ m_InvalidKeywords: []
+ m_LightmapFlags: 4
+ m_EnableInstancingVariants: 0
+ m_DoubleSidedGI: 0
+ m_CustomRenderQueue: -1
+ stringTagMap: {}
+ disabledShaderPasses: []
+ m_SavedProperties:
+ serializedVersion: 3
+ m_TexEnvs:
+ - _Tex:
+ m_Texture: {fileID: 8900000, guid: ba4f9681a4f907647a229035e27b138a, type: 3}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ m_Ints: []
+ m_Floats:
+ - _Exposure: 1
+ - _Rotation: 0
+ m_Colors:
+ - _Tint: {r: 0.5, g: 0.5, b: 0.5, a: 0.5}
+ m_BuildTextureStacks: []
diff --git a/Assets/External/Free Stylized Hand-Painted Skybox/Materials/Midnight.mat.meta b/Assets/External/Free Stylized Hand-Painted Skybox/Materials/Midnight.mat.meta
new file mode 100644
index 000000000..7191981ba
--- /dev/null
+++ b/Assets/External/Free Stylized Hand-Painted Skybox/Materials/Midnight.mat.meta
@@ -0,0 +1,15 @@
+fileFormatVersion: 2
+guid: 5eae8f65eabf7ee4994b422cd10214bc
+NativeFormatImporter:
+ externalObjects: {}
+ mainObjectFileID: 2100000
+ userData:
+ assetBundleName:
+ assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 265475
+ packageName: Free Stylized Hand-Painted Skybox
+ packageVersion: 1.0
+ assetPath: Assets/Free Stylized Hand-Painted Skybox/Materials/Midnight.mat
+ uploadId: 627812
diff --git a/Assets/External/Free Stylized Hand-Painted Skybox/Materials/Midnight_Stars.mat b/Assets/External/Free Stylized Hand-Painted Skybox/Materials/Midnight_Stars.mat
new file mode 100644
index 000000000..0800a852d
--- /dev/null
+++ b/Assets/External/Free Stylized Hand-Painted Skybox/Materials/Midnight_Stars.mat
@@ -0,0 +1,33 @@
+%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: Midnight_Stars
+ m_Shader: {fileID: 103, guid: 0000000000000000f000000000000000, type: 0}
+ m_ValidKeywords: []
+ m_InvalidKeywords: []
+ m_LightmapFlags: 4
+ m_EnableInstancingVariants: 0
+ m_DoubleSidedGI: 0
+ m_CustomRenderQueue: -1
+ stringTagMap: {}
+ disabledShaderPasses: []
+ m_SavedProperties:
+ serializedVersion: 3
+ m_TexEnvs:
+ - _Tex:
+ m_Texture: {fileID: 8900000, guid: 3b61a4965ad81044d8fd04c6738c08bb, type: 3}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ m_Ints: []
+ m_Floats:
+ - _Exposure: 1
+ - _Rotation: 0
+ m_Colors:
+ - _Tint: {r: 0.5, g: 0.5, b: 0.5, a: 0.5}
+ m_BuildTextureStacks: []
diff --git a/Assets/External/Free Stylized Hand-Painted Skybox/Materials/Midnight_Stars.mat.meta b/Assets/External/Free Stylized Hand-Painted Skybox/Materials/Midnight_Stars.mat.meta
new file mode 100644
index 000000000..c15904777
--- /dev/null
+++ b/Assets/External/Free Stylized Hand-Painted Skybox/Materials/Midnight_Stars.mat.meta
@@ -0,0 +1,15 @@
+fileFormatVersion: 2
+guid: b7c00be18a6e7a2428b01c61aea8c5b6
+NativeFormatImporter:
+ externalObjects: {}
+ mainObjectFileID: 2100000
+ userData:
+ assetBundleName:
+ assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 265475
+ packageName: Free Stylized Hand-Painted Skybox
+ packageVersion: 1.0
+ assetPath: Assets/Free Stylized Hand-Painted Skybox/Materials/Midnight_Stars.mat
+ uploadId: 627812
diff --git a/Assets/External/Free Stylized Hand-Painted Skybox/Materials/Midnight_Stars02.mat b/Assets/External/Free Stylized Hand-Painted Skybox/Materials/Midnight_Stars02.mat
new file mode 100644
index 000000000..f1d8a2a12
--- /dev/null
+++ b/Assets/External/Free Stylized Hand-Painted Skybox/Materials/Midnight_Stars02.mat
@@ -0,0 +1,33 @@
+%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: Midnight_Stars02
+ m_Shader: {fileID: 103, guid: 0000000000000000f000000000000000, type: 0}
+ m_ValidKeywords: []
+ m_InvalidKeywords: []
+ m_LightmapFlags: 4
+ m_EnableInstancingVariants: 0
+ m_DoubleSidedGI: 0
+ m_CustomRenderQueue: -1
+ stringTagMap: {}
+ disabledShaderPasses: []
+ m_SavedProperties:
+ serializedVersion: 3
+ m_TexEnvs:
+ - _Tex:
+ m_Texture: {fileID: 8900000, guid: e29caa9aad3602d40be0bdfa8138d34e, type: 3}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ m_Ints: []
+ m_Floats:
+ - _Exposure: 1
+ - _Rotation: 0
+ m_Colors:
+ - _Tint: {r: 0.5, g: 0.5, b: 0.5, a: 0.5}
+ m_BuildTextureStacks: []
diff --git a/Assets/External/Free Stylized Hand-Painted Skybox/Materials/Midnight_Stars02.mat.meta b/Assets/External/Free Stylized Hand-Painted Skybox/Materials/Midnight_Stars02.mat.meta
new file mode 100644
index 000000000..add2bd8e3
--- /dev/null
+++ b/Assets/External/Free Stylized Hand-Painted Skybox/Materials/Midnight_Stars02.mat.meta
@@ -0,0 +1,15 @@
+fileFormatVersion: 2
+guid: b8b51e91d70758d4587a58e98389c07a
+NativeFormatImporter:
+ externalObjects: {}
+ mainObjectFileID: 2100000
+ userData:
+ assetBundleName:
+ assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 265475
+ packageName: Free Stylized Hand-Painted Skybox
+ packageVersion: 1.0
+ assetPath: Assets/Free Stylized Hand-Painted Skybox/Materials/Midnight_Stars02.mat
+ uploadId: 627812
diff --git a/Assets/External/Free Stylized Hand-Painted Skybox/Materials/Sunset.mat b/Assets/External/Free Stylized Hand-Painted Skybox/Materials/Sunset.mat
new file mode 100644
index 000000000..e33f9abdf
--- /dev/null
+++ b/Assets/External/Free Stylized Hand-Painted Skybox/Materials/Sunset.mat
@@ -0,0 +1,33 @@
+%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: Sunset
+ m_Shader: {fileID: 103, guid: 0000000000000000f000000000000000, type: 0}
+ m_ValidKeywords: []
+ m_InvalidKeywords: []
+ m_LightmapFlags: 4
+ m_EnableInstancingVariants: 0
+ m_DoubleSidedGI: 0
+ m_CustomRenderQueue: -1
+ stringTagMap: {}
+ disabledShaderPasses: []
+ m_SavedProperties:
+ serializedVersion: 3
+ m_TexEnvs:
+ - _Tex:
+ m_Texture: {fileID: 8900000, guid: 8a923fadf769f794a8d3a9806f92c8c9, type: 3}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ m_Ints: []
+ m_Floats:
+ - _Exposure: 1
+ - _Rotation: 0
+ m_Colors:
+ - _Tint: {r: 0.5, g: 0.5, b: 0.5, a: 0.5}
+ m_BuildTextureStacks: []
diff --git a/Assets/External/Free Stylized Hand-Painted Skybox/Materials/Sunset.mat.meta b/Assets/External/Free Stylized Hand-Painted Skybox/Materials/Sunset.mat.meta
new file mode 100644
index 000000000..fbcd17ba8
--- /dev/null
+++ b/Assets/External/Free Stylized Hand-Painted Skybox/Materials/Sunset.mat.meta
@@ -0,0 +1,15 @@
+fileFormatVersion: 2
+guid: 170f2a047c448444ca1b8e2d20f504f1
+NativeFormatImporter:
+ externalObjects: {}
+ mainObjectFileID: 2100000
+ userData:
+ assetBundleName:
+ assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 265475
+ packageName: Free Stylized Hand-Painted Skybox
+ packageVersion: 1.0
+ assetPath: Assets/Free Stylized Hand-Painted Skybox/Materials/Sunset.mat
+ uploadId: 627812
diff --git a/Assets/External/Free Stylized Hand-Painted Skybox/Materials/Sunset_Cloudy.mat b/Assets/External/Free Stylized Hand-Painted Skybox/Materials/Sunset_Cloudy.mat
new file mode 100644
index 000000000..0a9b3ec12
--- /dev/null
+++ b/Assets/External/Free Stylized Hand-Painted Skybox/Materials/Sunset_Cloudy.mat
@@ -0,0 +1,33 @@
+%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: Sunset_Cloudy
+ m_Shader: {fileID: 103, guid: 0000000000000000f000000000000000, type: 0}
+ m_ValidKeywords: []
+ m_InvalidKeywords: []
+ m_LightmapFlags: 4
+ m_EnableInstancingVariants: 0
+ m_DoubleSidedGI: 0
+ m_CustomRenderQueue: -1
+ stringTagMap: {}
+ disabledShaderPasses: []
+ m_SavedProperties:
+ serializedVersion: 3
+ m_TexEnvs:
+ - _Tex:
+ m_Texture: {fileID: 8900000, guid: 7e3608d3009d2f74c8fc155c9ad6d76e, type: 3}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ m_Ints: []
+ m_Floats:
+ - _Exposure: 1
+ - _Rotation: 0
+ m_Colors:
+ - _Tint: {r: 0.5, g: 0.5, b: 0.5, a: 0.5}
+ m_BuildTextureStacks: []
diff --git a/Assets/External/Free Stylized Hand-Painted Skybox/Materials/Sunset_Cloudy.mat.meta b/Assets/External/Free Stylized Hand-Painted Skybox/Materials/Sunset_Cloudy.mat.meta
new file mode 100644
index 000000000..d7b0167eb
--- /dev/null
+++ b/Assets/External/Free Stylized Hand-Painted Skybox/Materials/Sunset_Cloudy.mat.meta
@@ -0,0 +1,15 @@
+fileFormatVersion: 2
+guid: bebabbca203115940bf67dfe65237b36
+NativeFormatImporter:
+ externalObjects: {}
+ mainObjectFileID: 2100000
+ userData:
+ assetBundleName:
+ assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 265475
+ packageName: Free Stylized Hand-Painted Skybox
+ packageVersion: 1.0
+ assetPath: Assets/Free Stylized Hand-Painted Skybox/Materials/Sunset_Cloudy.mat
+ uploadId: 627812
diff --git a/Assets/External/Free Stylized Hand-Painted Skybox/Textures.meta b/Assets/External/Free Stylized Hand-Painted Skybox/Textures.meta
new file mode 100644
index 000000000..1ea00afa0
--- /dev/null
+++ b/Assets/External/Free Stylized Hand-Painted Skybox/Textures.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 29a3eadb29517be4183463ae9bf75130
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/External/Free Stylized Hand-Painted Skybox/Textures/Cloudy01.png b/Assets/External/Free Stylized Hand-Painted Skybox/Textures/Cloudy01.png
new file mode 100644
index 000000000..7c1679888
--- /dev/null
+++ b/Assets/External/Free Stylized Hand-Painted Skybox/Textures/Cloudy01.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:7f25f1f518b2ba233fe182990e49169a94844af78f888f9898810658d19a4bff
+size 6177400
diff --git a/Assets/External/Free Stylized Hand-Painted Skybox/Textures/Cloudy01.png.meta b/Assets/External/Free Stylized Hand-Painted Skybox/Textures/Cloudy01.png.meta
new file mode 100644
index 000000000..23ecd4223
--- /dev/null
+++ b/Assets/External/Free Stylized Hand-Painted Skybox/Textures/Cloudy01.png.meta
@@ -0,0 +1,129 @@
+fileFormatVersion: 2
+guid: e31e2fa4fd8bdaa478f1675cf5762fd7
+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
+ vTOnly: 0
+ ignoreMasterTextureLimit: 0
+ grayScaleToAlpha: 0
+ generateCubemap: 2
+ cubemapConvolution: 0
+ seamlessCubemap: 1
+ textureFormat: 1
+ maxTextureSize: 2048
+ textureSettings:
+ serializedVersion: 2
+ filterMode: 1
+ aniso: 1
+ mipBias: 0
+ wrapU: 1
+ wrapV: 1
+ wrapW: 1
+ 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: 2
+ singleChannelComponent: 0
+ flipbookRows: 1
+ flipbookColumns: 1
+ maxTextureSizeSet: 0
+ compressionQualitySet: 0
+ textureFormatSet: 0
+ ignorePngGamma: 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
+ - 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
+ pSDShowRemoveMatteOption: 0
+ userData:
+ assetBundleName:
+ assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 265475
+ packageName: Free Stylized Hand-Painted Skybox
+ packageVersion: 1.0
+ assetPath: Assets/Free Stylized Hand-Painted Skybox/Textures/Cloudy01.png
+ uploadId: 627812
diff --git a/Assets/External/Free Stylized Hand-Painted Skybox/Textures/Cloudy02.png b/Assets/External/Free Stylized Hand-Painted Skybox/Textures/Cloudy02.png
new file mode 100644
index 000000000..e305a3770
--- /dev/null
+++ b/Assets/External/Free Stylized Hand-Painted Skybox/Textures/Cloudy02.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:4a79de0ed8c087e2576a9624aee6cbf6c6652ee18173676813371dfaf645bf88
+size 6927622
diff --git a/Assets/External/Free Stylized Hand-Painted Skybox/Textures/Cloudy02.png.meta b/Assets/External/Free Stylized Hand-Painted Skybox/Textures/Cloudy02.png.meta
new file mode 100644
index 000000000..16332331b
--- /dev/null
+++ b/Assets/External/Free Stylized Hand-Painted Skybox/Textures/Cloudy02.png.meta
@@ -0,0 +1,129 @@
+fileFormatVersion: 2
+guid: f1b504bff46c95346b5b1e99fd731eff
+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
+ vTOnly: 0
+ ignoreMasterTextureLimit: 0
+ grayScaleToAlpha: 0
+ generateCubemap: 2
+ cubemapConvolution: 0
+ seamlessCubemap: 1
+ textureFormat: 1
+ maxTextureSize: 2048
+ textureSettings:
+ serializedVersion: 2
+ filterMode: 1
+ aniso: 1
+ mipBias: 0
+ wrapU: 1
+ wrapV: 1
+ wrapW: 1
+ 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: 2
+ singleChannelComponent: 0
+ flipbookRows: 1
+ flipbookColumns: 1
+ maxTextureSizeSet: 0
+ compressionQualitySet: 0
+ textureFormatSet: 0
+ ignorePngGamma: 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
+ - 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
+ pSDShowRemoveMatteOption: 0
+ userData:
+ assetBundleName:
+ assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 265475
+ packageName: Free Stylized Hand-Painted Skybox
+ packageVersion: 1.0
+ assetPath: Assets/Free Stylized Hand-Painted Skybox/Textures/Cloudy02.png
+ uploadId: 627812
diff --git a/Assets/External/Free Stylized Hand-Painted Skybox/Textures/Cloudy03.png b/Assets/External/Free Stylized Hand-Painted Skybox/Textures/Cloudy03.png
new file mode 100644
index 000000000..d9d3d82e1
--- /dev/null
+++ b/Assets/External/Free Stylized Hand-Painted Skybox/Textures/Cloudy03.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:e4ddfb30a52015502542e96bd99316848a84b8dbfdf663ee018f74797272a79c
+size 2292106
diff --git a/Assets/External/Free Stylized Hand-Painted Skybox/Textures/Cloudy03.png.meta b/Assets/External/Free Stylized Hand-Painted Skybox/Textures/Cloudy03.png.meta
new file mode 100644
index 000000000..40150acbb
--- /dev/null
+++ b/Assets/External/Free Stylized Hand-Painted Skybox/Textures/Cloudy03.png.meta
@@ -0,0 +1,129 @@
+fileFormatVersion: 2
+guid: 3d60c74e415eb044cb7c63f12a1d955e
+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
+ vTOnly: 0
+ ignoreMasterTextureLimit: 0
+ grayScaleToAlpha: 0
+ generateCubemap: 2
+ cubemapConvolution: 0
+ seamlessCubemap: 1
+ textureFormat: 1
+ maxTextureSize: 2048
+ textureSettings:
+ serializedVersion: 2
+ filterMode: 1
+ aniso: 1
+ mipBias: 0
+ wrapU: 1
+ wrapV: 1
+ wrapW: 1
+ 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: 2
+ singleChannelComponent: 0
+ flipbookRows: 1
+ flipbookColumns: 1
+ maxTextureSizeSet: 0
+ compressionQualitySet: 0
+ textureFormatSet: 0
+ ignorePngGamma: 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
+ - 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
+ pSDShowRemoveMatteOption: 0
+ userData:
+ assetBundleName:
+ assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 265475
+ packageName: Free Stylized Hand-Painted Skybox
+ packageVersion: 1.0
+ assetPath: Assets/Free Stylized Hand-Painted Skybox/Textures/Cloudy03.png
+ uploadId: 627812
diff --git a/Assets/External/Free Stylized Hand-Painted Skybox/Textures/Cloudy04.png b/Assets/External/Free Stylized Hand-Painted Skybox/Textures/Cloudy04.png
new file mode 100644
index 000000000..8fddff772
--- /dev/null
+++ b/Assets/External/Free Stylized Hand-Painted Skybox/Textures/Cloudy04.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:0b592ec8540d28ef7ed0ed8f3738dfe89ee2dad3e2ecf00616660a1dc2b12001
+size 4044120
diff --git a/Assets/External/Free Stylized Hand-Painted Skybox/Textures/Cloudy04.png.meta b/Assets/External/Free Stylized Hand-Painted Skybox/Textures/Cloudy04.png.meta
new file mode 100644
index 000000000..4692ea53e
--- /dev/null
+++ b/Assets/External/Free Stylized Hand-Painted Skybox/Textures/Cloudy04.png.meta
@@ -0,0 +1,129 @@
+fileFormatVersion: 2
+guid: 663e4e044569d5d4fab103ab8ae7719c
+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
+ vTOnly: 0
+ ignoreMasterTextureLimit: 0
+ grayScaleToAlpha: 0
+ generateCubemap: 2
+ cubemapConvolution: 0
+ seamlessCubemap: 1
+ textureFormat: 1
+ maxTextureSize: 2048
+ textureSettings:
+ serializedVersion: 2
+ filterMode: 1
+ aniso: 1
+ mipBias: 0
+ wrapU: 1
+ wrapV: 1
+ wrapW: 1
+ 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: 2
+ singleChannelComponent: 0
+ flipbookRows: 1
+ flipbookColumns: 1
+ maxTextureSizeSet: 0
+ compressionQualitySet: 0
+ textureFormatSet: 0
+ ignorePngGamma: 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
+ - 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
+ pSDShowRemoveMatteOption: 0
+ userData:
+ assetBundleName:
+ assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 265475
+ packageName: Free Stylized Hand-Painted Skybox
+ packageVersion: 1.0
+ assetPath: Assets/Free Stylized Hand-Painted Skybox/Textures/Cloudy04.png
+ uploadId: 627812
diff --git a/Assets/External/Free Stylized Hand-Painted Skybox/Textures/Dawn.png b/Assets/External/Free Stylized Hand-Painted Skybox/Textures/Dawn.png
new file mode 100644
index 000000000..657a3d978
--- /dev/null
+++ b/Assets/External/Free Stylized Hand-Painted Skybox/Textures/Dawn.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:0ef2cb30faf2f9de8eb26917b5822122edf83bf6ad7c5ac951152dad91411807
+size 143627
diff --git a/Assets/External/Free Stylized Hand-Painted Skybox/Textures/Dawn.png.meta b/Assets/External/Free Stylized Hand-Painted Skybox/Textures/Dawn.png.meta
new file mode 100644
index 000000000..0444e6bd4
--- /dev/null
+++ b/Assets/External/Free Stylized Hand-Painted Skybox/Textures/Dawn.png.meta
@@ -0,0 +1,129 @@
+fileFormatVersion: 2
+guid: 41662f129e3c1054392aed1755433fd5
+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
+ vTOnly: 0
+ ignoreMasterTextureLimit: 0
+ grayScaleToAlpha: 0
+ generateCubemap: 2
+ cubemapConvolution: 0
+ seamlessCubemap: 1
+ textureFormat: 1
+ maxTextureSize: 2048
+ textureSettings:
+ serializedVersion: 2
+ filterMode: 1
+ aniso: 1
+ mipBias: 0
+ wrapU: 1
+ wrapV: 1
+ wrapW: 1
+ 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: 2
+ singleChannelComponent: 0
+ flipbookRows: 1
+ flipbookColumns: 1
+ maxTextureSizeSet: 0
+ compressionQualitySet: 0
+ textureFormatSet: 0
+ ignorePngGamma: 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
+ - 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
+ pSDShowRemoveMatteOption: 0
+ userData:
+ assetBundleName:
+ assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 265475
+ packageName: Free Stylized Hand-Painted Skybox
+ packageVersion: 1.0
+ assetPath: Assets/Free Stylized Hand-Painted Skybox/Textures/Dawn.png
+ uploadId: 627812
diff --git a/Assets/External/Free Stylized Hand-Painted Skybox/Textures/Dawn_Cloudy.png b/Assets/External/Free Stylized Hand-Painted Skybox/Textures/Dawn_Cloudy.png
new file mode 100644
index 000000000..4f8750ba1
--- /dev/null
+++ b/Assets/External/Free Stylized Hand-Painted Skybox/Textures/Dawn_Cloudy.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:8b89bd28c8432f024f8f7aaab17d7c2bb9c4f67042f416d2a3cba0dbac578fcc
+size 8199689
diff --git a/Assets/External/Free Stylized Hand-Painted Skybox/Textures/Dawn_Cloudy.png.meta b/Assets/External/Free Stylized Hand-Painted Skybox/Textures/Dawn_Cloudy.png.meta
new file mode 100644
index 000000000..ea2d7f95c
--- /dev/null
+++ b/Assets/External/Free Stylized Hand-Painted Skybox/Textures/Dawn_Cloudy.png.meta
@@ -0,0 +1,129 @@
+fileFormatVersion: 2
+guid: eb2951db9066f984f85ff41f6e9525f7
+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
+ vTOnly: 0
+ ignoreMasterTextureLimit: 0
+ grayScaleToAlpha: 0
+ generateCubemap: 2
+ cubemapConvolution: 0
+ seamlessCubemap: 1
+ textureFormat: 1
+ maxTextureSize: 2048
+ textureSettings:
+ serializedVersion: 2
+ filterMode: 1
+ aniso: 1
+ mipBias: 0
+ wrapU: 1
+ wrapV: 1
+ wrapW: 1
+ 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: 2
+ singleChannelComponent: 0
+ flipbookRows: 1
+ flipbookColumns: 1
+ maxTextureSizeSet: 0
+ compressionQualitySet: 0
+ textureFormatSet: 0
+ ignorePngGamma: 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
+ - 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
+ pSDShowRemoveMatteOption: 0
+ userData:
+ assetBundleName:
+ assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 265475
+ packageName: Free Stylized Hand-Painted Skybox
+ packageVersion: 1.0
+ assetPath: Assets/Free Stylized Hand-Painted Skybox/Textures/Dawn_Cloudy.png
+ uploadId: 627812
diff --git a/Assets/External/Free Stylized Hand-Painted Skybox/Textures/Day_Clear.png b/Assets/External/Free Stylized Hand-Painted Skybox/Textures/Day_Clear.png
new file mode 100644
index 000000000..bb7e214d9
--- /dev/null
+++ b/Assets/External/Free Stylized Hand-Painted Skybox/Textures/Day_Clear.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:ac4462862f4523729338b04b3f4d5caa8f0de5d8b3db1de0c4e5d809417cb4aa
+size 144424
diff --git a/Assets/External/Free Stylized Hand-Painted Skybox/Textures/Day_Clear.png.meta b/Assets/External/Free Stylized Hand-Painted Skybox/Textures/Day_Clear.png.meta
new file mode 100644
index 000000000..e27b67921
--- /dev/null
+++ b/Assets/External/Free Stylized Hand-Painted Skybox/Textures/Day_Clear.png.meta
@@ -0,0 +1,129 @@
+fileFormatVersion: 2
+guid: 4c6e3caff9a2c00459a8805bc96f8f69
+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
+ vTOnly: 0
+ ignoreMasterTextureLimit: 0
+ grayScaleToAlpha: 0
+ generateCubemap: 2
+ cubemapConvolution: 0
+ seamlessCubemap: 1
+ textureFormat: 1
+ maxTextureSize: 2048
+ textureSettings:
+ serializedVersion: 2
+ filterMode: 1
+ aniso: 1
+ mipBias: 0
+ wrapU: 1
+ wrapV: 1
+ wrapW: 1
+ 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: 2
+ singleChannelComponent: 0
+ flipbookRows: 1
+ flipbookColumns: 1
+ maxTextureSizeSet: 0
+ compressionQualitySet: 0
+ textureFormatSet: 0
+ ignorePngGamma: 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
+ - 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
+ pSDShowRemoveMatteOption: 0
+ userData:
+ assetBundleName:
+ assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 265475
+ packageName: Free Stylized Hand-Painted Skybox
+ packageVersion: 1.0
+ assetPath: Assets/Free Stylized Hand-Painted Skybox/Textures/Day_Clear.png
+ uploadId: 627812
diff --git a/Assets/External/Free Stylized Hand-Painted Skybox/Textures/Midnight.png b/Assets/External/Free Stylized Hand-Painted Skybox/Textures/Midnight.png
new file mode 100644
index 000000000..0534ea9b1
--- /dev/null
+++ b/Assets/External/Free Stylized Hand-Painted Skybox/Textures/Midnight.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:022e02a4e7855075297b274bf918a17b54f7cf7343132a6907b624784e479209
+size 4233467
diff --git a/Assets/External/Free Stylized Hand-Painted Skybox/Textures/Midnight.png.meta b/Assets/External/Free Stylized Hand-Painted Skybox/Textures/Midnight.png.meta
new file mode 100644
index 000000000..931551e1e
--- /dev/null
+++ b/Assets/External/Free Stylized Hand-Painted Skybox/Textures/Midnight.png.meta
@@ -0,0 +1,129 @@
+fileFormatVersion: 2
+guid: ba4f9681a4f907647a229035e27b138a
+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
+ vTOnly: 0
+ ignoreMasterTextureLimit: 0
+ grayScaleToAlpha: 0
+ generateCubemap: 2
+ cubemapConvolution: 0
+ seamlessCubemap: 1
+ textureFormat: 1
+ maxTextureSize: 2048
+ textureSettings:
+ serializedVersion: 2
+ filterMode: 1
+ aniso: 1
+ mipBias: 0
+ wrapU: 1
+ wrapV: 1
+ wrapW: 1
+ 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: 2
+ singleChannelComponent: 0
+ flipbookRows: 1
+ flipbookColumns: 1
+ maxTextureSizeSet: 0
+ compressionQualitySet: 0
+ textureFormatSet: 0
+ ignorePngGamma: 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
+ - 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
+ pSDShowRemoveMatteOption: 0
+ userData:
+ assetBundleName:
+ assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 265475
+ packageName: Free Stylized Hand-Painted Skybox
+ packageVersion: 1.0
+ assetPath: Assets/Free Stylized Hand-Painted Skybox/Textures/Midnight.png
+ uploadId: 627812
diff --git a/Assets/External/Free Stylized Hand-Painted Skybox/Textures/Midnight_Stars.png b/Assets/External/Free Stylized Hand-Painted Skybox/Textures/Midnight_Stars.png
new file mode 100644
index 000000000..ecd972b2e
--- /dev/null
+++ b/Assets/External/Free Stylized Hand-Painted Skybox/Textures/Midnight_Stars.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:5374d5aa16dd138309e88403cc89325a716fee9d03c9ab65212ee46f9a4ecae8
+size 4150157
diff --git a/Assets/External/Free Stylized Hand-Painted Skybox/Textures/Midnight_Stars.png.meta b/Assets/External/Free Stylized Hand-Painted Skybox/Textures/Midnight_Stars.png.meta
new file mode 100644
index 000000000..4c2d394b7
--- /dev/null
+++ b/Assets/External/Free Stylized Hand-Painted Skybox/Textures/Midnight_Stars.png.meta
@@ -0,0 +1,129 @@
+fileFormatVersion: 2
+guid: 3b61a4965ad81044d8fd04c6738c08bb
+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
+ vTOnly: 0
+ ignoreMasterTextureLimit: 0
+ grayScaleToAlpha: 0
+ generateCubemap: 2
+ cubemapConvolution: 0
+ seamlessCubemap: 1
+ textureFormat: 1
+ maxTextureSize: 2048
+ textureSettings:
+ serializedVersion: 2
+ filterMode: 1
+ aniso: 1
+ mipBias: 0
+ wrapU: 1
+ wrapV: 1
+ wrapW: 1
+ 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: 2
+ singleChannelComponent: 0
+ flipbookRows: 1
+ flipbookColumns: 1
+ maxTextureSizeSet: 0
+ compressionQualitySet: 0
+ textureFormatSet: 0
+ ignorePngGamma: 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
+ - 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
+ pSDShowRemoveMatteOption: 0
+ userData:
+ assetBundleName:
+ assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 265475
+ packageName: Free Stylized Hand-Painted Skybox
+ packageVersion: 1.0
+ assetPath: Assets/Free Stylized Hand-Painted Skybox/Textures/Midnight_Stars.png
+ uploadId: 627812
diff --git a/Assets/External/Free Stylized Hand-Painted Skybox/Textures/Midnight_Stars02.png b/Assets/External/Free Stylized Hand-Painted Skybox/Textures/Midnight_Stars02.png
new file mode 100644
index 000000000..018f27fac
--- /dev/null
+++ b/Assets/External/Free Stylized Hand-Painted Skybox/Textures/Midnight_Stars02.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:bce3b980ac2cf9045af951abe5c3d7ae013bee284bf57cd1deefd3e9268df361
+size 269933
diff --git a/Assets/External/Free Stylized Hand-Painted Skybox/Textures/Midnight_Stars02.png.meta b/Assets/External/Free Stylized Hand-Painted Skybox/Textures/Midnight_Stars02.png.meta
new file mode 100644
index 000000000..e64b45ecf
--- /dev/null
+++ b/Assets/External/Free Stylized Hand-Painted Skybox/Textures/Midnight_Stars02.png.meta
@@ -0,0 +1,129 @@
+fileFormatVersion: 2
+guid: e29caa9aad3602d40be0bdfa8138d34e
+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
+ vTOnly: 0
+ ignoreMasterTextureLimit: 0
+ grayScaleToAlpha: 0
+ generateCubemap: 2
+ cubemapConvolution: 0
+ seamlessCubemap: 1
+ textureFormat: 1
+ maxTextureSize: 2048
+ textureSettings:
+ serializedVersion: 2
+ filterMode: 1
+ aniso: 1
+ mipBias: 0
+ wrapU: 1
+ wrapV: 1
+ wrapW: 1
+ 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: 2
+ singleChannelComponent: 0
+ flipbookRows: 1
+ flipbookColumns: 1
+ maxTextureSizeSet: 0
+ compressionQualitySet: 0
+ textureFormatSet: 0
+ ignorePngGamma: 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
+ - 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
+ pSDShowRemoveMatteOption: 0
+ userData:
+ assetBundleName:
+ assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 265475
+ packageName: Free Stylized Hand-Painted Skybox
+ packageVersion: 1.0
+ assetPath: Assets/Free Stylized Hand-Painted Skybox/Textures/Midnight_Stars02.png
+ uploadId: 627812
diff --git a/Assets/External/Free Stylized Hand-Painted Skybox/Textures/Sunset.png b/Assets/External/Free Stylized Hand-Painted Skybox/Textures/Sunset.png
new file mode 100644
index 000000000..028b8a2b9
--- /dev/null
+++ b/Assets/External/Free Stylized Hand-Painted Skybox/Textures/Sunset.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:3d58c36be1de7b92a3f84573c0a0588c3617db6428d98058b3a93084cab05840
+size 143773
diff --git a/Assets/External/Free Stylized Hand-Painted Skybox/Textures/Sunset.png.meta b/Assets/External/Free Stylized Hand-Painted Skybox/Textures/Sunset.png.meta
new file mode 100644
index 000000000..4cd156d3b
--- /dev/null
+++ b/Assets/External/Free Stylized Hand-Painted Skybox/Textures/Sunset.png.meta
@@ -0,0 +1,129 @@
+fileFormatVersion: 2
+guid: 8a923fadf769f794a8d3a9806f92c8c9
+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
+ vTOnly: 0
+ ignoreMasterTextureLimit: 0
+ grayScaleToAlpha: 0
+ generateCubemap: 2
+ cubemapConvolution: 0
+ seamlessCubemap: 1
+ textureFormat: 1
+ maxTextureSize: 2048
+ textureSettings:
+ serializedVersion: 2
+ filterMode: 1
+ aniso: 1
+ mipBias: 0
+ wrapU: 1
+ wrapV: 1
+ wrapW: 1
+ 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: 2
+ singleChannelComponent: 0
+ flipbookRows: 1
+ flipbookColumns: 1
+ maxTextureSizeSet: 0
+ compressionQualitySet: 0
+ textureFormatSet: 0
+ ignorePngGamma: 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
+ - 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
+ pSDShowRemoveMatteOption: 0
+ userData:
+ assetBundleName:
+ assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 265475
+ packageName: Free Stylized Hand-Painted Skybox
+ packageVersion: 1.0
+ assetPath: Assets/Free Stylized Hand-Painted Skybox/Textures/Sunset.png
+ uploadId: 627812
diff --git a/Assets/External/Free Stylized Hand-Painted Skybox/Textures/Sunset_Cloudy.png b/Assets/External/Free Stylized Hand-Painted Skybox/Textures/Sunset_Cloudy.png
new file mode 100644
index 000000000..17d0a67f6
--- /dev/null
+++ b/Assets/External/Free Stylized Hand-Painted Skybox/Textures/Sunset_Cloudy.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:0f97d7645dbcedb34ba723a9cbf46571d401a6d0a794f6d84479d20dfe439907
+size 7191227
diff --git a/Assets/External/Free Stylized Hand-Painted Skybox/Textures/Sunset_Cloudy.png.meta b/Assets/External/Free Stylized Hand-Painted Skybox/Textures/Sunset_Cloudy.png.meta
new file mode 100644
index 000000000..002be6fa7
--- /dev/null
+++ b/Assets/External/Free Stylized Hand-Painted Skybox/Textures/Sunset_Cloudy.png.meta
@@ -0,0 +1,129 @@
+fileFormatVersion: 2
+guid: 7e3608d3009d2f74c8fc155c9ad6d76e
+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
+ vTOnly: 0
+ ignoreMasterTextureLimit: 0
+ grayScaleToAlpha: 0
+ generateCubemap: 2
+ cubemapConvolution: 0
+ seamlessCubemap: 1
+ textureFormat: 1
+ maxTextureSize: 2048
+ textureSettings:
+ serializedVersion: 2
+ filterMode: 1
+ aniso: 1
+ mipBias: 0
+ wrapU: 1
+ wrapV: 1
+ wrapW: 1
+ 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: 2
+ singleChannelComponent: 0
+ flipbookRows: 1
+ flipbookColumns: 1
+ maxTextureSizeSet: 0
+ compressionQualitySet: 0
+ textureFormatSet: 0
+ ignorePngGamma: 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
+ - 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
+ pSDShowRemoveMatteOption: 0
+ userData:
+ assetBundleName:
+ assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 265475
+ packageName: Free Stylized Hand-Painted Skybox
+ packageVersion: 1.0
+ assetPath: Assets/Free Stylized Hand-Painted Skybox/Textures/Sunset_Cloudy.png
+ uploadId: 627812
diff --git a/Assets/Scenes/123.unity b/Assets/Scenes/123.unity
new file mode 100644
index 000000000..728b16e84
--- /dev/null
+++ b/Assets/Scenes/123.unity
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:05c0e49ed4e938ba8a2aa6f96754e37d3e736c5a0ad2991bf3c06bbfd7c4bfd2
+size 1853430
diff --git a/Assets/Scenes/123.unity.meta b/Assets/Scenes/123.unity.meta
new file mode 100644
index 000000000..dd6bcae7c
--- /dev/null
+++ b/Assets/Scenes/123.unity.meta
@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: d3384ad04ecf0e049990c1f233d1e2ea
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scenes/SampleScene.unity b/Assets/Scenes/SampleScene.unity
new file mode 100644
index 000000000..e3adddbbf
--- /dev/null
+++ b/Assets/Scenes/SampleScene.unity
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:b486fd6efc63d16941e828208257f27310635d5a0823bad13780ffed3b6b0233
+size 15750
diff --git a/Assets/Scenes/SampleScene.unity.meta b/Assets/Scenes/SampleScene.unity.meta
new file mode 100644
index 000000000..9531828bc
--- /dev/null
+++ b/Assets/Scenes/SampleScene.unity.meta
@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: 99c9720ab356a0642a771bea13969a05
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/3rd.meta b/Assets/Scripts/3rd.meta
new file mode 100644
index 000000000..a8668ee90
--- /dev/null
+++ b/Assets/Scripts/3rd.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: b48153ffb94284f07b4402360a8d6294
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master.meta b/Assets/Scripts/3rd/mmd-for-unity-master.meta
new file mode 100644
index 000000000..467799b98
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: ca2e40c29b72148aca866896cf8e5b3e
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/Local.testsettings b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/Local.testsettings
new file mode 100644
index 000000000..5ed2113bd
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/Local.testsettings
@@ -0,0 +1,10 @@
+
+
+ これらはローカル テスト実行用の既定のテスト設定です。
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBaker.vsmdi b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBaker.vsmdi
new file mode 100644
index 000000000..1065f7d2a
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBaker.vsmdi
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBaker/IK_Test.vmd b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBaker/IK_Test.vmd
new file mode 100644
index 000000000..799a3771b
Binary files /dev/null and b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBaker/IK_Test.vmd differ
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBaker/Program.cs b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBaker/Program.cs
new file mode 100644
index 000000000..d4036a239
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBaker/Program.cs
@@ -0,0 +1,26 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using MikuMikuDance.Model.Ver1;
+using MikuMikuDance.Model;
+using MikuMikuDance.Motion.Motion2;
+using MikuMikuDance.Motion;
+using MMDIKBakerLibrary;
+
+namespace MMDIKBaker
+{
+ class Program
+ {
+ static void Main(string[] args)
+ {
+ //コンソールアプリ作りたいわけじゃないのでハードコーディングしとく
+ string InputPMD = "miku.pmd";
+ string InputVMD = "TrueMyHeart.vmd";
+ string OutputVMD = "tmh_bake.vmd";
+ MMDModel1 model = (MMDModel1)ModelManager.Read(InputPMD, MikuMikuDance.Model.CoordinateType.RightHandedCoordinate);
+ MMDMotion2 motion = (MMDMotion2)MotionManager.Read(InputVMD, MikuMikuDance.Motion.CoordinateType.RightHandedCoordinate);
+ motion = IKBaker.bake(motion, model);
+ MotionManager.Write(OutputVMD, motion);
+ }
+ }
+}
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBaker/Properties/AssemblyInfo.cs b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBaker/Properties/AssemblyInfo.cs
new file mode 100644
index 000000000..76e12d480
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBaker/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// アセンブリに関する一般情報は以下の属性セットをとおして制御されます。
+// アセンブリに関連付けられている情報を変更するには、
+// これらの属性値を変更してください。
+[assembly: AssemblyTitle("MMDBoneBaker")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("MMDBoneBaker")]
+[assembly: AssemblyCopyright("Copyright © 2011")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// ComVisible を false に設定すると、その型はこのアセンブリ内で COM コンポーネントから
+// 参照不可能になります。COM からこのアセンブリ内の型にアクセスする場合は、
+// その型の ComVisible 属性を true に設定してください。
+[assembly: ComVisible(false)]
+
+// 次の GUID は、このプロジェクトが COM に公開される場合の、typelib の ID です
+[assembly: Guid("49201036-3934-4006-b21b-04eb8fb6aeee")]
+
+// アセンブリのバージョン情報は、以下の 4 つの値で構成されています:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// すべての値を指定するか、下のように '*' を使ってビルドおよびリビジョン番号を
+// 既定値にすることができます:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBaker/TrueMyHeart.vmd b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBaker/TrueMyHeart.vmd
new file mode 100644
index 000000000..e47380233
Binary files /dev/null and b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBaker/TrueMyHeart.vmd differ
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBaker/miku.pmd b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBaker/miku.pmd
new file mode 100644
index 000000000..21ef5e48d
Binary files /dev/null and b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBaker/miku.pmd differ
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerGUI/Form1.Designer.cs b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerGUI/Form1.Designer.cs
new file mode 100644
index 000000000..451251e8d
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerGUI/Form1.Designer.cs
@@ -0,0 +1,166 @@
+namespace MMDIKBakerGUI
+{
+ partial class Form1
+ {
+ ///
+ /// 必要なデザイナー変数です。
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// 使用中のリソースをすべてクリーンアップします。
+ ///
+ /// マネージ リソースが破棄される場合 true、破棄されない場合は false です。
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows フォーム デザイナーで生成されたコード
+
+ ///
+ /// デザイナー サポートに必要なメソッドです。このメソッドの内容を
+ /// コード エディターで変更しないでください。
+ ///
+ private void InitializeComponent()
+ {
+ this.pmdFileName = new System.Windows.Forms.TextBox();
+ this.vmdFileName = new System.Windows.Forms.TextBox();
+ this.label1 = new System.Windows.Forms.Label();
+ this.label2 = new System.Windows.Forms.Label();
+ this.pmdRef = new System.Windows.Forms.Button();
+ this.vmdRef = new System.Windows.Forms.Button();
+ this.startBake = new System.Windows.Forms.Button();
+ this.button1 = new System.Windows.Forms.Button();
+ this.label3 = new System.Windows.Forms.Label();
+ this.saveVmdName = new System.Windows.Forms.TextBox();
+ this.SuspendLayout();
+ //
+ // pmdFileName
+ //
+ this.pmdFileName.Location = new System.Drawing.Point(14, 24);
+ this.pmdFileName.Name = "pmdFileName";
+ this.pmdFileName.Size = new System.Drawing.Size(270, 19);
+ this.pmdFileName.TabIndex = 0;
+ //
+ // vmdFileName
+ //
+ this.vmdFileName.Location = new System.Drawing.Point(14, 61);
+ this.vmdFileName.Name = "vmdFileName";
+ this.vmdFileName.Size = new System.Drawing.Size(270, 19);
+ this.vmdFileName.TabIndex = 1;
+ //
+ // label1
+ //
+ this.label1.AutoSize = true;
+ this.label1.Location = new System.Drawing.Point(12, 9);
+ this.label1.Name = "label1";
+ this.label1.Size = new System.Drawing.Size(29, 12);
+ this.label1.TabIndex = 2;
+ this.label1.Text = "PMD";
+ //
+ // label2
+ //
+ this.label2.AutoSize = true;
+ this.label2.Location = new System.Drawing.Point(12, 46);
+ this.label2.Name = "label2";
+ this.label2.Size = new System.Drawing.Size(30, 12);
+ this.label2.TabIndex = 3;
+ this.label2.Text = "VMD";
+ //
+ // pmdRef
+ //
+ this.pmdRef.Location = new System.Drawing.Point(290, 22);
+ this.pmdRef.Name = "pmdRef";
+ this.pmdRef.Size = new System.Drawing.Size(42, 23);
+ this.pmdRef.TabIndex = 4;
+ this.pmdRef.Text = "参照";
+ this.pmdRef.UseVisualStyleBackColor = true;
+ this.pmdRef.Click += new System.EventHandler(this.pmdRef_Click);
+ //
+ // vmdRef
+ //
+ this.vmdRef.Location = new System.Drawing.Point(290, 59);
+ this.vmdRef.Name = "vmdRef";
+ this.vmdRef.Size = new System.Drawing.Size(42, 23);
+ this.vmdRef.TabIndex = 5;
+ this.vmdRef.Text = "参照";
+ this.vmdRef.UseVisualStyleBackColor = true;
+ this.vmdRef.Click += new System.EventHandler(this.vmdRef_Click);
+ //
+ // startBake
+ //
+ this.startBake.Location = new System.Drawing.Point(257, 142);
+ this.startBake.Name = "startBake";
+ this.startBake.Size = new System.Drawing.Size(75, 23);
+ this.startBake.TabIndex = 6;
+ this.startBake.Text = "Bake !!";
+ this.startBake.UseVisualStyleBackColor = true;
+ this.startBake.Click += new System.EventHandler(this.startBake_Click);
+ //
+ // button1
+ //
+ this.button1.Location = new System.Drawing.Point(290, 96);
+ this.button1.Name = "button1";
+ this.button1.Size = new System.Drawing.Size(42, 23);
+ this.button1.TabIndex = 9;
+ this.button1.Text = "参照";
+ this.button1.UseVisualStyleBackColor = true;
+ //
+ // label3
+ //
+ this.label3.AutoSize = true;
+ this.label3.Location = new System.Drawing.Point(12, 83);
+ this.label3.Name = "label3";
+ this.label3.Size = new System.Drawing.Size(59, 12);
+ this.label3.TabIndex = 8;
+ this.label3.Text = "Save VMD";
+ //
+ // saveVmdName
+ //
+ this.saveVmdName.Location = new System.Drawing.Point(14, 98);
+ this.saveVmdName.Name = "saveVmdName";
+ this.saveVmdName.Size = new System.Drawing.Size(270, 19);
+ this.saveVmdName.TabIndex = 7;
+ //
+ // Form1
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.ClientSize = new System.Drawing.Size(344, 177);
+ this.Controls.Add(this.button1);
+ this.Controls.Add(this.label3);
+ this.Controls.Add(this.saveVmdName);
+ this.Controls.Add(this.startBake);
+ this.Controls.Add(this.vmdRef);
+ this.Controls.Add(this.pmdRef);
+ this.Controls.Add(this.label2);
+ this.Controls.Add(this.label1);
+ this.Controls.Add(this.vmdFileName);
+ this.Controls.Add(this.pmdFileName);
+ this.Name = "Form1";
+ this.Text = "MMDIKBakerGUI";
+ this.ResumeLayout(false);
+ this.PerformLayout();
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.TextBox pmdFileName;
+ private System.Windows.Forms.TextBox vmdFileName;
+ private System.Windows.Forms.Label label1;
+ private System.Windows.Forms.Label label2;
+ private System.Windows.Forms.Button pmdRef;
+ private System.Windows.Forms.Button vmdRef;
+ private System.Windows.Forms.Button startBake;
+ private System.Windows.Forms.Button button1;
+ private System.Windows.Forms.Label label3;
+ private System.Windows.Forms.TextBox saveVmdName;
+ }
+}
+
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerGUI/Form1.cs b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerGUI/Form1.cs
new file mode 100644
index 000000000..37dae1444
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerGUI/Form1.cs
@@ -0,0 +1,120 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Linq;
+using System.Text;
+using System.Windows.Forms;
+using System.IO;
+using MikuMikuDance.Model;
+using MikuMikuDance.Model.Ver1;
+using MikuMikuDance.Motion;
+using MikuMikuDance.Motion.Motion2;
+using MMDIKBakerLibrary;
+
+namespace MMDIKBakerGUI
+{
+ public partial class Form1 : Form
+ {
+ public Form1()
+ {
+ InitializeComponent();
+ }
+
+ private void startBake_Click(object sender, EventArgs e)
+ {
+ // 入力チェック
+ if (!File.Exists(pmdFileName.Text))
+ {
+ MessageBox.Show(
+ "PMDファイルが見つかりません!:\n" + pmdFileName.Text,
+ "PMD読み込みエラー",
+ MessageBoxButtons.OK,
+ MessageBoxIcon.Error);
+ return;
+ }
+
+ if (!File.Exists(vmdFileName.Text))
+ {
+ MessageBox.Show(
+ "VMDファイルが見つかりません!:\n" + vmdFileName.Text,
+ "VMD読み込みエラー",
+ MessageBoxButtons.OK,
+ MessageBoxIcon.Error);
+ return;
+ }
+
+ // saveVMDの上書き確認
+ if (File.Exists(saveVmdName.Text))
+ {
+ var result = MessageBox.Show(
+ "VMDファイルが存在します。\n" + saveVmdName.Text + "\n上書きしてよろしいですか?",
+ "上書き確認",
+ MessageBoxButtons.YesNoCancel,
+ MessageBoxIcon.Question);
+
+ if(result != System.Windows.Forms.DialogResult.Yes)
+ return;
+
+ // bakeでエラー出るっぽいので削除しておく
+ File.Delete(saveVmdName.Text);
+ }
+
+ // Bake!
+ try
+ {
+ MMDModel1 model = (MMDModel1)ModelManager.Read(pmdFileName.Text, MikuMikuDance.Model.CoordinateType.RightHandedCoordinate);
+ MMDMotion2 motion = (MMDMotion2)MotionManager.Read(vmdFileName.Text, MikuMikuDance.Motion.CoordinateType.RightHandedCoordinate);
+ motion = IKBaker.bake(motion, model);
+ MotionManager.Write(saveVmdName.Text, motion);
+
+ MessageBox.Show(
+ "Bake完了",
+ "Baked!!");
+ }
+ catch
+ {
+ MessageBox.Show(
+ "Bake中にエラーが発生しました",
+ "未知のエラー",
+ MessageBoxButtons.OK,
+ MessageBoxIcon.Error);
+ return;
+ }
+ }
+
+ private void pmdRef_Click(object sender, EventArgs e)
+ {
+ var dialog = new OpenFileDialog();
+ dialog.Filter = "PMDファイル|*.pmd";
+ if (dialog.ShowDialog() == DialogResult.OK)
+ {
+ pmdFileName.Text = dialog.FileName;
+ }
+ }
+
+ private void vmdRef_Click(object sender, EventArgs e)
+ {
+ var dialog = new OpenFileDialog();
+ dialog.Filter = "VMDファイル|*.vmd";
+ if (dialog.ShowDialog() == DialogResult.OK)
+ {
+ vmdFileName.Text = dialog.FileName;
+
+ var f = new FileInfo(vmdFileName.Text);
+ saveVmdName.Text = Path.Combine(f.DirectoryName, f.Name.Replace(f.Extension, "_baked") + f.Extension);
+ }
+ }
+
+ private void saveRef_Click(object sender, EventArgs e)
+ {
+ var dialog = new SaveFileDialog();
+ dialog.Filter = "VMDファイル|*.vmd";
+ if (dialog.ShowDialog() == DialogResult.OK)
+ {
+ saveVmdName.Text = dialog.FileName;
+ }
+ }
+ }
+}
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerGUI/Form1.resx b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerGUI/Form1.resx
new file mode 100644
index 000000000..1af7de150
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerGUI/Form1.resx
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerGUI/Program.cs b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerGUI/Program.cs
new file mode 100644
index 000000000..bd2f23d65
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerGUI/Program.cs
@@ -0,0 +1,21 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Windows.Forms;
+
+namespace MMDIKBakerGUI
+{
+ static class Program
+ {
+ ///
+ /// アプリケーションのメイン エントリ ポイントです。
+ ///
+ [STAThread]
+ static void Main()
+ {
+ Application.EnableVisualStyles();
+ Application.SetCompatibleTextRenderingDefault(false);
+ Application.Run(new Form1());
+ }
+ }
+}
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerGUI/Properties/AssemblyInfo.cs b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerGUI/Properties/AssemblyInfo.cs
new file mode 100644
index 000000000..6fb8ab57e
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerGUI/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// アセンブリに関する一般情報は以下の属性セットをとおして制御されます。
+// アセンブリに関連付けられている情報を変更するには、
+// これらの属性値を変更してください。
+[assembly: AssemblyTitle("MMDIKBakerGUI")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("MMDIKBakerGUI")]
+[assembly: AssemblyCopyright("Copyright © 2012")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// ComVisible を false に設定すると、その型はこのアセンブリ内で COM コンポーネントから
+// 参照不可能になります。COM からこのアセンブリ内の型にアクセスする場合は、
+// その型の ComVisible 属性を true に設定してください。
+[assembly: ComVisible(false)]
+
+// 次の GUID は、このプロジェクトが COM に公開される場合の、typelib の ID です
+[assembly: Guid("0339f748-b7cb-4486-bae7-b330d0ac3512")]
+
+// アセンブリのバージョン情報は、以下の 4 つの値で構成されています:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// すべての値を指定するか、下のように '*' を使ってビルドおよびリビジョン番号を
+// 既定値にすることができます:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerGUI/Properties/Resources.Designer.cs b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerGUI/Properties/Resources.Designer.cs
new file mode 100644
index 000000000..e9c28be0d
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerGUI/Properties/Resources.Designer.cs
@@ -0,0 +1,71 @@
+//------------------------------------------------------------------------------
+//
+// このコードはツールによって生成されました。
+// ランタイム バージョン:4.0.30319.269
+//
+// このファイルへの変更は、以下の状況下で不正な動作の原因になったり、
+// コードが再生成されるときに損失したりします
+//
+//------------------------------------------------------------------------------
+
+namespace MMDIKBakerGUI.Properties
+{
+
+
+ ///
+ /// ローカライズされた文字列などを検索するための、厳密に型指定されたリソース クラスです。
+ ///
+ // このクラスは StronglyTypedResourceBuilder クラスが ResGen
+ // または Visual Studio のようなツールを使用して自動生成されました。
+ // メンバーを追加または削除するには、.ResX ファイルを編集して、/str オプションと共に
+ // ResGen を実行し直すか、または VS プロジェクトをビルドし直します。
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ internal class Resources
+ {
+
+ private static global::System.Resources.ResourceManager resourceMan;
+
+ private static global::System.Globalization.CultureInfo resourceCulture;
+
+ [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+ internal Resources()
+ {
+ }
+
+ ///
+ /// このクラスに使用される、キャッシュされた ResourceManager のインスタンスを返します。
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Resources.ResourceManager ResourceManager
+ {
+ get
+ {
+ if ((resourceMan == null))
+ {
+ global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("MMDIKBakerGUI.Properties.Resources", typeof(Resources).Assembly);
+ resourceMan = temp;
+ }
+ return resourceMan;
+ }
+ }
+
+ ///
+ /// 厳密に型指定されたこのリソース クラスを使用して、すべての検索リソースに対し、
+ /// 現在のスレッドの CurrentUICulture プロパティをオーバーライドします。
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Globalization.CultureInfo Culture
+ {
+ get
+ {
+ return resourceCulture;
+ }
+ set
+ {
+ resourceCulture = value;
+ }
+ }
+ }
+}
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerGUI/Properties/Resources.resx b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerGUI/Properties/Resources.resx
new file mode 100644
index 000000000..af7dbebba
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerGUI/Properties/Resources.resx
@@ -0,0 +1,117 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerGUI/Properties/Settings.Designer.cs b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerGUI/Properties/Settings.Designer.cs
new file mode 100644
index 000000000..4d1f1c874
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerGUI/Properties/Settings.Designer.cs
@@ -0,0 +1,30 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by a tool.
+// Runtime Version:4.0.30319.269
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+namespace MMDIKBakerGUI.Properties
+{
+
+
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")]
+ internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
+ {
+
+ private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
+
+ public static Settings Default
+ {
+ get
+ {
+ return defaultInstance;
+ }
+ }
+ }
+}
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerGUI/Properties/Settings.settings b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerGUI/Properties/Settings.settings
new file mode 100644
index 000000000..39645652a
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerGUI/Properties/Settings.settings
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerGUI/bin/Debug/MMDBoneBakerLibrary.dll b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerGUI/bin/Debug/MMDBoneBakerLibrary.dll
new file mode 100644
index 000000000..3ee67f5cb
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerGUI/bin/Debug/MMDBoneBakerLibrary.dll
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:9baae5d3530cedf887aba16481d6a6dae8a9efc7551c325842f3cad364262271
+size 42496
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerGUI/bin/Debug/MMDIKBakerGUI.exe b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerGUI/bin/Debug/MMDIKBakerGUI.exe
new file mode 100644
index 000000000..2a1967ad4
Binary files /dev/null and b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerGUI/bin/Debug/MMDIKBakerGUI.exe differ
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerGUI/bin/Debug/MMDIKBakerGUI.vshost.exe b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerGUI/bin/Debug/MMDIKBakerGUI.vshost.exe
new file mode 100644
index 000000000..bb84a51ac
Binary files /dev/null and b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerGUI/bin/Debug/MMDIKBakerGUI.vshost.exe differ
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerGUI/bin/Debug/MMDModelLibrary.dll b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerGUI/bin/Debug/MMDModelLibrary.dll
new file mode 100644
index 000000000..32d8ed3eb
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerGUI/bin/Debug/MMDModelLibrary.dll
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:0910d326678e5da866e1498f4d8a1afe6f6ee22b96025e2fb7ebb29c7d71e836
+size 33792
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerGUI/bin/Debug/MMDMotionLibrary.dll b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerGUI/bin/Debug/MMDMotionLibrary.dll
new file mode 100644
index 000000000..f6e803fd8
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerGUI/bin/Debug/MMDMotionLibrary.dll
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:4cff3b36ebbdd067fc8aeb3acc71c8941dc77a45939d1a45dec538fda329e48d
+size 13824
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerLibrary/IKBaker.cs b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerLibrary/IKBaker.cs
new file mode 100644
index 000000000..5ccb15bc1
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerLibrary/IKBaker.cs
@@ -0,0 +1,62 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using MMDIKBakerLibrary.Model;
+using MMDIKBakerLibrary.Motion;
+using MMDMotion2 = MikuMikuDance.Motion.Motion2.MMDMotion2;
+using MMDModel1 = MikuMikuDance.Model.Ver1.MMDModel1;
+namespace MMDIKBakerLibrary
+{
+ public class IKBaker
+ {
+ public static MMDMotion2 bake(MMDMotion2 motion, MMDModel1 model)
+ {
+ //ボーン取得
+ MMDBoneManager boneManager = ModelConverter.BuildBoneManager(model);
+ //ベイク前のモーションとベイク後のモーションを準備
+ MMDMotion beforeMotion = MotionConverter.Convert(motion);
+ MMDMotion afterMotion = CreateAfterMotionPrototype(beforeMotion, boneManager);
+ //アニメーションプレイヤーを作成
+ AnimationPlayer player = new AnimationPlayer(boneManager);
+ player.SetMotion(beforeMotion);
+ //ベイクしていく
+ uint frameNo = 0;
+ bool ExitFlag = false;
+ while (!ExitFlag)
+ {
+ ExitFlag = !player.Update();
+ //ボーンのグローバル行列更新
+ boneManager.CalcGlobalTransform();
+ //IK更新
+ boneManager.CalcIK();
+ //ベイク
+ boneManager.bake(frameNo, afterMotion);
+ ++frameNo;
+ }
+ //元のMMDMotion2に直して返却
+ return MotionConverter.Convert(afterMotion, motion.ModelName);
+ }
+
+ private static MMDMotion CreateAfterMotionPrototype(MMDMotion beforeMotion, MMDBoneManager boneManager)
+ {
+ //ベイク対象外の情報をコピー
+ MMDMotion result = new MMDMotion();
+ //表情は参照をコピーしておく
+ result.FaceFrames = beforeMotion.FaceFrames;
+ //ボーンは必要分だけ参照をコピー
+ result.BoneFrames = new Dictionary>();
+ foreach (KeyValuePair> boneSet in beforeMotion.BoneFrames)
+ {
+ if (!boneManager.IsUnderIK(boneSet.Key))
+ {
+ result.BoneFrames.Add(boneSet.Key, boneSet.Value);
+ }
+ else
+ {
+ result.BoneFrames.Add(boneSet.Key, new List());
+ }
+ }
+ return result;
+ }
+ }
+}
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerLibrary/Misc/BezireCurve.cs b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerLibrary/Misc/BezireCurve.cs
new file mode 100644
index 000000000..81f94c021
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerLibrary/Misc/BezireCurve.cs
@@ -0,0 +1,61 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace MMDIKBakerLibrary.Misc
+{
+ struct BezierCurve
+ {
+ internal const float Epsilon = 1.0e-3f;
+
+ ///
+ /// ベジェ曲線に用いる点1
+ ///
+ public Vector2 v1;
+ ///
+ /// ベジェ曲線に用いる点2
+ ///
+ public Vector2 v2;
+
+
+ ///
+ /// 進行度合から移行度合を取得
+ ///
+ /// 進行度合
+ /// 移行度合
+ public float Evaluate(float Progress)
+ {
+ //ニュートン法による近似
+ float t = MathHelper.Clamp(Progress, 0f, 1f);
+ float dt;
+ do
+ {
+ dt = -(fx(t) - Progress) / dfx(t);
+
+ if (float.IsNaN(dt))
+ break;
+ t += MathHelper.Clamp(dt, -1f, 1f);//大幅に移動して別の解に到達するのを防止する用
+ } while (Math.Abs(dt) > Epsilon);
+ return MathHelper.Clamp(fy(t), 0f, 1f);//念のため、0-1の間に収まるようにした
+ }
+ //fy(t)を計算する関数
+ private float fy(float t)
+ {
+ //fy(t)=(1-t)^3*0+3*(1-t)^2*t*v1.y+3*(1-t)*t^2*v2.y+t^3*1
+ return 3 * (1 - t) * (1 - t) * t * v1.Y + 3 * (1 - t) * t * t * v2.Y + t * t * t;
+ }
+ //fx(t)を計算する関数
+ float fx(float t)
+ {
+ //fx(t)=(1-t)^3*0+3*(1-t)^2*t*v1.x+3*(1-t)*t^2*v2.x+t^3*1
+ return 3 * (1 - t) * (1 - t) * t * v1.X + 3 * (1 - t) * t * t * v2.X + t * t * t;
+ }
+ //dfx/dtを計算する関数
+ float dfx(float t)
+ {
+ //dfx(t)/dt=-6(1-t)*t*v1.x+3(1-t)^2*v1.x-3t^2*v2.x+6(1-t)*t*v2.x+3t^2
+ return -6 * (1 - t) * t * v1.X + 3 * (1 - t) * (1 - t) * v1.X
+ - 3 * t * t * v2.X + 6 * (1 - t) * t * v2.X + 3 * t * t;
+ }
+ }
+}
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerLibrary/Misc/CCDSolver.cs b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerLibrary/Misc/CCDSolver.cs
new file mode 100644
index 000000000..372e4d7e9
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerLibrary/Misc/CCDSolver.cs
@@ -0,0 +1,123 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using MMDIKBakerLibrary.Model;
+
+namespace MMDIKBakerLibrary.Misc
+{
+ ///
+ /// CCD-IKソルバー
+ ///
+ /// Cyclic-Coordinate-Descent(CCD)法によるIK計算クラス
+ class CCDSolver : IIKSolver
+ {
+ const double errToleranceSq = 1.0e-8f;
+
+ ///
+ /// IKのソルブ
+ ///
+ /// 対象IK
+ /// ボーンマネージャ
+ /// 呼び出し側でUpdateGlobalをもう一度呼ぶ場合はtrue
+ public bool Solve(MMDIK ik, MMDBoneManager BoneManager)
+ {
+#if SlimDX
+ Vector4 localTargetPos = Vector4.Zero;
+ Vector4 localEffectorPos = Vector4.Zero;
+#else
+ Vector3 localTargetPos = Vector3.Zero;
+ Vector3 localEffectorPos = Vector3.Zero;
+#endif
+ //エフェクタとなるボーンを取得
+ MMDBone effector = ik.IKTargetBone;
+ //IK対象のボーンのGlobalを更新(別のIK影響下のボーンからIKチェインが出ている場合があるので)
+ Matrix local;
+ for (int i = ik.IKChildBones.Count - 1; i >= 0; --i)
+ {//順番に親子関係になっている。(Processorでチェックかけてある
+ //GlobalTransformを仮更新
+ int parentBone = ik.IKChildBones[i].SkeletonHierarchy;
+ ik.IKChildBones[i].LocalTransform.CreateMatrix(out local);
+ Matrix.Multiply(ref local, ref BoneManager[parentBone].GlobalTransform, out ik.IKChildBones[i].GlobalTransform);
+ }
+ effector.LocalTransform.CreateMatrix(out local);
+ Matrix.Multiply(ref local, ref BoneManager[effector.SkeletonHierarchy].GlobalTransform, out effector.GlobalTransform);
+
+ //ターゲット位置の取得
+ Vector3 targetPos;
+ Matrix.GetTranslation(ref ik.IKBone.GlobalTransform, out targetPos);
+
+ //最大ループ回数分ループ
+ for (int it = 0; it < ik.Iteration; ++it)
+ {
+ for (int nodeIndex = 0; nodeIndex < ik.IKChildBones.Count; ++nodeIndex)
+ {//子ノードを子から順番に……
+ MMDBone node = ik.IKChildBones[nodeIndex];
+ //エフェクタの位置
+ Vector3 effectorPos;
+ Matrix.GetTranslation(ref effector.GlobalTransform, out effectorPos);
+ // 注目ノードの位置の取得
+ Vector3 jointPos;
+ Matrix.GetTranslation(ref node.GlobalTransform, out jointPos);
+
+ // ワールド座標系から注目ノードの局所座標系への変換
+ Matrix invCoord;
+ Matrix.Invert(ref node.GlobalTransform, out invCoord);
+ // 各ベクトルの座標変換を行い、検索中のボーンi基準の座標系にする
+ // (1) 注目ノード→エフェクタ位置へのベクトル(a)(注目ノード)
+ Vector3.Transform(ref effectorPos, ref invCoord, out localEffectorPos);
+ // (2) 基準関節i→目標位置へのベクトル(b)(ボーンi基準座標系)
+ Vector3.Transform(ref targetPos, ref invCoord, out localTargetPos);
+#if SlimDX
+ //念のため……
+ // (1) 基準関節→エフェクタ位置への方向ベクトル
+ Vector3 basis2Effector = Vector3.Normalize(new Vector3(localEffectorPos.X, localEffectorPos.Y, localEffectorPos.Z));
+ // (2) 基準関節→目標位置への方向ベクトル
+ Vector3 basis2Target = Vector3.Normalize(new Vector3(localTargetPos.X, localTargetPos.Y, localTargetPos.Z));
+#else
+ // (1) 基準関節→エフェクタ位置への方向ベクトル
+ Vector3 basis2Effector = Vector3.Normalize(localEffectorPos);
+ // (2) 基準関節→目標位置への方向ベクトル
+ Vector3 basis2Target = Vector3.Normalize(localTargetPos);
+#endif
+
+ // 回転角
+ float rotationDotProduct = (float)Vector3.Dot(basis2Effector, basis2Target);
+ float rotationAngle = (float)Math.Acos(rotationDotProduct);
+
+ //回転量制限をかける
+ if (rotationAngle > MathHelper.Pi * ik.ControlWeight * (nodeIndex + 1))
+ rotationAngle = MathHelper.Pi * ik.ControlWeight * (nodeIndex + 1);
+ if (rotationAngle < -MathHelper.Pi * ik.ControlWeight * (nodeIndex + 1))
+ rotationAngle = -MathHelper.Pi * ik.ControlWeight * (nodeIndex + 1);
+
+ // 回転軸
+ Vector3 rotationAxis = Vector3.Cross(basis2Effector, basis2Target);
+ BoneManager.IKLimitter.Adjust(node.Name, ref rotationAxis);
+ rotationAxis.Normalize();
+
+ if (!float.IsNaN(rotationAngle) && rotationAngle > 1.0e-3f && !rotationAxis.NaN)
+ {
+ // 関節回転量の補正
+ Quaternion subRot = Quaternion.CreateFromAxisAngle(rotationAxis, (decimal)rotationAngle);
+ Quaternion.Multiply(ref subRot, ref node.LocalTransform.Rotation, out node.LocalTransform.Rotation);
+ BoneManager.IKLimitter.Adjust(node);
+ //関係ノードのグローバル座標更新
+ for (int i = nodeIndex; i >= 0; --i)
+ {//順番に親子関係になっている。(Processorでチェックかけてある
+ //GlobalTransformを仮更新
+ int parentBone = ik.IKChildBones[i].SkeletonHierarchy;
+ ik.IKChildBones[i].LocalTransform.CreateMatrix(out local);
+ Matrix.Multiply(ref local, ref BoneManager[parentBone].GlobalTransform, out ik.IKChildBones[i].GlobalTransform);
+ }
+ effector.LocalTransform.CreateMatrix(out local);
+ Matrix.Multiply(ref local, ref BoneManager[effector.SkeletonHierarchy].GlobalTransform, out effector.GlobalTransform);
+ }
+ }
+ }
+ return true;//UpdateGlobalをもう一度呼ぶ
+ //IKチェインにぶら下がってるIK影響外のボーンを更新するため。
+ }
+
+
+ }
+}
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerLibrary/Misc/DefaultIKLimitter.cs b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerLibrary/Misc/DefaultIKLimitter.cs
new file mode 100644
index 000000000..5c98530f1
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerLibrary/Misc/DefaultIKLimitter.cs
@@ -0,0 +1,273 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace MMDIKBakerLibrary.Misc
+{
+ ///
+ /// 回転制限クラス
+ ///
+ public class RotationLimit
+ {
+ ///
+ /// 最大回転
+ ///
+ /// X回転、Y回転、Z回転制限
+ public float[] MaxRot { get; protected set; }
+ ///
+ /// 最小回転
+ ///
+ /// X回転、Y回転、Z回転制限
+ public float[] MinRot { get; protected set; }
+ ///
+ /// 角度の反射調整機能使用フラグ
+ ///
+ /// IKのCCDソルブは足のIKが<が>になる感じの解を出してくるので、反射してやると上手くいくっぽい
+ public bool[] Mirror { get; private set; }
+ ///
+ /// 角度の反射調整の反発係数
+ ///
+ public float[] Restitution { get; private set; }
+ ///
+ /// 角速度の"粘性"係数。IKのソルブの過程で解が"飛ぶ"のを防ぐために設定
+ ///
+ public float[] Stickness { get; private set; }
+
+
+ ///
+ /// 既定のコンストラクタ
+ ///
+ public RotationLimit()
+ {
+ MaxRot = new float[3];
+ MinRot = new float[3];
+ Mirror = new bool[3];
+ Restitution = new float[3];
+ for (int i = 0; i < 3; i++)
+ {
+ MaxRot[i] = MathHelper.Pi;
+ MinRot[i] = -MathHelper.Pi;
+ Mirror[i] = false;
+ Restitution[i] = 0.5f;
+ }
+
+
+ }
+
+
+ ///
+ /// 指定した角度をアジャストする
+ ///
+ /// 回転角
+ /// 回転軸
+ /// アジャスト済み角度
+ public float Adjust(float value, int index)
+ {
+ if (MinRot[index] > MaxRot[index])
+ {//角度が逆なら入れ替えておく
+ float temp = MinRot[index];
+ MinRot[index] = MaxRot[index];
+ MaxRot[index] = temp;
+ }
+ if (MaxRot[index] < value)
+ {
+ if (Mirror[index])
+ return MaxRot[index] * (1 + Restitution[index]) - value * Restitution[index];
+ else
+ return MaxRot[index];
+ }
+ else if (MinRot[index] > value)
+ {
+ if (Mirror[index])
+ return MinRot[index] * (1 + Restitution[index]) - value * Restitution[index];
+ else
+ return MinRot[index];
+ }
+ else
+ return value;
+
+ }
+ }
+ ///
+ /// IK計算時の回転軸制限クラス
+ ///
+ class RotationAxisLimit
+ {
+ ///
+ /// 回転制限を行う軸(X,Y,Z)
+ ///
+ public bool[] Limits { get; private set; }
+ ///
+ /// 既定のコンストラクタ
+ ///
+ public RotationAxisLimit()
+ {
+ Limits = new bool[3] { false, false, false };
+ }
+ ///
+ /// 回転軸制限の適用
+ ///
+ ///
+ public void Adjust(ref Vector3 rotationAxis)
+ {
+ if (Limits[0])
+ {
+ rotationAxis.X = 0;
+ }
+ if (Limits[1])
+ {
+ rotationAxis.Y = 0;
+ }
+ if (Limits[2])
+ {
+ rotationAxis.Z = 0;
+ }
+ }
+ }
+ ///
+ /// 標準IKLimitter
+ ///
+ class DefaltIKLimitter : IIKLimitter
+ {
+ ///
+ /// 総合稼働軸制限一覧
+ ///
+ /// ボーン名マッチング用の正規表現オブジェクトと許可回転軸(親ボーン基準)
+ Dictionary TotalRotationLimits { get; set; }
+
+ ///
+ /// IK補正回転軸制限一覧
+ ///
+ /// IK計算をする際の回転軸の制限
+ Dictionary RotationAxisLimits { get; set; }
+
+ ///
+ /// 既定のコンストラクタ
+ ///
+ public DefaltIKLimitter()
+ {
+ //総合稼働制限
+ TotalRotationLimits = new Dictionary();
+ RotationLimit limit;
+ limit = new RotationLimit();
+ limit.MaxRot[0] = MathHelper.Pi;
+ limit.MinRot[0] = MathHelper.ToRadians(3f);//3度ぐらい制限を設けてやると上手くいく。
+ limit.MinRot[1] = 0;
+ limit.MaxRot[1] = 0;
+ limit.MinRot[2] = 0;
+ limit.MaxRot[2] = 0;
+ limit.Mirror[0] = true;
+ limit.Restitution[0] = 0.99f;
+ TotalRotationLimits.Add("左ひざ", limit);
+ limit = new RotationLimit();
+ limit.MaxRot[0] = MathHelper.Pi;
+ limit.MinRot[0] = MathHelper.ToRadians(3f);//3度ぐらい制限を設けてやると上手くいく。
+ limit.MinRot[1] = 0;
+ limit.MaxRot[1] = 0;
+ limit.MinRot[2] = 0;
+ limit.MaxRot[2] = 0;
+ limit.Mirror[0] = true;
+ limit.Restitution[0] = 0.99f;
+ TotalRotationLimits.Add("右ひざ", limit);
+
+ RotationAxisLimits = new Dictionary();
+ RotationAxisLimit axisLimit;
+ axisLimit = new RotationAxisLimit();
+ axisLimit.Limits[0] = false;
+ axisLimit.Limits[1] = true;
+ axisLimit.Limits[2] = false;
+ RotationAxisLimits.Add("左足", axisLimit);
+ axisLimit = new RotationAxisLimit();
+ axisLimit.Limits[0] = false;
+ axisLimit.Limits[1] = true;
+ axisLimit.Limits[2] = false;
+ RotationAxisLimits.Add("右足", axisLimit);
+
+ //IKのソルブ及びそれの調整計算に関するメモ
+ //上記数値調整計算及び各種数値設定はMMDの元コード推定(リバースエンジニアリング、逆コンパイラとかはしてないからRエンジニアって言うのか分からないけど)する過程で落ち着いている今のところの解です。
+ //ほんとの解法は樋口さんが知ってるんだろうけどw
+ //解法は今のところIK-CCD法がMMDにとって最適だと考えてます。
+ //理由として
+ //・ひざのボーンにIKソルブ時の角度制限が入っているっぽいので、ソルブにボーンの角度を扱う必要があること
+ //・高速解法が必要であること(MMDが非常に軽いことと、イテレーションの存在とその回数を考えると、軽いアルゴリズムを使ってないとつじつまが合わない)
+ //が上げられます
+ //そこで、CCD,Particleかの二つで、角度を使い易かったCCDを選びました。
+ //ひざの角度調整はCCDのクセを抑える理由もあって工夫してあります。
+ //CCDのクセとして、正しい解が<だとしたら、>という解を出してくることが多いという問題があります。(><は足ですw)
+ //そのために"反発係数"なる謎なパラメータを付けてますw
+ //また、解がほとんどまっすぐな解を出す際に、|な感じの解で固定されてしまう問題があるため、3度ぐらい下限を入れています(どうも、MMDの方も入れてるっぽいけど、よく分からない……)
+ //これは現在の推定結果です。もっと再現性が高い解があれば、改造して、ぜひ教えてください
+
+ //2012/01/19追記分
+ //IK計算の本家MMDとの微妙なズレを発見。
+ //場所は付属モーション(true my heart)の腰振りのあと\(^o^)/な動作に移行する腰振りのところ
+ //足の動きが微妙に本家とズレていることを発見
+ //原因を調査したところ、右足、左足のY軸回転の動きがIKの計算により補正されてしまうのが原因と判明
+ //そのため、新たにaxisLimit機能を追加し、右足、左足がIK計算でY軸回転を補正されないようにした。
+ //これにより他のモーションに影響が出ないかは現在調査中
+ }
+
+
+
+ #region IIKLimitter メンバー
+ ///
+ /// 制限の適用
+ ///
+ /// 対象となるボーン
+ public void Adjust(Model.MMDBone bone)
+ {
+ if (!TotalRotationLimits.ContainsKey(bone.Name))
+ return;
+ float YRot, XRot, ZRot;
+ int FactoringType = 0;
+ //if (MMDMath.FactoringQuaternionZXY(rot, out ZRot, out XRot, out YRot))
+ //まずはXYZで分解
+ if (!MathHelper.FactoringQuaternionXYZ(bone.LocalTransform.Rotation, out XRot, out YRot, out ZRot))
+ {//ジンバルロック対策
+ //YZXで分解
+ if (!MathHelper.FactoringQuaternionYZX(bone.LocalTransform.Rotation, out YRot, out ZRot, out XRot))
+ {
+ //ZXYで分解
+ MathHelper.FactoringQuaternionZXY(bone.LocalTransform.Rotation, out ZRot, out XRot, out YRot);
+ FactoringType = 2;
+ }
+ else
+ FactoringType = 1;
+ }
+ else
+ FactoringType = 0;
+
+ RotationLimit lim = TotalRotationLimits[bone.Name];
+ XRot = lim.Adjust(XRot, 0);
+ YRot = lim.Adjust(YRot, 1);
+ ZRot = lim.Adjust(ZRot, 2);
+ if (FactoringType == 0)
+ bone.LocalTransform.Rotation = Quaternion.CreateFromRotationMatrix(
+ Matrix.CreateRotationX(XRot) *
+ Matrix.CreateRotationY(YRot) *
+ Matrix.CreateRotationZ(ZRot));
+ else if (FactoringType == 1)
+ bone.LocalTransform.Rotation = Quaternion.CreateFromRotationMatrix(
+ Matrix.CreateRotationY(YRot) *
+ Matrix.CreateRotationZ(ZRot) *
+ Matrix.CreateRotationX(XRot));
+ else
+ bone.LocalTransform.Rotation = Quaternion.CreateFromYawPitchRoll(YRot, XRot, ZRot);
+
+ }
+ ///
+ /// 回転軸制限の適用
+ ///
+ /// ボーン名
+ /// 回転軸
+ public void Adjust(string boneName, ref Vector3 rotationAxis)
+ {
+ RotationAxisLimit limit;
+ if (RotationAxisLimits.TryGetValue(boneName, out limit))
+ {
+ limit.Adjust(ref rotationAxis);
+ }
+ }
+ #endregion
+ }
+}
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerLibrary/Misc/IIKLimitter.cs b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerLibrary/Misc/IIKLimitter.cs
new file mode 100644
index 000000000..7af448aaa
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerLibrary/Misc/IIKLimitter.cs
@@ -0,0 +1,23 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using MMDIKBakerLibrary.Model;
+
+namespace MMDIKBakerLibrary.Misc
+{
+ interface IIKLimitter
+ {
+ ///
+ /// 制限の適用
+ ///
+ /// 対象となるボーン
+ void Adjust(MMDBone bone);
+
+ ///
+ /// 回転軸制限の適用
+ ///
+ /// 対象となるボーン名
+ /// 回転軸
+ void Adjust(string boneName, ref Vector3 rotationAxis);
+ }
+}
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerLibrary/Misc/IIKSolver.cs b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerLibrary/Misc/IIKSolver.cs
new file mode 100644
index 000000000..e09c6a681
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerLibrary/Misc/IIKSolver.cs
@@ -0,0 +1,18 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using MMDIKBakerLibrary.Model;
+
+namespace MMDIKBakerLibrary.Misc
+{
+ interface IIKSolver
+ {
+ ///
+ /// IKのソルブ
+ ///
+ /// 対象IK
+ /// ボーンマネージャ
+ /// 呼び出し側でUpdateGlobalをもう一度呼ぶ場合はtrue
+ bool Solve(MMDIK ik, MMDBoneManager BoneManager);
+ }
+}
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerLibrary/Misc/MathHelper.cs b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerLibrary/Misc/MathHelper.cs
new file mode 100644
index 000000000..7a6a6244d
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerLibrary/Misc/MathHelper.cs
@@ -0,0 +1,224 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace MMDIKBakerLibrary.Misc
+{
+ static class MathHelper
+ {
+ public static float Pi { get { return (float)Math.PI; } }
+ public static float PiOver2 { get { return Pi / 2; } }
+ public static decimal Clamp(decimal value, decimal min, decimal max)
+ {
+ return Math.Max(min, Math.Min(value, max));
+ }
+ public static float Clamp(float value, float min, float max)
+ {
+ return Math.Max(min, Math.Min(value, max));
+ }
+
+
+ public static decimal Lerp(decimal value1, decimal value2, decimal amount)
+ {
+ if (value1 == value2)
+ {
+ return value1;
+ }
+ return value1 + (value2 - value1) * Clamp(amount, 0m, 1m);
+ }
+ public static float Lerp(float value1, float value2, float amount)
+ {
+ if (value1 == value2)
+ {
+ return value1;
+ }
+ return value1 + (value2 - value1) * Clamp(amount, 0, 1);
+ }
+ public static BezierCurve[] CreateIdentityCurve()
+ {
+ BezierCurve[] result = new BezierCurve[4];
+ for (int i = 0; i < result.Length; i++)
+ {
+ result[i].v1 = new Vector2 { X = 0.25f, Y = 0.25f };
+ result[i].v2 = new Vector2 { X = 0.75f, Y = 0.75f };
+ }
+ return result;
+ }
+
+ public static int GetMaxArgIndex(params decimal[] argument)
+ {
+ decimal value = decimal.MinValue;
+ int index = -1;
+ for (int i = 0; i < argument.Length; ++i)
+ {
+ if (argument[i] > value)
+ {
+ index = i;
+ value = argument[i];
+ }
+ }
+ return index;
+ }
+
+ public static Vector3 Round(Vector3 vector, int decimals)
+ {
+ return new Vector3(Math.Round(vector.X, decimals),Math.Round(vector.Y, decimals),Math.Round(vector.Z, decimals));
+ }
+
+ public static Quaternion Round(Quaternion rotation, int decimals)
+ {
+ return new Quaternion(Math.Round(rotation.X, decimals), Math.Round(rotation.Y, decimals), Math.Round(rotation.Z, decimals), Math.Round(rotation.W, decimals));
+ }
+
+ internal static Matrix Round(Matrix matrix, int decimals)
+ {
+ return new Matrix()
+ {
+ M11 = Math.Round(matrix.M11, decimals),
+ M12 = Math.Round(matrix.M12, decimals),
+ M13 = Math.Round(matrix.M13, decimals),
+ M14 = Math.Round(matrix.M14, decimals),
+ M21 = Math.Round(matrix.M21, decimals),
+ M22 = Math.Round(matrix.M22, decimals),
+ M23 = Math.Round(matrix.M23, decimals),
+ M24 = Math.Round(matrix.M24, decimals),
+ M31 = Math.Round(matrix.M31, decimals),
+ M32 = Math.Round(matrix.M32, decimals),
+ M33 = Math.Round(matrix.M33, decimals),
+ M34 = Math.Round(matrix.M34, decimals),
+ M41 = Math.Round(matrix.M41, decimals),
+ M42 = Math.Round(matrix.M42, decimals),
+ M43 = Math.Round(matrix.M43, decimals),
+ M44 = Math.Round(matrix.M44, decimals)
+ };
+ }
+
+
+
+
+ public static float ToRadians(float degrees)
+ {
+ return degrees * 0.01745329f;
+ }
+ ///
+ /// クォータニオンをYaw(Y回転), Pitch(X回転), Roll(Z回転)に分解する関数
+ ///
+ /// 分解するクォータニオン
+ /// Z軸回転
+ /// X軸回転(-PI/2~PI/2)
+ /// Y軸回転
+ /// ジンバルロックが発生した時はfalse。ジンバルロックはX軸回転で発生
+ public static bool FactoringQuaternionZXY(Quaternion input, out float ZRot, out float XRot, out float YRot)
+ {
+ //クォータニオンの正規化
+ Quaternion inputQ = new Quaternion(input.X, input.Y, input.Z, input.W);
+ inputQ.Normalize();
+ //マトリクスを生成する
+ Matrix rot;
+ Matrix.CreateFromQuaternion(ref inputQ, out rot);
+ //ヨー(X軸周りの回転)を取得
+ if ((double)rot.M32 > 1 - 1.0e-4 || (double)rot.M32 < -1 + 1.0e-4)
+ {//ジンバルロック判定
+ XRot = (rot.M32 < 0 ? MathHelper.PiOver2 : -MathHelper.PiOver2);
+ ZRot = 0; YRot = (float)Math.Atan2(-(double)rot.M13, (double) rot.M11);
+ return false;
+ }
+ XRot = -(float)Math.Asin((double)rot.M32);
+ //ロールを取得
+ ZRot = (float)Math.Asin((double)rot.M12 / Math.Cos(XRot));
+ if (float.IsNaN(ZRot))
+ {//漏れ対策
+ XRot = (rot.M32 < 0 ? MathHelper.PiOver2 : -MathHelper.PiOver2);
+ ZRot = 0; YRot = (float)Math.Atan2(-(double)rot.M13, (double)rot.M11);
+ return false;
+ }
+ if (rot.M22 < 0)
+ ZRot = MathHelper.Pi - ZRot;
+ //ピッチを取得
+ YRot = (float)Math.Atan2((double)rot.M31, (double)rot.M33);
+ return true;
+ }
+
+
+ ///
+ /// クォータニオンをX,Y,Z回転に分解する関数
+ ///
+ /// 分解するクォータニオン
+ /// X軸回転
+ /// Y軸回転(-PI/2~PI/2)
+ /// Z軸回転
+ ///
+ public static bool FactoringQuaternionXYZ(Quaternion input, out float XRot, out float YRot, out float ZRot)
+ {
+ //クォータニオンの正規化
+ Quaternion inputQ = new Quaternion(input.X, input.Y, input.Z, input.W);
+ inputQ.Normalize();
+ //マトリクスを生成する
+ Matrix rot;
+ Matrix.CreateFromQuaternion(ref inputQ, out rot);
+ //Y軸回りの回転を取得
+ if ((double)rot.M13 > 1 - 1.0e-4 || (double)rot.M13 < -1 + 1.0e-4)
+ {//ジンバルロック判定
+ XRot = 0;
+ YRot = (rot.M13 < 0 ? MathHelper.PiOver2 : -MathHelper.PiOver2);
+ ZRot = -(float)Math.Atan2(-(double)rot.M21, (double)rot.M22);
+ return false;
+ }
+ YRot = -(float)Math.Asin((double)rot.M13);
+ //X軸回りの回転を取得
+ XRot = (float)Math.Asin((double)rot.M23 / Math.Cos(YRot));
+ if (float.IsNaN(XRot))
+ {//ジンバルロック判定(漏れ対策)
+ XRot = 0;
+ YRot = (rot.M13 < 0 ? MathHelper.PiOver2 : -MathHelper.PiOver2);
+ ZRot = -(float)Math.Atan2(-(double)rot.M21, (double)rot.M22);
+ return false;
+ }
+ if (rot.M33 < 0)
+ XRot = MathHelper.Pi - XRot;
+ //Z軸回りの回転を取得
+ ZRot = (float)Math.Atan2((double)rot.M12, (double)rot.M11);
+ return true;
+ }
+ ///
+ /// クォータニオンをY,Z,X回転に分解する関数
+ ///
+ /// 分解するクォータニオン
+ /// Y軸回転
+ /// Z軸回転(-PI/2~PI/2)
+ /// X軸回転
+ ///
+ public static bool FactoringQuaternionYZX(Quaternion input, out float YRot, out float ZRot, out float XRot)
+ {
+ //クォータニオンの正規化
+ Quaternion inputQ = new Quaternion(input.X, input.Y, input.Z, input.W);
+ inputQ.Normalize();
+ //マトリクスを生成する
+ Matrix rot;
+ Matrix.CreateFromQuaternion(ref inputQ, out rot);
+ //Z軸回りの回転を取得
+ if ((double)rot.M21 > 1 - 1.0e-4 || (double)rot.M21 < -1 + 1.0e-4)
+ {//ジンバルロック判定
+ YRot = 0;
+ ZRot = (rot.M21 < 0 ? MathHelper.PiOver2 : -MathHelper.PiOver2);
+ XRot = -(float)Math.Atan2(-(double)rot.M32, (double)rot.M33);
+ return false;
+ }
+ ZRot = -(float)Math.Asin((double)rot.M21);
+ //Y軸回りの回転を取得
+ YRot = (float)Math.Asin((double)rot.M31 / Math.Cos(ZRot));
+ if (float.IsNaN(YRot))
+ {//ジンバルロック判定(漏れ対策)
+ YRot = 0;
+ ZRot = (rot.M21 < 0 ? MathHelper.PiOver2 : -MathHelper.PiOver2);
+ XRot = -(float)Math.Atan2(-(double)rot.M32, (double)rot.M33);
+ return false;
+ }
+ if (rot.M11 < 0)
+ YRot = MathHelper.Pi - YRot;
+ //X軸回りの回転を取得
+ XRot = (float)Math.Atan2((double)rot.M23, (double)rot.M22);
+ return true;
+ }
+ }
+}
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerLibrary/Misc/Matrix.cs b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerLibrary/Misc/Matrix.cs
new file mode 100644
index 000000000..34d4e9d5e
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerLibrary/Misc/Matrix.cs
@@ -0,0 +1,393 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace MMDIKBakerLibrary.Misc
+{
+ struct Matrix
+ {
+ public decimal M11;
+ public decimal M12;
+ public decimal M13;
+ public decimal M14;
+ public decimal M21;
+ public decimal M22;
+ public decimal M23;
+ public decimal M24;
+ public decimal M31;
+ public decimal M32;
+ public decimal M33;
+ public decimal M34;
+ public decimal M41;
+ public decimal M42;
+ public decimal M43;
+ public decimal M44;
+
+
+ public static Matrix Identity
+ {
+ get
+ {
+ return new Matrix { M11 = 1, M12 = 0, M13 = 0, M14 = 0, M21 = 0, M22 = 1, M23 = 0, M24 = 0, M31 = 0, M32 = 0, M33 = 1, M34 = 0, M41 = 0, M42 = 0, M43 = 0, M44 = 1 };
+ }
+ }
+ public Vector3 Translation
+ {
+ get
+ {
+ Vector3 result;
+ result.X = this.M41;
+ result.Y = this.M42;
+ result.Z = this.M43;
+ result.NaN = false;
+ return result;
+ }
+
+ }
+
+
+ public static void CreateTranslation(decimal x, decimal y, decimal z, out Matrix result)
+ {
+ result.M11 = 1;
+ result.M12 = 0;
+ result.M13 = 0;
+ result.M14 = 0;
+ result.M21 = 0;
+ result.M22 = 1;
+ result.M23 = 0;
+ result.M24 = 0;
+ result.M31 = 0;
+ result.M32 = 0;
+ result.M33 = 1;
+ result.M34 = 0;
+ result.M41 = x;
+ result.M42 = y;
+ result.M43 = z;
+ result.M44 = 1;
+ }
+
+ public static void Invert(ref Matrix matrix, out Matrix result)
+ {
+ decimal temp1 = matrix.M33 * matrix.M44 - matrix.M34 * matrix.M43;
+ decimal temp2 = matrix.M32 * matrix.M44 - matrix.M34 * matrix.M42;
+ decimal temp3 = matrix.M32 * matrix.M43 - matrix.M33 * matrix.M42;
+ decimal temp4 = matrix.M31 * matrix.M44 - matrix.M34 * matrix.M41;
+ decimal temp5 = matrix.M31 * matrix.M43 - matrix.M33 * matrix.M41;
+ decimal temp6 = matrix.M31 * matrix.M42 - matrix.M32 * matrix.M41;
+ decimal temp7 = matrix.M22 * temp1 - matrix.M23 * temp2 + matrix.M24 * temp3;
+ decimal temp8 = -(matrix.M21 * temp1 - matrix.M23 * temp4 + matrix.M24 * temp5);
+ decimal temp9 = matrix.M21 * temp2 - matrix.M22 * temp4 + matrix.M24 * temp6;
+ decimal temp10 = -(matrix.M21 * temp3 - matrix.M22 * temp5 + matrix.M23 * temp6);
+ decimal temp11 = matrix.M23 * matrix.M44 - matrix.M24 * matrix.M43;
+ decimal temp12 = matrix.M22 * matrix.M44 - matrix.M24 * matrix.M42;
+ decimal temp13 = matrix.M22 * matrix.M43 - matrix.M23 * matrix.M42;
+ decimal temp14 = matrix.M21 * matrix.M44 - matrix.M24 * matrix.M41;
+ decimal temp15 = matrix.M21 * matrix.M43 - matrix.M23 * matrix.M41;
+ decimal temp16 = matrix.M21 * matrix.M42 - matrix.M22 * matrix.M41;
+ decimal temp17 = matrix.M23 * matrix.M34 - matrix.M24 * matrix.M33;
+ decimal temp18 = matrix.M22 * matrix.M34 - matrix.M24 * matrix.M32;
+ decimal temp19 = matrix.M22 * matrix.M33 - matrix.M23 * matrix.M32;
+ decimal temp20 = matrix.M21 * matrix.M34 - matrix.M24 * matrix.M31;
+ decimal temp21 = matrix.M21 * matrix.M33 - matrix.M23 * matrix.M31;
+ decimal temp22 = matrix.M21 * matrix.M32 - matrix.M22 * matrix.M31;
+ decimal det = 1m / (matrix.M11 * temp7 + matrix.M12 * temp8 + matrix.M13 * temp9 + matrix.M14 * temp10);
+ result.M11 = temp7 * det;
+ result.M21 = temp8 * det;
+ result.M31 = temp9 * det;
+ result.M41 = temp10 * det;
+ result.M12 = -(matrix.M12 * temp1 - matrix.M13 * temp2 + matrix.M14 * temp3) * det;
+ result.M22 = (matrix.M11 * temp1 - matrix.M13 * temp4 + matrix.M14 * temp5) * det;
+ result.M32 = -(matrix.M11 * temp2 - matrix.M12 * temp4 + matrix.M14 * temp6) * det;
+ result.M42 = (matrix.M11 * temp3 - matrix.M12 * temp5 + matrix.M13 * temp6) * det;
+ result.M13 = (matrix.M12 * temp11 - matrix.M13 * temp12 + matrix.M14 * temp13) * det;
+ result.M23 = -(matrix.M11 * temp11 - matrix.M13 * temp14 + matrix.M14 * temp15) * det;
+ result.M33 = (matrix.M11 * temp12 - matrix.M12 * temp14 + matrix.M14 * temp16) * det;
+ result.M43 = -(matrix.M11 * temp13 - matrix.M12 * temp15 + matrix.M13 * temp16) * det;
+ result.M14 = -(matrix.M12 * temp17 - matrix.M13 * temp18 + matrix.M14 * temp19) * det;
+ result.M24 = (matrix.M11 * temp17 - matrix.M13 * temp20 + matrix.M14 * temp21) * det;
+ result.M34 = -(matrix.M11 * temp18 - matrix.M12 * temp20 + matrix.M14 * temp22) * det;
+ result.M44 = (matrix.M11 * temp19 - matrix.M12 * temp21 + matrix.M13 * temp22) * det;
+ }
+
+ public static void Multiply(ref Matrix matrix1, ref Matrix matrix2, out Matrix result)
+ {
+ result.M11 = matrix1.M11 * matrix2.M11 + matrix1.M12 * matrix2.M21 + matrix1.M13 * matrix2.M31 + matrix1.M14 * matrix2.M41;
+ result.M12 = matrix1.M11 * matrix2.M12 + matrix1.M12 * matrix2.M22 + matrix1.M13 * matrix2.M32 + matrix1.M14 * matrix2.M42;
+ result.M13 = matrix1.M11 * matrix2.M13 + matrix1.M12 * matrix2.M23 + matrix1.M13 * matrix2.M33 + matrix1.M14 * matrix2.M43;
+ result.M14 = matrix1.M11 * matrix2.M14 + matrix1.M12 * matrix2.M24 + matrix1.M13 * matrix2.M34 + matrix1.M14 * matrix2.M44;
+ result.M21 = matrix1.M21 * matrix2.M11 + matrix1.M22 * matrix2.M21 + matrix1.M23 * matrix2.M31 + matrix1.M24 * matrix2.M41;
+ result.M22 = matrix1.M21 * matrix2.M12 + matrix1.M22 * matrix2.M22 + matrix1.M23 * matrix2.M32 + matrix1.M24 * matrix2.M42;
+ result.M23 = matrix1.M21 * matrix2.M13 + matrix1.M22 * matrix2.M23 + matrix1.M23 * matrix2.M33 + matrix1.M24 * matrix2.M43;
+ result.M24 = matrix1.M21 * matrix2.M14 + matrix1.M22 * matrix2.M24 + matrix1.M23 * matrix2.M34 + matrix1.M24 * matrix2.M44;
+ result.M31 = matrix1.M31 * matrix2.M11 + matrix1.M32 * matrix2.M21 + matrix1.M33 * matrix2.M31 + matrix1.M34 * matrix2.M41;
+ result.M32 = matrix1.M31 * matrix2.M12 + matrix1.M32 * matrix2.M22 + matrix1.M33 * matrix2.M32 + matrix1.M34 * matrix2.M42;
+ result.M33 = matrix1.M31 * matrix2.M13 + matrix1.M32 * matrix2.M23 + matrix1.M33 * matrix2.M33 + matrix1.M34 * matrix2.M43;
+ result.M34 = matrix1.M31 * matrix2.M14 + matrix1.M32 * matrix2.M24 + matrix1.M33 * matrix2.M34 + matrix1.M34 * matrix2.M44;
+ result.M41 = matrix1.M41 * matrix2.M11 + matrix1.M42 * matrix2.M21 + matrix1.M43 * matrix2.M31 + matrix1.M44 * matrix2.M41;
+ result.M42 = matrix1.M41 * matrix2.M12 + matrix1.M42 * matrix2.M22 + matrix1.M43 * matrix2.M32 + matrix1.M44 * matrix2.M42;
+ result.M43 = matrix1.M41 * matrix2.M13 + matrix1.M42 * matrix2.M23 + matrix1.M43 * matrix2.M33 + matrix1.M44 * matrix2.M43;
+ result.M44 = matrix1.M41 * matrix2.M14 + matrix1.M42 * matrix2.M24 + matrix1.M43 * matrix2.M34 + matrix1.M44 * matrix2.M44;
+ }
+ public static Matrix operator *(Matrix matrix1, Matrix matrix2)
+ {
+ Matrix result;
+ Matrix.Multiply(ref matrix1, ref matrix2, out result);
+ return result;
+ }
+ public static void CreateScale(ref Vector3 scale, out Matrix result)
+ {
+ result.M11 = scale.X;
+ result.M12 = 0;
+ result.M13 = 0;
+ result.M14 = 0;
+ result.M21 = 0;
+ result.M22 = scale.Y;
+ result.M23 = 0;
+ result.M24 = 0;
+ result.M31 = 0;
+ result.M32 = 0;
+ result.M33 = scale.Z;
+ result.M34 = 0;
+ result.M41 = 0;
+ result.M42 = 0;
+ result.M43 = 0;
+ result.M44 = 1;
+ }
+ public static void CreateFromQuaternion(Quaternion quaternion, out Matrix result)
+ {
+ quaternion.Normalize();
+ decimal xx = quaternion.X * quaternion.X;
+ decimal yy = quaternion.Y * quaternion.Y;
+ decimal zz = quaternion.Z * quaternion.Z;
+ decimal xy = quaternion.X * quaternion.Y;
+ decimal yz = quaternion.Y * quaternion.Z;
+ decimal zx = quaternion.Z * quaternion.X;
+ decimal xw = quaternion.X * quaternion.W;
+ decimal yw = quaternion.Y * quaternion.W;
+ decimal zw = quaternion.Z * quaternion.W;
+ result.M11 = 1 - 2 * (yy + zz);
+ result.M12 = 2 * (xy + zw);
+ result.M13 = 2 * (zx - yw);
+ result.M14 = 0;
+ result.M21 = 2 * (xy - zw);
+ result.M22 = 1 - 2 * (zz + xx);
+ result.M23 = 2 * (yz + xw);
+ result.M24 = 0;
+ result.M31 = 2 * (zx + yw);
+ result.M32 = 2 * (yz - xw);
+ result.M33 = 1 - 2 * (yy + xx);
+ result.M34 = 0;
+ result.M41 = 0;
+ result.M42 = 0;
+ result.M43 = 0;
+ result.M44 = 1;
+ }
+ public static void CreateTranslation(ref Vector3 position, out Matrix result)
+ {
+ result.M11 = 1;
+ result.M12 = 0;
+ result.M13 = 0;
+ result.M14 = 0;
+ result.M21 = 0;
+ result.M22 = 1;
+ result.M23 = 0;
+ result.M24 = 0;
+ result.M31 = 0;
+ result.M32 = 0;
+ result.M33 = 1;
+ result.M34 = 0;
+ result.M41 = position.X;
+ result.M42 = position.Y;
+ result.M43 = position.Z;
+ result.M44 = 1;
+ }
+
+ public void Decompose(out Vector3 scale, out Quaternion rotation, out Vector3 translation)
+ {
+ //移動行列の切り出し
+ translation = new Vector3(M41, M42, M43);
+ //スケールの切り出しと回転行列の作成
+ scale = new Vector3();
+ Matrix rotMatrix = new Matrix();
+ Vector3 temp;
+ temp = new Vector3(M11, M12, M13);
+ scale.X = temp.Length();
+ if (scale.X > 0)
+ {
+ rotMatrix.M11 = M11 / scale.X;
+ rotMatrix.M12 = M12 / scale.X;
+ rotMatrix.M13 = M13 / scale.X;
+ }
+ temp = new Vector3(M21, M22, M23);
+ scale.Y = temp.Length();
+ if (scale.X > 0)
+ {
+ rotMatrix.M21 = M21 / scale.Y;
+ rotMatrix.M22 = M22 / scale.Y;
+ rotMatrix.M23 = M23 / scale.Y;
+ }
+ temp = new Vector3(M31, M32, M33);
+ scale.Z = temp.Length();
+ if (scale.X > 0)
+ {
+ rotMatrix.M31 = M31 / scale.Z;
+ rotMatrix.M32 = M32 / scale.Z;
+ rotMatrix.M33 = M33 / scale.Z;
+ }
+ if (scale.Length() == 0)
+ {
+ throw new ArgumentException("scale成分が不明");
+ }
+ //回転行列をクォータニオンに変換する
+ rotation = new Quaternion();
+ decimal w = (decimal)Math.Sqrt((double)Math.Max(rotMatrix.M11 + rotMatrix.M22 + rotMatrix.M33 + 1, 0)) / 2;
+ decimal tempX = (decimal)Math.Sqrt((double)Math.Max(rotMatrix.M11 - rotMatrix.M22 - rotMatrix.M33 + 1, 0)) / 2;
+ decimal tempY = (decimal)Math.Sqrt((double)Math.Max(-rotMatrix.M11 + rotMatrix.M22 - rotMatrix.M33 + 1, 0)) / 2;
+ decimal tempZ = (decimal)Math.Sqrt((double)Math.Max(-rotMatrix.M11 - rotMatrix.M22 + rotMatrix.M33 + 1, 0)) / 2;
+ int MaxIndex = MathHelper.GetMaxArgIndex(tempX, tempY, tempZ, w);
+ switch (MaxIndex)
+ {
+ case 0://x
+ rotation.X = tempX;
+ rotation.Y = (rotMatrix.M12 + rotMatrix.M21) / (4 * Math.Abs(tempX));
+ rotation.Z = (rotMatrix.M31 + rotMatrix.M13) / (4 * Math.Abs(tempX));
+ rotation.W = (rotMatrix.M23 - rotMatrix.M32) / (4 * Math.Abs(tempX));
+ break;
+ case 1:
+ rotation.X = (rotMatrix.M12 + rotMatrix.M21) / (4 * Math.Abs(tempY));
+ rotation.Y = tempY;
+ rotation.Z = (rotMatrix.M23 + rotMatrix.M32) / (4 * Math.Abs(tempY));
+ rotation.W = (rotMatrix.M31 - rotMatrix.M13) / (4 * Math.Abs(tempY));
+ break;
+ case 2:
+ rotation.X = (rotMatrix.M31 + rotMatrix.M13) / (4 * Math.Abs(tempZ));
+ rotation.Y = (rotMatrix.M23 + rotMatrix.M32) / (4 * Math.Abs(tempZ));
+ rotation.Z = tempZ;
+ rotation.W = (rotMatrix.M12 - rotMatrix.M21) / (4 * Math.Abs(tempZ));
+ break;
+ default://w
+ rotation.X = (rotMatrix.M23 - rotMatrix.M32) / (4 * Math.Abs(w));
+ rotation.Y = (rotMatrix.M31 - rotMatrix.M13) / (4 * Math.Abs(w));
+ rotation.Z = (rotMatrix.M12 - rotMatrix.M21) / (4 * Math.Abs(w));
+ rotation.W = w;
+ break;
+ }
+ }
+ public static void Compose(Vector3 scale,Quaternion rotation, Vector3 translation, out Matrix result)
+ {
+ Matrix scaleMat, rotateMat, translationMat;
+ Matrix.CreateScale(ref scale, out scaleMat);
+ Matrix.CreateFromQuaternion(rotation, out rotateMat);
+ Matrix.CreateTranslation(ref translation, out translationMat);
+ Matrix temp;
+ Multiply(ref scaleMat, ref rotateMat, out temp);
+ Multiply(ref temp, ref translationMat, out result);
+ }
+
+
+ internal static void GetTranslation(ref Matrix matrix, out Vector3 trans)
+ {
+ trans = matrix.Translation;
+ }
+
+ public static Matrix CreateRotationX(float radians)
+ {
+ Matrix result;
+ decimal single1 = (decimal)Math.Cos((double)radians);
+ decimal single2 = (decimal)Math.Sin((double)radians);
+ result.M11 = 1;
+ result.M12 = 0;
+ result.M13 = 0;
+ result.M14 = 0;
+ result.M21 = 0;
+ result.M22 = single1;
+ result.M23 = single2;
+ result.M24 = 0;
+ result.M31 = 0;
+ result.M32 = -single2;
+ result.M33 = single1;
+ result.M34 = 0;
+ result.M41 = 0;
+ result.M42 = 0;
+ result.M43 = 0;
+ result.M44 = 1;
+ return result;
+ }
+ public static Matrix CreateRotationY(float radians)
+ {
+ Matrix result;
+ decimal single1 = (decimal)Math.Cos((double)radians);
+ decimal single2 = (decimal)Math.Sin((double)radians);
+ result.M11 = single1;
+ result.M12 = 0;
+ result.M13 = -single2;
+ result.M14 = 0;
+ result.M21 = 0;
+ result.M22 = 1;
+ result.M23 = 0;
+ result.M24 = 0;
+ result.M31 = single2;
+ result.M32 = 0;
+ result.M33 = single1;
+ result.M34 = 0;
+ result.M41 = 0;
+ result.M42 = 0;
+ result.M43 = 0;
+ result.M44 = 1;
+ return result;
+ }
+ public static Matrix CreateRotationZ(float radians)
+ {
+ Matrix result;
+ decimal single1 = (decimal)Math.Cos((double)radians);
+ decimal single2 = (decimal)Math.Sin((double)radians);
+ result.M11 = single1;
+ result.M12 = single2;
+ result.M13 = 0;
+ result.M14 = 0;
+ result.M21 = -single2;
+ result.M22 = single1;
+ result.M23 = 0;
+ result.M24 = 0;
+ result.M31 = 0;
+ result.M32 = 0;
+ result.M33 = 1;
+ result.M34 = 0;
+ result.M41 = 0;
+ result.M42 = 0;
+ result.M43 = 0;
+ result.M44 = 1;
+ return result;
+ }
+ public static void CreateFromQuaternion(ref Quaternion quaternion, out Matrix result)
+ {
+ decimal xx = quaternion.X * quaternion.X;
+ decimal yy = quaternion.Y * quaternion.Y;
+ decimal zz = quaternion.Z * quaternion.Z;
+ decimal xy = quaternion.X * quaternion.Y;
+ decimal zw = quaternion.Z * quaternion.W;
+ decimal zx = quaternion.Z * quaternion.X;
+ decimal yw = quaternion.Y * quaternion.W;
+ decimal yz = quaternion.Y * quaternion.Z;
+ decimal xw = quaternion.X * quaternion.W;
+ result.M11 = 1 - 2 * (yy + zz);
+ result.M12 = 2 * (xy + zw);
+ result.M13 = 2 * (zx - yw);
+ result.M14 = 0;
+ result.M21 = 2 * (xy - zw);
+ result.M22 = 1 - 2 * (zz + xx);
+ result.M23 = 2 * (yz + xw);
+ result.M24 = 0;
+ result.M31 = 2 * (zx + yw);
+ result.M32 = 2 * (yz - xw);
+ result.M33 = 1 - 2 * (yy + xx);
+ result.M34 = 0;
+ result.M41 = 0;
+ result.M42 = 0;
+ result.M43 = 0;
+ result.M44 = 1;
+ }
+
+
+ }
+}
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerLibrary/Misc/Quaternion.cs b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerLibrary/Misc/Quaternion.cs
new file mode 100644
index 000000000..b004e92c4
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerLibrary/Misc/Quaternion.cs
@@ -0,0 +1,123 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace MMDIKBakerLibrary.Misc
+{
+ struct Quaternion
+ {
+ public decimal X;
+ public decimal Y;
+ public decimal Z;
+ public decimal W;
+
+ public static Quaternion Identity { get { return new Quaternion(0, 0, 0, 1); } }
+
+ public Quaternion(decimal x, decimal y, decimal z, decimal w)
+ {
+ X = x; Y = y; Z = z; W = w;
+ }
+ public static void Slerp(ref Quaternion quaternion1, ref Quaternion quaternion2, decimal amount, out Quaternion result)
+ {
+ decimal rate2;
+ decimal rate1;
+ decimal dot = quaternion1.X * quaternion2.X + quaternion1.Y * quaternion2.Y + quaternion1.Z * quaternion2.Z + quaternion1.W * quaternion2.W;
+ bool flag = false;
+ if (dot < 0)
+ {
+ flag = true;
+ dot = -dot;
+ }
+ if (dot > 0.999999m)
+ {
+ rate1 = 1 - amount;
+ rate2 = (flag ? -amount : amount);
+ }
+ else
+ {
+ decimal ph = (decimal)Math.Acos((double)dot);
+ rate1 = (decimal)Math.Sin((double)((1 - amount) * ph)) * (decimal)(1.0f/(float)Math.Sin((double)ph));
+ rate2 = (decimal)Math.Sin((double)(amount * ph)) * (decimal)(1.0f/(float)Math.Sin((double)ph));
+ if (flag)
+ {
+ rate2 = -rate2;
+ }
+ }
+ result.X = rate1 * quaternion1.X + rate2 * quaternion2.X;
+ result.Y = rate1 * quaternion1.Y + rate2 * quaternion2.Y;
+ result.Z = rate1 * quaternion1.Z + rate2 * quaternion2.Z;
+ result.W = rate1 * quaternion1.W + rate2 * quaternion2.W;
+ }
+ public static Quaternion CreateFromAxisAngle(Vector3 axis, decimal angle)
+ {
+ decimal temp = (decimal)Math.Sin((double)angle * 0.5);
+ Quaternion result;
+ result.X = axis.X * temp;
+ result.Y = axis.Y * temp;
+ result.Z = axis.Z * temp;
+ result.W = (decimal)Math.Cos((double)angle * 0.5);
+ return result;
+ }
+
+
+
+ public void Normalize()
+ {
+ decimal temp = 1 / (decimal)Math.Sqrt((double)(this.X * this.X + this.Y * this.Y + this.Z * this.Z + this.W * this.W));
+ this.X = this.X * temp;
+ this.Y = this.Y * temp;
+ this.Z = this.Z * temp;
+ this.W = this.W * temp;
+ }
+
+ public static void Multiply(ref Quaternion quaternion1, ref Quaternion quaternion2, out Quaternion result)
+ {
+ result.X = quaternion1.X * quaternion2.W + quaternion2.X * quaternion1.W + quaternion1.Y * quaternion2.Z - quaternion1.Z * quaternion2.Y;
+ result.Y = quaternion1.Y * quaternion2.W + quaternion2.Y * quaternion1.W + quaternion1.Z * quaternion2.X - quaternion1.X * quaternion2.Z;
+ result.Z = quaternion1.Z * quaternion2.W + quaternion2.Z * quaternion1.W + quaternion1.X * quaternion2.Y - quaternion1.Y * quaternion2.X;
+ result.W = quaternion1.W * quaternion2.W - (quaternion1.X * quaternion2.X + quaternion1.Y * quaternion2.Y + quaternion1.Z * quaternion2.Z);
+ }
+ public static Quaternion CreateFromRotationMatrix(Matrix matrix)
+ {
+ decimal diag = matrix.M11 + matrix.M22 + matrix.M33;
+ Quaternion result = new Quaternion();
+ if (diag > 0)
+ {
+ decimal temp1 = (decimal)Math.Sqrt((double)diag + 1);
+ result.W = temp1 * 0.5m;
+ temp1 = 0.5m / temp1;
+ result.X = (matrix.M23 - matrix.M32) * temp1;
+ result.Y = (matrix.M31 - matrix.M13) * temp1;
+ result.Z = (matrix.M12 - matrix.M21) * temp1;
+ }
+ else
+ {
+ if (matrix.M11 >= matrix.M22 && matrix.M11 >= matrix.M33)
+ {
+ decimal temp2 = (decimal)Math.Sqrt((double)(1m + matrix.M11 - matrix.M22 - matrix.M33));
+ decimal temp3 = 0.5m / temp2;
+ result.X = 0.5m * temp2;
+ result.Y = (matrix.M12 + matrix.M21) * temp3;
+ result.Z = (matrix.M13 + matrix.M31) * temp3;
+ result.W = (matrix.M23 - matrix.M32) * temp3;
+ }
+ }
+ return result;
+ }
+ public static Quaternion CreateFromYawPitchRoll(float yaw, float pitch, float roll)
+ {
+ decimal sin_roll = (decimal)Math.Sin((double)roll * 0.5);
+ decimal cos_roll = (decimal)Math.Cos((double)roll * 0.5);
+ decimal sin_pitch = (decimal)Math.Sin((double)pitch * 0.5);
+ decimal cos_pitch = (decimal)Math.Cos((double)pitch * 0.5);
+ decimal sin_yaw = (decimal)Math.Sin((double)yaw * 0.5);
+ decimal cos_yaw = (decimal)Math.Cos((double)yaw * 0.5);
+ Quaternion result;
+ result.X = cos_yaw * sin_pitch * cos_roll + sin_yaw * cos_pitch * sin_roll;
+ result.Y = sin_yaw * cos_pitch * cos_roll - cos_yaw * sin_pitch * sin_roll;
+ result.Z = cos_yaw * cos_pitch * sin_roll - sin_yaw * sin_pitch * cos_roll;
+ result.W = cos_yaw * cos_pitch * cos_roll + sin_yaw * sin_pitch * sin_roll;
+ return result;
+ }
+ }
+}
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerLibrary/Misc/SQTTransform.cs b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerLibrary/Misc/SQTTransform.cs
new file mode 100644
index 000000000..25dfb058c
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerLibrary/Misc/SQTTransform.cs
@@ -0,0 +1,160 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace MMDIKBakerLibrary.Misc
+{
+ ///
+ /// 拡大、回転、移動の3つを表す変換
+ ///
+ struct SQTTransform
+ {
+ #region フィールド
+ ///
+ /// 拡大
+ ///
+ public Vector3 Scales;
+
+ ///
+ /// 回転
+ ///
+ public Quaternion Rotation;
+
+ ///
+ /// 平行移動
+ ///
+ public Vector3 Translation;
+
+ #endregion
+
+ ///
+ /// SQTTransformを生成
+ ///
+ /// スケールベクトル
+ /// 回転クォータニオン
+ /// 移動ベクトル
+ public SQTTransform(Vector3 scales, Quaternion rotation, Vector3 translation)
+ {
+ Scales = scales;
+ Rotation = rotation;
+ Translation = translation;
+ }
+
+ ///
+ /// SQTTransformを生成
+ ///
+ /// スケールベクトル
+ /// 回転クォータニオン
+ /// 移動ベクトル
+ /// SQTTransform
+ public static void Create(ref Vector3 scales, ref Quaternion rotation, ref Vector3 translation, out SQTTransform result)
+ {
+ result = new SQTTransform() { Scales = scales, Rotation = rotation, Translation = translation };
+ }
+ ///
+ /// 指定された行列から生成する
+ ///
+ ///
+ ///
+ public static SQTTransform FromMatrix(Matrix matrix)
+ {
+ // 行列の分解
+ Quaternion rotation;
+ Vector3 translation;
+ Vector3 scale;
+ matrix.Decompose(out scale, out rotation, out translation);
+
+
+ return new SQTTransform(scale, rotation, translation);
+ }
+
+ ///
+ /// SQTTransformの乗算
+ ///
+ public static void Multiply(ref SQTTransform value1, ref SQTTransform value2, out SQTTransform result)
+ {
+ result = new SQTTransform();
+ // 平行移動の算出
+ // 拡大→回転
+ Vector3 temp = new Vector3();
+ Vector3 newTranslation;
+ temp.X = value1.Translation.X * value2.Scales.X;
+ temp.Y = value1.Translation.Y * value2.Scales.Y;
+ temp.Z = value1.Translation.Z * value2.Scales.Z;
+ Vector3.Transform(ref temp, ref value2.Rotation, out newTranslation);
+
+ newTranslation.X += value2.Translation.X;
+ newTranslation.Y += value2.Translation.Y;
+ newTranslation.Z += value2.Translation.Z;
+
+ // 回転部分の結合(回転と拡大は独立だったはず……)
+ Quaternion.Multiply(ref value1.Rotation, ref value2.Rotation,
+ out result.Rotation);
+ //拡大部分の結合
+ result.Scales.X = value1.Scales.X * value2.Scales.X;
+ result.Scales.Y = value1.Scales.Y * value2.Scales.Y;
+ result.Scales.Z = value1.Scales.Z * value2.Scales.Z;
+ result.Translation = newTranslation;
+ }
+ internal Matrix CreateMatrix()
+ {
+ Matrix result;
+ CreateMatrix(out result);
+ return result;
+ }
+ ///
+ /// マトリックスの生成
+ ///
+ /// マトリックス
+ public void CreateMatrix(out Matrix result)
+ {
+ Matrix scales;
+ Matrix move;
+ Matrix rot;
+ Matrix temp;
+
+ Matrix.CreateScale(ref Scales, out scales);
+ Matrix.CreateTranslation(ref Translation, out move);
+ Matrix.CreateFromQuaternion(Rotation, out rot);
+ Matrix.Multiply(ref scales, ref rot, out temp);
+ Matrix.Multiply(ref temp, ref move, out result);
+
+ }
+
+#if false
+ ///
+ /// 恒等SQTTransformを返します
+ ///
+ public static SQTTransform Identity { get { return new SQTTransform(new Vector3(1, 1, 1), Quaternion.Identity, Vector3.Zero); } }
+ #region 初期化
+
+
+
+
+
+ #endregion
+
+
+
+ ///
+ /// 姿勢の線形補間
+ ///
+ /// 姿勢1
+ /// 姿勢2
+ /// 補完係数(0-1)
+ /// 線形補間された姿勢
+ /// Quaternionは球状線形補間を使用
+ internal static void Lerp(ref SQTTransform pose1, ref SQTTransform pose2, float amount, out SQTTransform result)
+ {
+ Vector3.Lerp(ref pose1.Scales, ref pose2.Scales, amount, out result.Scales);
+ Vector3.Lerp(ref pose1.Translation, ref pose2.Translation, amount, out result.Translation);
+ Quaternion.Slerp(ref pose1.Rotation, ref pose2.Rotation, amount, out result.Rotation);
+ }
+
+#endif
+
+
+
+
+ }
+}
\ No newline at end of file
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerLibrary/Misc/Vector2.cs b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerLibrary/Misc/Vector2.cs
new file mode 100644
index 000000000..72f4c7569
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerLibrary/Misc/Vector2.cs
@@ -0,0 +1,17 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace MMDIKBakerLibrary.Misc
+{
+ struct Vector2
+ {
+ public float X;
+ public float Y;
+ public Vector2(float x, float y)
+ {
+ X = x;
+ Y = y;
+ }
+ }
+}
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerLibrary/Misc/Vector3.cs b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerLibrary/Misc/Vector3.cs
new file mode 100644
index 000000000..0206d51d9
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerLibrary/Misc/Vector3.cs
@@ -0,0 +1,120 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace MMDIKBakerLibrary.Misc
+{
+ struct Vector3
+ {
+ public decimal X;
+ public decimal Y;
+ public decimal Z;
+ public bool NaN;
+ public static Vector3 Zero { get { return new Vector3(); } }
+ public static Vector3 One { get { return new Vector3(1, 1, 1); } }
+
+ public Vector3(decimal x, decimal y, decimal z)
+ {
+ X = x;
+ Y = y;
+ Z = z;
+ NaN = false;
+ }
+
+ public static void Lerp(ref Vector3 value1, ref Vector3 value2, decimal amount, out Vector3 result)
+ {
+ result.X = value1.X + (value2.X - value1.X) * amount;
+ result.Y = value1.Y + (value2.Y - value1.Y) * amount;
+ result.Z = value1.Z + (value2.Z - value1.Z) * amount;
+ result.NaN = false;
+ }
+
+ public decimal Length()
+ {
+ return (decimal)Math.Sqrt((double)(X * X + Y * Y + Z * Z));
+ }
+
+ public static void Transform(ref Vector3 value, ref Quaternion rotation, out Vector3 result)
+ {
+ decimal xx = rotation.X * rotation.X * 2m;
+ decimal xy = rotation.X * rotation.Y * 2m;
+ decimal xz = rotation.X * rotation.Z * 2m;
+ decimal xw = rotation.W * rotation.X * 2m;
+ decimal yy = rotation.Y * rotation.Y * 2m;
+ decimal yz = rotation.Y * rotation.Z * 2m;
+ decimal yw = rotation.W * rotation.Y * 2m;
+ decimal zz = rotation.Z * rotation.Z * 2m;
+ decimal zw = rotation.W * rotation.Z * 2m;
+ result.X = value.X * (1 - yy - zz) + value.Y * (xy - zw) + value.Z * (xz + yw);
+ result.Y = value.X * (xy + zw) + value.Y * (1 - xx - zz) + value.Z * (yz - xw);
+ result.Z = value.X * (xz - yw) + value.Y * (yz + xw) + value.Z * (1 - xx - yy);
+ result.NaN = false;
+ }
+
+
+
+ public static Vector3 Normalize(Vector3 value)
+ {
+ decimal len2 = value.X * value.X + value.Y * value.Y + value.Z * value.Z;
+ Vector3 result;
+ if (len2 == 0)
+ {
+ result.X = 0;
+ result.Y = 0;
+ result.Z = 0;
+ result.NaN = true;
+ return result;
+ }
+ else
+ {
+ result.X = value.X / (decimal)Math.Sqrt((double)len2);
+ result.Y = value.Y / (decimal)Math.Sqrt((double)len2);
+ result.Z = value.Z / (decimal)Math.Sqrt((double)len2);
+ result.NaN = false;
+ return result;
+ }
+ }
+
+ public static decimal Dot(Vector3 vector1, Vector3 vector2)
+ {
+ return vector1.X * vector2.X + vector1.Y * vector2.Y + vector1.Z * vector2.Z;
+ }
+
+ public static Vector3 Cross(Vector3 vector1, Vector3 vector2)
+ {
+ Vector3 result;
+ result.X = vector1.Y * vector2.Z - vector1.Z * vector2.Y;
+ result.Y = vector1.Z * vector2.X - vector1.X * vector2.Z;
+ result.Z = vector1.X * vector2.Y - vector1.Y * vector2.X;
+ result.NaN = false;
+ return result;
+ }
+
+
+
+ public static void Transform(ref Vector3 position, ref Matrix matrix, out Vector3 result)
+ {
+ result.X = position.X * matrix.M11 + position.Y * matrix.M21 + position.Z * matrix.M31 + matrix.M41;
+ result.Y = position.X * matrix.M12 + position.Y * matrix.M22 + position.Z * matrix.M32 + matrix.M42;
+ result.Z = position.X * matrix.M13 + position.Y * matrix.M23 + position.Z * matrix.M33 + matrix.M43;
+ result.NaN = false;
+ }
+
+
+
+ public void Normalize()
+ {
+ decimal len2 = X * X + Y * Y + Z * Z;
+ if (len2 == 0)
+ {
+ NaN = true;
+ }
+ else
+ {
+ X /= (decimal)Math.Sqrt((double)len2);
+ Y /= (decimal)Math.Sqrt((double)len2);
+ Z /= (decimal)Math.Sqrt((double)len2);
+ }
+ }
+ }
+}
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerLibrary/Model/MMDBone.cs b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerLibrary/Model/MMDBone.cs
new file mode 100644
index 000000000..bdea19e18
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerLibrary/Model/MMDBone.cs
@@ -0,0 +1,58 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using MMDIKBakerLibrary.Misc;
+
+namespace MMDIKBakerLibrary.Model
+{
+ class MMDBone
+ {
+ ///
+ /// ボーンの名前
+ ///
+ public readonly string Name;
+
+ ///
+ /// ボーンのバインドポーズ行列
+ ///
+ public readonly SQTTransform BindPose;
+ ///
+ /// ボーンのバインドポーズ逆行列
+ ///
+ /// 変更しないこと……
+ public Matrix InverseBindPose;
+ ///
+ /// ボーンの親のボーンのインデックス情報
+ ///
+ /// 親が無い場合は-1
+ public readonly int SkeletonHierarchy;
+
+ ///
+ /// ボーンのローカル変換行列
+ ///
+ /// アニメーション再生時にはアニメーションにより上書きされる
+ public SQTTransform LocalTransform;
+
+ ///
+ /// ボーンのグローバル変換行列
+ ///
+ /// 毎フレームごとにLocalTransformから計算され、上書きされる
+ public Matrix GlobalTransform;
+ ///
+ /// コンストラクタ
+ ///
+ /// 名前
+ /// バインドポーズ
+ /// 逆バインドポーズ
+ /// 親ボーン番号
+ public MMDBone(string name, SQTTransform bindPose, Matrix inverseBindPose, int skeletonHierarchy)
+ {
+ Name = name;
+ BindPose = bindPose;
+ InverseBindPose = inverseBindPose;
+ SkeletonHierarchy = skeletonHierarchy;
+ LocalTransform = bindPose;
+ GlobalTransform = Matrix.Identity;
+ }
+ }
+}
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerLibrary/Model/MMDBoneManager.cs b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerLibrary/Model/MMDBoneManager.cs
new file mode 100644
index 000000000..5029936f6
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerLibrary/Model/MMDBoneManager.cs
@@ -0,0 +1,153 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using MMDIKBakerLibrary.Motion;
+using MMDIKBakerLibrary.Misc;
+
+namespace MMDIKBakerLibrary.Model
+{
+ class MMDBoneManager
+ {
+ public IIKSolver IKSolver = new CCDSolver();
+ public IIKLimitter IKLimitter = new DefaltIKLimitter();
+ private List bones;
+ private List iks;
+ private Dictionary ik_dict = new Dictionary();
+ Dictionary boneDic;
+ ///
+ /// ボーン取得
+ ///
+ /// ボーン番号
+ /// ボーンオブジェクト
+ public MMDBone this[int index] { get { return bones[index]; } }
+ ///
+ /// ボーン取得
+ ///
+ /// ボーン名
+ /// ボーンオブジェクト
+ public MMDBone this[string key] { get { return bones[boneDic[key]]; } }
+ ///
+ /// ボーン数
+ ///
+ public int Count { get { return bones.Count; } }
+
+ public MMDBoneManager(List bones, List iks)
+ {
+ this.bones = bones;
+ this.iks = iks;
+ boneDic = new Dictionary();
+ for (int i = 0; i < bones.Count; i++)
+ {
+ boneDic.Add(bones[i].Name, i);
+ }
+ foreach (MMDBone bone in bones)
+ {
+ ik_dict[bone.Name] = false;
+ }
+ foreach (MMDIK ik in iks)
+ {
+ foreach (MMDBone ikchild in ik.IKChildBones)
+ {
+ ik_dict[ikchild.Name] = true;
+ }
+ }
+ }
+
+ public bool IsUnderIK(string boneName)
+ {
+ bool result;
+ if (!ik_dict.TryGetValue(boneName, out result))
+ {
+ return false;
+ }
+ return result;
+ }
+ ///
+ /// グローバルトランスフォームの更新
+ ///
+ public virtual void CalcGlobalTransform()
+ {
+ bones[0].LocalTransform.CreateMatrix(out bones[0].GlobalTransform);
+ for (int i = 1; i < bones.Count; ++i)
+ {
+ int parentBone = bones[i].SkeletonHierarchy;
+ Matrix local;
+ bones[i].LocalTransform.CreateMatrix(out local);
+ if (parentBone > bones.Count)
+ {
+ bones[i].GlobalTransform = local;
+ }
+ else
+ {
+ Matrix.Multiply(ref local, ref bones[parentBone].GlobalTransform, out bones[i].GlobalTransform);
+ }
+ }
+ }
+ ///
+ /// IK計算
+ ///
+ public virtual void CalcIK()
+ {
+ bool UpdateFlag = false;
+ for (int i = 0; i < iks.Count; ++i)
+ {
+ if (IKSolver.Solve(iks[i], this))
+ UpdateFlag = true;
+ }
+ if (UpdateFlag)
+ CalcGlobalTransform();
+ }
+ public void bake(uint frameNo, MMDMotion afterMotion)
+ {
+ foreach (KeyValuePair it in ik_dict)
+ {
+ if (it.Value && afterMotion.BoneFrames.ContainsKey(it.Key))
+ {
+ Matrix globalTrans = this[it.Key].GlobalTransform;
+ Matrix parentTrans, invParentTrans;
+ if (this[it.Key].SkeletonHierarchy >= bones.Count)
+ {
+ parentTrans = Matrix.Identity;
+ }
+ else
+ {
+ parentTrans = this[this[it.Key].SkeletonHierarchy].GlobalTransform;
+ }
+ Matrix.Invert(ref parentTrans, out invParentTrans);
+ Matrix LocalTrans;
+ Matrix.Multiply(ref globalTrans, ref invParentTrans, out LocalTrans);
+ Matrix BindPose = this[it.Key].BindPose.CreateMatrix();
+ Matrix invBindPose;
+ Matrix.Invert(ref BindPose, out invBindPose);
+ Matrix subPose;
+ Vector3 scale, Location;
+ Quaternion quaternion;
+ Matrix.Multiply(ref LocalTrans, ref invBindPose, out subPose);
+ subPose.Decompose(out scale, out quaternion, out Location);
+ MMDBoneKeyFrame keyframe = new MMDBoneKeyFrame();
+ if (afterMotion.BoneFrames[it.Key].Count == 0 && frameNo > 0)
+ {
+ keyframe.FrameNo = 0;
+ keyframe.BoneName = it.Key;
+ keyframe.Curve = MathHelper.CreateIdentityCurve();
+ keyframe.Location = Location;
+ keyframe.Quatanion = quaternion;
+ keyframe.Scales = scale;
+ afterMotion.BoneFrames[it.Key].Add(keyframe);
+ keyframe = new MMDBoneKeyFrame();
+ }
+ keyframe.FrameNo = frameNo;
+ keyframe.BoneName = it.Key;
+ keyframe.Curve = MathHelper.CreateIdentityCurve();
+ keyframe.Location = Location;
+ keyframe.Quatanion = quaternion;
+ keyframe.Scales = scale;
+ afterMotion.BoneFrames[it.Key].Add(keyframe);
+ }
+ }
+
+
+
+ }
+ }
+}
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerLibrary/Model/MMDIK.cs b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerLibrary/Model/MMDIK.cs
new file mode 100644
index 000000000..3b4485791
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerLibrary/Model/MMDIK.cs
@@ -0,0 +1,50 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace MMDIKBakerLibrary.Model
+{
+ class MMDIK
+ {
+ ///
+ /// 目標位置となるボーン
+ ///
+ public MMDBone IKBone { get; internal set; }
+ ///
+ /// エフェクタとなるボーン
+ ///
+ public MMDBone IKTargetBone { get; internal set; }
+ ///
+ /// 再帰演算回数
+ ///
+ public readonly UInt16 Iteration;
+ ///
+ /// IKの影響度
+ ///
+ public readonly float ControlWeight;
+ ///
+ /// IK影響下のボーン
+ ///
+ public List IKChildBones { get; internal set; }
+
+ internal int IKBoneIndex;
+ internal int IKTargetBoneIndex;
+ internal List ikChildBoneIndex;
+ ///
+ /// コンストラクタ
+ ///
+ /// IKボーンとなるボーン
+ /// エフェクタとなるボーン
+ /// 再帰演算回数
+ /// IKの影響度
+ /// IK影響下のボーン
+ public MMDIK(int ikBoneIndex, int iktargetindex, UInt16 iteration, float controlWeight, List ikChildBones)
+ {
+ IKBoneIndex = ikBoneIndex;
+ IKTargetBoneIndex = iktargetindex;
+ Iteration = iteration;
+ ControlWeight = controlWeight;
+ ikChildBoneIndex = ikChildBones;
+ }
+ }
+}
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerLibrary/Model/ModelConverter.cs b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerLibrary/Model/ModelConverter.cs
new file mode 100644
index 000000000..226ed8408
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerLibrary/Model/ModelConverter.cs
@@ -0,0 +1,70 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using MMDIKBakerLibrary.Misc;
+
+namespace MMDIKBakerLibrary.Model
+{
+ static class ModelConverter
+ {
+ public static MMDBoneManager BuildBoneManager(MikuMikuDance.Model.Ver1.MMDModel1 model)
+ {
+ List bones;
+ List iks;
+ bones = new List();
+ iks = new List();
+ Matrix[] absPoses = new Matrix[model.Bones.LongLength];
+ //各ボーンの絶対座標を計算
+ for (long i = 0; i < model.Bones.LongLength; ++i)
+ {
+ Matrix.CreateTranslation((decimal)model.Bones[i].BoneHeadPos[0],
+ (decimal)model.Bones[i].BoneHeadPos[1],
+ (decimal)model.Bones[i].BoneHeadPos[2],
+ out absPoses[i]);
+ }
+ for (long i = 0; i < model.Bones.LongLength; ++i)
+ {
+ Matrix localMatrix;
+ if (model.Bones[i].ParentBoneIndex != 0xffff)
+ {
+ Matrix parentInv;
+ Matrix.Invert(ref absPoses[model.Bones[i].ParentBoneIndex], out parentInv);
+ Matrix.Multiply(ref parentInv, ref absPoses[i], out localMatrix);
+ }
+ else
+ {
+ localMatrix = absPoses[i];
+ }
+ SQTTransform bindPose = SQTTransform.FromMatrix(localMatrix);
+ Matrix inverseBindPose;
+ Matrix.Invert(ref absPoses[i], out inverseBindPose);
+ bones.Add(new MMDBone(model.Bones[i].BoneName, bindPose, inverseBindPose, model.Bones[i].ParentBoneIndex));
+ }
+ for (long i = 0; i < model.IKs.LongLength; ++i)
+ {
+ List ikChildBones = new List();
+ foreach (var ikc in model.IKs[i].IKChildBoneIndex)
+ ikChildBones.Add(ikc);
+ iks.Add(new MMDIK(model.IKs[i].IKBoneIndex, model.IKs[i].IKTargetBoneIndex, model.IKs[i].Iterations, model.IKs[i].AngleLimit, ikChildBones));
+ }
+ //ボーンインデックス→ボーンオブジェクト化
+ IKSetup(iks, bones);
+ return new MMDBoneManager(bones, iks);
+ }
+ ///
+ /// ボーンインデックス→ボーンオブジェクト化
+ ///
+ public static void IKSetup(List iks, List bones)
+ {
+ foreach (var ik in iks)
+ {
+ ik.IKBone = bones[ik.IKBoneIndex];
+ ik.IKTargetBone = bones[ik.IKTargetBoneIndex];
+ List ikchilds = new List();
+ foreach (var ikci in ik.ikChildBoneIndex)
+ ikchilds.Add(bones[ikci]);
+ ik.IKChildBones = new List(ikchilds);
+ }
+ }
+ }
+}
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerLibrary/Motion/AnimationPlayer.cs b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerLibrary/Motion/AnimationPlayer.cs
new file mode 100644
index 000000000..0fefea100
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerLibrary/Motion/AnimationPlayer.cs
@@ -0,0 +1,50 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using MMDIKBakerLibrary.Model;
+using MMDIKBakerLibrary.Misc;
+
+namespace MMDIKBakerLibrary.Motion
+{
+ class AnimationPlayer
+ {
+ private MMDBoneManager boneManager;
+ private MMDMotionTrack motionTrack;
+ private Dictionary resultPoses = new Dictionary();
+ private List underIKBones = new List();
+ Dictionary BindPoses;
+ public AnimationPlayer(MMDBoneManager boneManager)
+ {
+ this.boneManager = boneManager;
+ BindPoses = new Dictionary();
+ for (int i = 0; i < boneManager.Count; ++i)
+ {
+ BindPoses.Add(boneManager[i].Name, boneManager[i].BindPose);
+ }
+ }
+
+ public void SetMotion(MMDMotion motionData)
+ {
+ this.motionTrack = new MMDMotionTrack(motionData);
+ }
+
+ public bool Update()
+ {
+ resultPoses.Clear();
+ bool result = motionTrack.Update();
+ foreach (KeyValuePair subpose in motionTrack.SubPoses)
+ {
+ resultPoses[subpose.Key] = subpose.Value;
+ SQTTransform bindPose, sub = subpose.Value, local;
+ if (BindPoses.TryGetValue(subpose.Key, out bindPose))
+ {
+ SQTTransform.Multiply(ref sub, ref bindPose, out local);
+ boneManager[subpose.Key].LocalTransform = local;
+ }
+ }
+ return result;
+ }
+
+
+ }
+}
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerLibrary/Motion/MMDBoneKeyFrame.cs b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerLibrary/Motion/MMDBoneKeyFrame.cs
new file mode 100644
index 000000000..ec272d006
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerLibrary/Motion/MMDBoneKeyFrame.cs
@@ -0,0 +1,73 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using DWORD = System.UInt32;
+using MMDIKBakerLibrary.Misc;
+
+namespace MMDIKBakerLibrary.Motion
+{
+ class MMDBoneKeyFrame
+ {
+ ///
+ /// ボーン名
+ ///
+ public string BoneName;//[15];
+ ///
+ /// フレーム番号
+ ///
+ public DWORD FrameNo;
+ ///
+ /// スケールベクトル
+ ///
+ public Vector3 Scales;
+ ///
+ /// 位置ベクトル
+ ///
+ public Vector3 Location;
+ ///
+ /// クォータニオン
+ ///
+ public Quaternion Quatanion;
+
+ ///
+ /// 補完用曲線
+ ///
+ /// 順にX,Y,Z,回転
+ public BezierCurve[] Curve;
+
+ ///
+ /// 補完
+ ///
+ /// フレーム1
+ /// フレーム2
+ /// 進行度合い
+ /// 補完結果
+ public static void Lerp(MMDBoneKeyFrame frame1, MMDBoneKeyFrame frame2, decimal Progress, out SQTTransform result)
+ {
+ decimal ProgX, ProgY, ProgZ, ProgR;
+ ProgX = (decimal)frame2.Curve[0].Evaluate((float)Progress);
+ ProgY = (decimal)frame2.Curve[1].Evaluate((float)Progress);
+ ProgZ = (decimal)frame2.Curve[2].Evaluate((float)Progress);
+ ProgR = (decimal)frame2.Curve[3].Evaluate((float)Progress);
+ decimal x, y, z;
+ Quaternion q;
+ Vector3 scales;
+ x = MathHelper.Lerp(frame1.Location.X, frame2.Location.X, ProgX);
+ y = MathHelper.Lerp(frame1.Location.Y, frame2.Location.Y, ProgY);
+ z = MathHelper.Lerp(frame1.Location.Z, frame2.Location.Z, ProgZ);
+ Quaternion.Slerp(ref frame1.Quatanion, ref frame2.Quatanion, ProgR, out q);
+ //MMDはスケールのアニメーションを含まないので、スケールのベジェ曲線計算は行わない
+ Vector3.Lerp(ref frame1.Scales, ref frame2.Scales, Progress, out scales);
+ Vector3 t = new Vector3(x, y, z);
+ SQTTransform.Create(ref scales, ref q, ref t, out result);
+ }
+ ///
+ /// このフレームのSQTトランスフォームを取得
+ ///
+ /// SQLトランスフォーム
+ public void GetSQTTransform(out SQTTransform result)
+ {
+ SQTTransform.Create(ref Scales, ref Quatanion, ref Location, out result);
+ }
+ }
+}
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerLibrary/Motion/MMDFaceKeyFrame.cs b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerLibrary/Motion/MMDFaceKeyFrame.cs
new file mode 100644
index 000000000..bfa33e6b0
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerLibrary/Motion/MMDFaceKeyFrame.cs
@@ -0,0 +1,34 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using MMDIKBakerLibrary.Misc;
+
+namespace MMDIKBakerLibrary.Motion
+{
+ class MMDFaceKeyFrame
+ {
+ ///
+ /// 表情名
+ ///
+ public string FaceName;
+ ///
+ /// フレーム番号
+ ///
+ public uint FrameNo;
+ ///
+ /// 表情適応割合
+ ///
+ public float Rate;
+ ///
+ /// 表情の補完
+ ///
+ /// フレーム1
+ /// フレーム2
+ /// 進行度合い
+ /// 表情適用量
+ public static float Lerp(MMDFaceKeyFrame frame1, MMDFaceKeyFrame frame2, float progress)
+ {
+ return MathHelper.Lerp(frame1.Rate, frame2.Rate, progress);
+ }
+ }
+}
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerLibrary/Motion/MMDMotion.cs b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerLibrary/Motion/MMDMotion.cs
new file mode 100644
index 000000000..f07166dc8
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerLibrary/Motion/MMDMotion.cs
@@ -0,0 +1,20 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace MMDIKBakerLibrary.Motion
+{
+ class MMDMotion
+ {
+ ///
+ /// ボーンモーションデータ
+ ///
+ /// ボーンごとに時系列順
+ public Dictionary> BoneFrames;
+ ///
+ /// フェイスモーションデータ
+ ///
+ /// 表情ごとに時系列順
+ public Dictionary> FaceFrames;
+ }
+}
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerLibrary/Motion/MMDMotionTrack.cs b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerLibrary/Motion/MMDMotionTrack.cs
new file mode 100644
index 000000000..be0e142f3
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerLibrary/Motion/MMDMotionTrack.cs
@@ -0,0 +1,95 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using MMDIKBakerLibrary.Misc;
+
+namespace MMDIKBakerLibrary.Motion
+{
+ class MMDMotionTrack
+ {
+ ///
+ /// デフォルトモーション再生FPS
+ ///
+ public const decimal DefaultFPS = 30m;
+ decimal m_NowFrame = 0;
+ decimal m_MaxFrame = 0;
+ //モーションデータ
+ Dictionary> boneFrames;
+ //モーションデータの読み出し位置
+ Dictionary bonePos = new Dictionary();
+ //トラックから抽出されたボーンの差分一覧
+ Dictionary subPoses;
+ ///
+ /// モーション再生用FPS
+ ///
+ public decimal FramePerSecond { get; set; }
+ ///
+ /// 現在のボーン差分一覧
+ ///
+ public Dictionary SubPoses { get { return subPoses; } }
+
+ public MMDMotionTrack(MMDMotion motionData)
+ {
+ //ボーンの配列抜き出し
+ boneFrames = motionData.BoneFrames;
+ //モーションのFPS=30
+ FramePerSecond = DefaultFPS;
+ //差分一覧を作成
+ subPoses = new Dictionary(motionData.BoneFrames.Count);
+ //現在の再生位置を設定&最大フレーム数のチェック
+ foreach (KeyValuePair> it in motionData.BoneFrames)
+ {
+ bonePos.Add(it.Key, 0);
+ foreach (MMDBoneKeyFrame it2 in it.Value)
+ {
+ if (it2.FrameNo > m_MaxFrame)
+ m_MaxFrame = it2.FrameNo;
+ }
+ }
+ }
+
+ //終了したらfalseを返す
+ public bool Update()
+ {
+ bool result = !TimeUpdate();
+ SubPoses.Clear();
+ //ボーンの更新
+ foreach (KeyValuePair> frameList in boneFrames)
+ {
+ //カーソル位置の更新
+ int CursorPos = bonePos[frameList.Key];
+ for (; CursorPos < frameList.Value.Count && frameList.Value[CursorPos].FrameNo < m_NowFrame; ++CursorPos) ;
+ for (; CursorPos > 0 && frameList.Value[CursorPos - 1].FrameNo > m_NowFrame; --CursorPos) ;
+ bonePos[frameList.Key] = CursorPos;
+ if (CursorPos == frameList.Value.Count)
+ {//通常再生時の最終フレーム
+ SQTTransform subPose;
+ frameList.Value[CursorPos - 1].GetSQTTransform(out subPose);
+ SubPoses.Add(frameList.Key, subPose);
+ }
+ else
+ {
+ //時間経過取得
+ decimal Progress = (m_NowFrame - frameList.Value[CursorPos - 1].FrameNo) / (frameList.Value[CursorPos].FrameNo - frameList.Value[CursorPos - 1].FrameNo);
+ SQTTransform subPose;
+ MMDBoneKeyFrame pose1 = frameList.Value[CursorPos - 1], pose2 = frameList.Value[CursorPos];
+ MMDBoneKeyFrame.Lerp(pose1, pose2, Progress, out subPose);
+ SubPoses.Add(frameList.Key, subPose);
+ }
+ }
+ return result;
+ }
+ private bool TimeUpdate()
+ {
+ decimal elapsedSeconds = 1m / 30m;
+ bool result = false;
+ m_NowFrame += elapsedSeconds * FramePerSecond;
+ if (m_NowFrame > m_MaxFrame)
+ {
+ result = true;
+ m_NowFrame = m_MaxFrame;
+ }
+ return result;
+ }
+ }
+}
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerLibrary/Motion/MotionConverter.cs b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerLibrary/Motion/MotionConverter.cs
new file mode 100644
index 000000000..fd53176fb
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerLibrary/Motion/MotionConverter.cs
@@ -0,0 +1,104 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using MMDIKBakerLibrary.Misc;
+
+namespace MMDIKBakerLibrary.Motion
+{
+ static class MotionConverter
+ {
+ internal static MMDMotion Convert(MikuMikuDance.Motion.Motion2.MMDMotion2 input)
+ {
+ MMDMotion result = new MMDMotion();
+ //ボーンモーションデータの変換
+ MMDBoneKeyFrame[] BoneFrames = new MMDBoneKeyFrame[input.Motions.LongLength];
+ for (long i = 0; i < input.Motions.LongLength; i++)
+ {
+ BoneFrames[i] = new MMDBoneKeyFrame();
+ BoneFrames[i].BoneName = input.Motions[i].BoneName;
+ BoneFrames[i].FrameNo = input.Motions[i].FrameNo;
+
+ BoneFrames[i].Curve = new BezierCurve[4];
+ for (int j = 0; j < BoneFrames[i].Curve.Length; j++)
+ {
+ BezierCurve curve = new BezierCurve();
+ curve.v1 = new Vector2((float)input.Motions[i].Interpolation[0][0][j] / 128f, (float)input.Motions[i].Interpolation[0][1][j] / 128f);
+ curve.v2 = new Vector2((float)input.Motions[i].Interpolation[0][2][j] / 128f, (float)input.Motions[i].Interpolation[0][3][j] / 128f);
+ BoneFrames[i].Curve[j] = curve;
+ }
+ BoneFrames[i].Scales = new Vector3(1, 1, 1);
+ BoneFrames[i].Location = new Vector3((decimal)input.Motions[i].Location[0], (decimal)input.Motions[i].Location[1], (decimal)input.Motions[i].Location[2]);
+ BoneFrames[i].Quatanion = new Quaternion((decimal)input.Motions[i].Quatanion[0], (decimal)input.Motions[i].Quatanion[1], (decimal)input.Motions[i].Quatanion[2], (decimal)input.Motions[i].Quatanion[3]);
+ BoneFrames[i].Quatanion.Normalize();
+ }
+ result.BoneFrames = MotionHelper.SplitBoneMotion(BoneFrames);
+ //表情モーションの変換
+ MMDFaceKeyFrame[] FaceFrames = new MMDFaceKeyFrame[input.FaceMotions.LongLength];
+ for (long i = 0; i < input.FaceMotions.Length; i++)
+ {
+ FaceFrames[i] = new MMDFaceKeyFrame();
+ FaceFrames[i].Rate = input.FaceMotions[i].Rate;
+ FaceFrames[i].FaceName = input.FaceMotions[i].FaceName;
+ FaceFrames[i].FrameNo = input.FaceMotions[i].FrameNo;
+ float temp = input.FaceMotions[i].FrameNo;
+ }
+ result.FaceFrames = MotionHelper.SplitFaceMotion(FaceFrames);
+ //カメラモーションは無視(使わんので)
+ //ライトモーションは無視(使わんので)
+ //変換したデータを返却
+ return result;
+ }
+
+ public static MikuMikuDance.Motion.Motion2.MMDMotion2 Convert(MMDMotion input, string modelName)
+ {
+ MikuMikuDance.Motion.Motion2.MMDMotion2 result = new MikuMikuDance.Motion.Motion2.MMDMotion2();
+ result.ModelName = modelName;
+ result.Coordinate = MikuMikuDance.Motion.CoordinateType.RightHandedCoordinate;
+ //ボーンモーションデータの変換
+ MMDBoneKeyFrame[] BoneFrames= MotionHelper.ImplodeBoneMotion(input.BoneFrames);
+ MikuMikuDance.Motion.Motion2.MotionData[] BoneMotionData = new MikuMikuDance.Motion.Motion2.MotionData[BoneFrames.LongLength];
+ for (long i = 0; i < BoneFrames.LongLength; i++)
+ {
+ BoneMotionData[i] = new MikuMikuDance.Motion.Motion2.MotionData();
+ BoneMotionData[i].BoneName = BoneFrames[i].BoneName;
+ BoneMotionData[i].FrameNo = BoneFrames[i].FrameNo;
+
+ for (int j = 0; j < BoneFrames[i].Curve.Length; j++)
+ {
+ BoneMotionData[i].Interpolation[0][0][j]=(byte)MathHelper.Clamp(BoneFrames[i].Curve[j].v1.X*128f,0,255);
+ BoneMotionData[i].Interpolation[0][1][j]=(byte)MathHelper.Clamp(BoneFrames[i].Curve[j].v1.Y*128f,0,255);
+ BoneMotionData[i].Interpolation[0][2][j]=(byte)MathHelper.Clamp(BoneFrames[i].Curve[j].v2.X*128f,0,255);
+ BoneMotionData[i].Interpolation[0][3][j]=(byte)MathHelper.Clamp(BoneFrames[i].Curve[j].v2.Y*128f,0,255);
+ }
+
+ BoneMotionData[i].Location[0] = (float)BoneFrames[i].Location.X;
+ BoneMotionData[i].Location[1] = (float)BoneFrames[i].Location.Y;
+ BoneMotionData[i].Location[2] = (float)BoneFrames[i].Location.Z;
+
+ BoneFrames[i].Quatanion.Normalize();
+ BoneMotionData[i].Quatanion[0] = (float)BoneFrames[i].Quatanion.X;
+ BoneMotionData[i].Quatanion[1] = (float)BoneFrames[i].Quatanion.Y;
+ BoneMotionData[i].Quatanion[2] = (float)BoneFrames[i].Quatanion.Z;
+ BoneMotionData[i].Quatanion[3] = (float)BoneFrames[i].Quatanion.W;
+ }
+ result.Motions = BoneMotionData;
+ //表情モーションの変換
+ MMDFaceKeyFrame[] FaceFrames = MotionHelper.ImplodeFaceMotion(input.FaceFrames);
+ MikuMikuDance.Motion.Motion2.FaceMotionData[] FaceMotionData = new MikuMikuDance.Motion.Motion2.FaceMotionData[FaceFrames.LongLength];
+ for (long i = 0; i < FaceFrames.LongLength; i++)
+ {
+ FaceMotionData[i] = new MikuMikuDance.Motion.Motion2.FaceMotionData();
+ FaceMotionData[i].Rate = FaceFrames[i].Rate;
+ FaceMotionData[i].FaceName = FaceFrames[i].FaceName;
+ FaceMotionData[i].FrameNo = FaceFrames[i].FrameNo;
+ }
+ result.FaceMotions = FaceMotionData;
+ //カメラモーションは無視(使わんので)
+ result.CameraMotions = new MikuMikuDance.Motion.Motion2.CameraMotionData[0];
+ //ライトモーションは無視(使わんので)
+ result.LightMotions = new MikuMikuDance.Motion.Motion2.LightMotionData[0];
+
+ return result;
+ }
+ }
+}
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerLibrary/Motion/MotionHelper.cs b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerLibrary/Motion/MotionHelper.cs
new file mode 100644
index 000000000..97dccab6c
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerLibrary/Motion/MotionHelper.cs
@@ -0,0 +1,103 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace MMDIKBakerLibrary.Motion
+{
+ static class MotionHelper
+ {
+ internal static Dictionary> SplitBoneMotion(MMDBoneKeyFrame[] keyframes)
+ {
+ Dictionary> result = new Dictionary>();
+ foreach (var keyframe in keyframes)
+ {
+ if (!result.ContainsKey(keyframe.BoneName))
+ result.Add(keyframe.BoneName, new List());
+ result[keyframe.BoneName].Add(keyframe);
+ }
+ foreach (var boneframes in result)
+ {
+ boneframes.Value.Sort((x, y) => (int)((long)x.FrameNo - (long)y.FrameNo));
+ }
+ return result;
+ }
+
+ internal static Dictionary> SplitFaceMotion(MMDFaceKeyFrame[] keyframes)
+ {
+ Dictionary> result = new Dictionary>();
+ foreach (var keyframe in keyframes)
+ {
+ if (!result.ContainsKey(keyframe.FaceName))
+ result.Add(keyframe.FaceName, new List());
+ result[keyframe.FaceName].Add(keyframe);
+ }
+ foreach (var boneframes in result)
+ {
+ boneframes.Value.Sort((x, y) => (int)((long)x.FrameNo - (long)y.FrameNo));
+ }
+ return result;
+ }
+
+ internal static MMDBoneKeyFrame[] ImplodeBoneMotion(Dictionary> keyframes)
+ {
+ List result = new List();
+ Dictionary> iterators = new Dictionary>();
+ foreach (KeyValuePair> keyframe in keyframes)
+ {
+ iterators.Add(keyframe.Key, keyframe.Value.GetEnumerator());
+ iterators[keyframe.Key].MoveNext();
+ }
+ List endKeys = new List();
+ for (uint frame = 0; iterators.Count > 0; ++frame)
+ {
+ foreach (KeyValuePair> it in iterators)
+ {
+ if (it.Value.Current.FrameNo <= frame)
+ {
+ result.Add(it.Value.Current);
+ if (!it.Value.MoveNext())
+ {
+ endKeys.Add(it.Key);
+ }
+ }
+ }
+ foreach (string key in endKeys)
+ {
+ iterators.Remove(key);
+ }
+ }
+ return result.ToArray();
+ }
+
+ internal static MMDFaceKeyFrame[] ImplodeFaceMotion(Dictionary> keyframes)
+ {
+ List result = new List();
+ Dictionary> iterators = new Dictionary>();
+ foreach (KeyValuePair> keyframe in keyframes)
+ {
+ iterators.Add(keyframe.Key, keyframe.Value.GetEnumerator());
+ iterators[keyframe.Key].MoveNext();
+ }
+ List endKeys = new List();
+ for (uint frame = 0; iterators.Count > 0; ++frame)
+ {
+ foreach (KeyValuePair> it in iterators)
+ {
+ if (it.Value.Current.FrameNo <= frame)
+ {
+ result.Add(it.Value.Current);
+ if (!it.Value.MoveNext())
+ {
+ endKeys.Add(it.Key);
+ }
+ }
+ }
+ foreach (string key in endKeys)
+ {
+ iterators.Remove(key);
+ }
+ }
+ return result.ToArray();
+ }
+ }
+}
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerLibrary/Properties/AssemblyInfo.cs b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerLibrary/Properties/AssemblyInfo.cs
new file mode 100644
index 000000000..6c5b10e0f
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerLibrary/Properties/AssemblyInfo.cs
@@ -0,0 +1,38 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// アセンブリに関する一般情報は以下の属性セットをとおして制御されます。
+// アセンブリに関連付けられている情報を変更するには、
+// これらの属性値を変更してください。
+[assembly: AssemblyTitle("MMDBoneBakerLibrary")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("MMDBoneBakerLibrary")]
+[assembly: AssemblyCopyright("Copyright © 2011")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// ComVisible を false に設定すると、その型はこのアセンブリ内で COM コンポーネントから
+// 参照不可能になります。COM からこのアセンブリ内の型にアクセスする場合は、
+// その型の ComVisible 属性を true に設定してください。
+[assembly: ComVisible(false)]
+
+// 次の GUID は、このプロジェクトが COM に公開される場合の、typelib の ID です
+[assembly: Guid("912f8a3c-d5c2-421d-8d85-7be2978d4dcf")]
+
+// アセンブリのバージョン情報は、以下の 4 つの値で構成されています:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// すべての値を指定するか、下のように '*' を使ってビルドおよびリビジョン番号を
+// 既定値にすることができます:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
+
+[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("MMDIKBakerTest")]
\ No newline at end of file
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerTest/MatrixTest.cs b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerTest/MatrixTest.cs
new file mode 100644
index 000000000..060521184
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerTest/MatrixTest.cs
@@ -0,0 +1,177 @@
+using MMDIKBakerLibrary.Misc;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using System;
+
+namespace MMDIKBakerTest
+{
+
+
+ ///
+ ///MatrixTest のテスト クラスです。すべての
+ ///MatrixTest 単体テストをここに含めます
+ ///
+ [TestClass()]
+ public class MatrixTest
+ {
+
+
+ private TestContext testContextInstance;
+
+ ///
+ ///現在のテストの実行についての情報および機能を
+ ///提供するテスト コンテキストを取得または設定します。
+ ///
+ public TestContext TestContext
+ {
+ get
+ {
+ return testContextInstance;
+ }
+ set
+ {
+ testContextInstance = value;
+ }
+ }
+
+ #region 追加のテスト属性
+ //
+ //テストを作成するときに、次の追加属性を使用することができます:
+ //
+ //クラスの最初のテストを実行する前にコードを実行するには、ClassInitialize を使用
+ //[ClassInitialize()]
+ //public static void MyClassInitialize(TestContext testContext)
+ //{
+ //}
+ //
+ //クラスのすべてのテストを実行した後にコードを実行するには、ClassCleanup を使用
+ //[ClassCleanup()]
+ //public static void MyClassCleanup()
+ //{
+ //}
+ //
+ //各テストを実行する前にコードを実行するには、TestInitialize を使用
+ //[TestInitialize()]
+ //public void MyTestInitialize()
+ //{
+ //}
+ //
+ //各テストを実行した後にコードを実行するには、TestCleanup を使用
+ //[TestCleanup()]
+ //public void MyTestCleanup()
+ //{
+ //}
+ //
+ #endregion
+
+
+ ///
+ ///Decompose のテスト
+ ///
+ [TestMethod()]
+ public void DecomposeTest()
+ {
+ Vector3 scale;
+ Quaternion rotation;
+ Vector3 translation;
+ Matrix target = new Matrix();
+ Vector3[] scaleTestPatterns = { Vector3.One, new Vector3(5, 1, 1), new Vector3(1, 5, 1), new Vector3(1, 1, 5), new Vector3(5, 5, 1), new Vector3(5, 1, 5), new Vector3(1, 5, 5), new Vector3(5, 5, 5) };
+ Quaternion[] rotationTestPatterns = { Quaternion.Identity, Quaternion.CreateFromAxisAngle(new Vector3(1, 0, 0), 0.72m), Quaternion.CreateFromAxisAngle(new Vector3(0.5m, 0.5m, 0), 0.72m), Quaternion.CreateFromAxisAngle(new Vector3(0, 0.5m, 0.5m), 0.72m) };
+ Vector3[] transrationTestPatterns = { Vector3.Zero, Vector3.One, new Vector3(5, 1, 1), new Vector3(1, 5, 1), new Vector3(1, 1, 5), new Vector3(5, 5, 1), new Vector3(5, 1, 5), new Vector3(1, 5, 5), new Vector3(5, 5, 5) };
+
+ foreach (Vector3 scaleTestPattern in scaleTestPatterns)
+ {
+ foreach (Quaternion rotationTestPattern in rotationTestPatterns)
+ {
+ foreach (Vector3 transrationTestPattern in transrationTestPatterns)
+ {
+ Matrix.Compose(scaleTestPattern, rotationTestPattern, transrationTestPattern, out target);
+ rotationTestPattern.Normalize();
+ target.Decompose(out scale, out rotation, out translation);
+ Vector3 scaleExpected = MathHelper.Round(scaleTestPattern, 5);
+ scale = MathHelper.Round(scale, 5);
+ Quaternion rotationExpected = MathHelper.Round(rotationTestPattern, 5);
+ rotation = MathHelper.Round(rotation, 5);
+ Vector3 translationExpected = MathHelper.Round(transrationTestPattern, 5);
+ translation = MathHelper.Round(translation, 5);
+ Assert.AreEqual(scaleExpected.X, scale.X);
+ Assert.AreEqual(scaleExpected.Y, scale.Y);
+ Assert.AreEqual(scaleExpected.Z, scale.Z);
+ Assert.AreEqual((double)rotationExpected.X, (double)rotation.X);
+ Assert.AreEqual(rotationExpected.Y, rotation.Y);
+ Assert.AreEqual(rotationExpected.Z, rotation.Z);
+ Assert.AreEqual(rotationExpected.W, rotation.W);
+ Assert.AreEqual(translationExpected.X, translation.X);
+ Assert.AreEqual(translationExpected.Y, translation.Y);
+ Assert.AreEqual(translationExpected.Z, translation.Z);
+ }
+ }
+ }
+ }
+
+ ///
+ ///Invert のテスト
+ ///
+ [TestMethod()]
+ public void InvertTest()
+ {
+ Matrix matrix;
+ Matrix result; // TODO: 適切な値に初期化してください
+ Vector3[] scaleTestPatterns = { Vector3.One, new Vector3(5, 1, 1), new Vector3(1, 5, 1), new Vector3(1, 1, 5), new Vector3(5, 5, 1), new Vector3(5, 1, 5), new Vector3(1, 5, 5), new Vector3(5, 5, 5) };
+ Quaternion[] rotationTestPatterns = { Quaternion.Identity, Quaternion.CreateFromAxisAngle(new Vector3(1, 0, 0), 0.72m), Quaternion.CreateFromAxisAngle(new Vector3(0.5m, 0.5m, 0), 0.72m), Quaternion.CreateFromAxisAngle(new Vector3(0, 0.5m, 0.5m), 0.72m) };
+ Vector3[] transrationTestPatterns = { Vector3.Zero, Vector3.One, new Vector3(5, 1, 1), new Vector3(1, 5, 1), new Vector3(1, 1, 5), new Vector3(5, 5, 1), new Vector3(5, 1, 5), new Vector3(1, 5, 5), new Vector3(5, 5, 5) };
+
+ foreach (Vector3 scaleTestPattern in scaleTestPatterns)
+ {
+ foreach (Quaternion rotationTestPattern in rotationTestPatterns)
+ {
+ foreach (Vector3 transrationTestPattern in transrationTestPatterns)
+ {
+ rotationTestPattern.Normalize();
+ Matrix.Compose(scaleTestPattern, rotationTestPattern, transrationTestPattern, out matrix);
+ Matrix temp;
+ Matrix.Invert(ref matrix, out temp);
+ Matrix.Invert(ref temp, out result);
+ matrix = MathHelper.Round(matrix, 5);
+ result = MathHelper.Round(result, 5);
+ Assert.IsTrue(Math.Abs(matrix.M11 - result.M11) < 0.001m);
+ Assert.IsTrue(Math.Abs(matrix.M12 - result.M12) < 0.001m);
+ Assert.IsTrue(Math.Abs(matrix.M13 - result.M13) < 0.001m);
+ Assert.IsTrue(Math.Abs(matrix.M14 - result.M14) < 0.001m);
+ Assert.IsTrue(Math.Abs(matrix.M21 - result.M21) < 0.001m);
+ Assert.IsTrue(Math.Abs(matrix.M22 - result.M22) < 0.001m);
+ Assert.IsTrue(Math.Abs(matrix.M23 - result.M23) < 0.001m);
+ Assert.IsTrue(Math.Abs(matrix.M24 - result.M24) < 0.001m);
+ Assert.IsTrue(Math.Abs(matrix.M31 - result.M31) < 0.001m);
+ Assert.IsTrue(Math.Abs(matrix.M32 - result.M32) < 0.001m);
+ Assert.IsTrue(Math.Abs(matrix.M33 - result.M33) < 0.001m);
+ Assert.IsTrue(Math.Abs(matrix.M34 - result.M34) < 0.001m);
+ Assert.IsTrue(Math.Abs(matrix.M41 - result.M41) < 0.001m);
+ Assert.IsTrue(Math.Abs(matrix.M42 - result.M42) < 0.001m);
+ Assert.IsTrue(Math.Abs(matrix.M43 - result.M43) < 0.001m);
+ Assert.IsTrue(Math.Abs(matrix.M44 - result.M44) < 0.001m);
+ Matrix.Multiply(ref temp, ref matrix, out result);
+ matrix = Matrix.Identity;
+ result = MathHelper.Round(result, 5);
+ Assert.IsTrue(Math.Abs(matrix.M11 - result.M11) < 0.001m);
+ Assert.IsTrue(Math.Abs(matrix.M12 - result.M12) < 0.001m);
+ Assert.IsTrue(Math.Abs(matrix.M13 - result.M13) < 0.001m);
+ Assert.IsTrue(Math.Abs(matrix.M14 - result.M14) < 0.001m);
+ Assert.IsTrue(Math.Abs(matrix.M21 - result.M21) < 0.001m);
+ Assert.IsTrue(Math.Abs(matrix.M22 - result.M22) < 0.001m);
+ Assert.IsTrue(Math.Abs(matrix.M23 - result.M23) < 0.001m);
+ Assert.IsTrue(Math.Abs(matrix.M24 - result.M24) < 0.001m);
+ Assert.IsTrue(Math.Abs(matrix.M31 - result.M31) < 0.001m);
+ Assert.IsTrue(Math.Abs(matrix.M32 - result.M32) < 0.001m);
+ Assert.IsTrue(Math.Abs(matrix.M33 - result.M33) < 0.001m);
+ Assert.IsTrue(Math.Abs(matrix.M34 - result.M34) < 0.001m);
+ Assert.IsTrue(Math.Abs(matrix.M41 - result.M41) < 0.001m);
+ Assert.IsTrue(Math.Abs(matrix.M42 - result.M42) < 0.001m);
+ Assert.IsTrue(Math.Abs(matrix.M43 - result.M43) < 0.001m);
+ Assert.IsTrue(Math.Abs(matrix.M44 - result.M44) < 0.001m);
+
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerTest/Properties/AssemblyInfo.cs b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerTest/Properties/AssemblyInfo.cs
new file mode 100644
index 000000000..fe1e4dba6
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerTest/Properties/AssemblyInfo.cs
@@ -0,0 +1,35 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// アセンブリに関する一般情報は以下の属性セットを通して制御されます。
+// アセンブリに関連付けられている情報を変更するには、
+// これらの属性値を変更してください。
+[assembly: AssemblyTitle("MMDIKBakerTest")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("MMDIKBakerTest")]
+[assembly: AssemblyCopyright("Copyright © 2011")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// ComVisible を false に設定すると、その型はこのアセンブリ内で COM コンポーネントから
+// 参照できなくなります。このアセンブリ内で COM から型にアクセスする必要がある場合は、
+// その型の ComVisible 属性を true に設定してください。
+[assembly: ComVisible(false)]
+
+// このプロジェクトが COM に公開される場合、次の GUID がタイプ ライブラリの ID になります。
+[assembly: Guid("fb3f53b4-55bc-473b-8bb1-c40e079dd827")]
+
+// アセンブリのバージョン情報は、以下の 4 つの値で構成されています:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// すべての値を指定するか、以下のように '*' を使用してビルド番号とリビジョン番号を
+// 既定値にすることができます:
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerTest/QuaternionTest.cs b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerTest/QuaternionTest.cs
new file mode 100644
index 000000000..4efa402bc
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerTest/QuaternionTest.cs
@@ -0,0 +1,135 @@
+using MMDIKBakerLibrary.Misc;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using System;
+
+namespace MMDIKBakerTest
+{
+
+
+ ///
+ ///QuaternionTest のテスト クラスです。すべての
+ ///QuaternionTest 単体テストをここに含めます
+ ///
+ [TestClass()]
+ public class QuaternionTest
+ {
+
+
+ private TestContext testContextInstance;
+
+ ///
+ ///現在のテストの実行についての情報および機能を
+ ///提供するテスト コンテキストを取得または設定します。
+ ///
+ public TestContext TestContext
+ {
+ get
+ {
+ return testContextInstance;
+ }
+ set
+ {
+ testContextInstance = value;
+ }
+ }
+
+ #region 追加のテスト属性
+ //
+ //テストを作成するときに、次の追加属性を使用することができます:
+ //
+ //クラスの最初のテストを実行する前にコードを実行するには、ClassInitialize を使用
+ //[ClassInitialize()]
+ //public static void MyClassInitialize(TestContext testContext)
+ //{
+ //}
+ //
+ //クラスのすべてのテストを実行した後にコードを実行するには、ClassCleanup を使用
+ //[ClassCleanup()]
+ //public static void MyClassCleanup()
+ //{
+ //}
+ //
+ //各テストを実行する前にコードを実行するには、TestInitialize を使用
+ //[TestInitialize()]
+ //public void MyTestInitialize()
+ //{
+ //}
+ //
+ //各テストを実行した後にコードを実行するには、TestCleanup を使用
+ //[TestCleanup()]
+ //public void MyTestCleanup()
+ //{
+ //}
+ //
+ #endregion
+
+
+ ///
+ ///Slerp のテスト
+ ///
+ [TestMethod()]
+ public void SlerpTest()
+ {
+ Quaternion[] QuaternionPatterns = { /*Quaternion.Identity,*/ Quaternion.CreateFromAxisAngle(new Vector3(1, 0, 0), 0.72m), Quaternion.CreateFromAxisAngle(new Vector3(0.5m, 0.5m, 0), 0.72m), Quaternion.CreateFromAxisAngle(new Vector3(0, 0.5m, 0.5m), 0.72m) };
+ decimal[] ratePatterns = { 0m, 0.2m, 0.25m, 0.6m, 0.8m, 1m };
+
+ foreach (Quaternion q1 in QuaternionPatterns)
+ {
+ foreach (Quaternion q2 in QuaternionPatterns)
+ {
+ foreach (decimal rate in ratePatterns)
+ {
+ Quaternion quaternion1 = q1, quaternion2 = q2;
+ Quaternion result;
+ quaternion1.Normalize();
+ quaternion2.Normalize();
+ Quaternion.Slerp(ref quaternion1, ref quaternion2, rate, out result);
+ Microsoft.Xna.Framework.Quaternion xnaq1 = new Microsoft.Xna.Framework.Quaternion((float)q1.X, (float)q1.Y, (float)q1.Z, (float)q1.W);
+ Microsoft.Xna.Framework.Quaternion xnaq2 = new Microsoft.Xna.Framework.Quaternion((float)q2.X, (float)q2.Y, (float)q2.Z, (float)q2.W);
+ Microsoft.Xna.Framework.Quaternion xnaactual;
+ Microsoft.Xna.Framework.Quaternion.Slerp(ref xnaq1, ref xnaq2, (float)rate, out xnaactual);
+ Quaternion actual = new Quaternion { X = (decimal)xnaactual.X, Y = (decimal)xnaactual.Y, Z = (decimal)xnaactual.Z, W = (decimal)xnaactual.W };
+ actual.Normalize();
+ result.Normalize();
+ Assert.AreEqual(Math.Abs(actual.X- result.X)<0.01m, true);
+ Assert.AreEqual(Math.Abs(actual.Y - result.Y) < 0.01m, true);
+ Assert.AreEqual(Math.Abs(actual.Z- result.Z)<0.01m, true);
+ Assert.AreEqual(Math.Abs(actual.W- result.W) < 0.01m, true);
+ }
+ }
+ }
+ }
+
+ ///
+ ///Multiply のテスト
+ ///
+ [TestMethod()]
+ public void MultiplyTest()
+ {
+ Quaternion[] QuaternionPatterns = { Quaternion.Identity, Quaternion.CreateFromAxisAngle(new Vector3(1, 0, 0), 0.72m), Quaternion.CreateFromAxisAngle(new Vector3(0.5m, 0.5m, 0), 0.72m), Quaternion.CreateFromAxisAngle(new Vector3(0, 0.5m, 0.5m), 0.72m) };
+ foreach (Quaternion q1 in QuaternionPatterns)
+ {
+ foreach (Quaternion q2 in QuaternionPatterns)
+ {
+ Quaternion quaternion1 = q1, quaternion2 = q2;
+ Quaternion result;
+ quaternion1.Normalize();
+ quaternion2.Normalize();
+ Quaternion.Multiply(ref quaternion1, ref quaternion2, out result);
+ Microsoft.Xna.Framework.Quaternion xnaq1 = new Microsoft.Xna.Framework.Quaternion((float)q1.X, (float)q1.Y, (float)q1.Z, (float)q1.W);
+ Microsoft.Xna.Framework.Quaternion xnaq2 = new Microsoft.Xna.Framework.Quaternion((float)q2.X, (float)q2.Y, (float)q2.Z, (float)q2.W);
+ Microsoft.Xna.Framework.Quaternion xnaactual;
+ Microsoft.Xna.Framework.Quaternion.Multiply(ref xnaq1, ref xnaq2, out xnaactual);
+ Quaternion actual = new Quaternion { X = (decimal)xnaactual.X, Y = (decimal)xnaactual.Y, Z = (decimal)xnaactual.Z, W = (decimal)xnaactual.W };
+ actual.Normalize();
+ result.Normalize();
+ Assert.IsTrue(Math.Abs(actual.X - result.X) < 0.01m);
+ Assert.IsTrue(Math.Abs(actual.Y - result.Y) < 0.01m);
+ Assert.IsTrue(Math.Abs(actual.Z - result.Z) < 0.01m);
+ Assert.IsTrue(Math.Abs(actual.W - result.W) < 0.01m);
+ }
+ }
+
+ }
+ }
+}
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerTest/Vector3Test.cs b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerTest/Vector3Test.cs
new file mode 100644
index 000000000..ae676f1de
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDIKBakerTest/Vector3Test.cs
@@ -0,0 +1,95 @@
+using MMDIKBakerLibrary.Misc;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using System;
+
+namespace MMDIKBakerTest
+{
+
+
+ ///
+ ///Vector3Test のテスト クラスです。すべての
+ ///Vector3Test 単体テストをここに含めます
+ ///
+ [TestClass()]
+ public class Vector3Test
+ {
+
+
+ private TestContext testContextInstance;
+
+ ///
+ ///現在のテストの実行についての情報および機能を
+ ///提供するテスト コンテキストを取得または設定します。
+ ///
+ public TestContext TestContext
+ {
+ get
+ {
+ return testContextInstance;
+ }
+ set
+ {
+ testContextInstance = value;
+ }
+ }
+
+ #region 追加のテスト属性
+ //
+ //テストを作成するときに、次の追加属性を使用することができます:
+ //
+ //クラスの最初のテストを実行する前にコードを実行するには、ClassInitialize を使用
+ //[ClassInitialize()]
+ //public static void MyClassInitialize(TestContext testContext)
+ //{
+ //}
+ //
+ //クラスのすべてのテストを実行した後にコードを実行するには、ClassCleanup を使用
+ //[ClassCleanup()]
+ //public static void MyClassCleanup()
+ //{
+ //}
+ //
+ //各テストを実行する前にコードを実行するには、TestInitialize を使用
+ //[TestInitialize()]
+ //public void MyTestInitialize()
+ //{
+ //}
+ //
+ //各テストを実行した後にコードを実行するには、TestCleanup を使用
+ //[TestCleanup()]
+ //public void MyTestCleanup()
+ //{
+ //}
+ //
+ #endregion
+
+
+ ///
+ ///Transform のテスト
+ ///
+ [TestMethod()]
+ public void TransformTest()
+ {
+ Quaternion[] rotationTestPatterns = { Quaternion.Identity, Quaternion.CreateFromAxisAngle(new Vector3(1, 0, 0), 0.72m), Quaternion.CreateFromAxisAngle(new Vector3(0.5m, 0.5m, 0), 0.72m), Quaternion.CreateFromAxisAngle(new Vector3(0, 0.5m, 0.5m), 0.72m) };
+ Vector3[] transrationTestPatterns = { Vector3.Zero, Vector3.One, new Vector3(5, 1, 1), new Vector3(1, 5, 1), new Vector3(1, 1, 5), new Vector3(5, 5, 1), new Vector3(5, 1, 5), new Vector3(1, 5, 5), new Vector3(5, 5, 5) };
+
+ foreach (var rot in rotationTestPatterns)
+ {
+ foreach (var vec in transrationTestPatterns)
+ {
+ Vector3 value = vec, result;
+ Quaternion rotation = rot;
+ Vector3.Transform(ref value, ref rotation, out result);
+ Microsoft.Xna.Framework.Vector3 value2 = new Microsoft.Xna.Framework.Vector3((float)vec.X, (float)vec.Y, (float)vec.Z), actual_xna;
+ Microsoft.Xna.Framework.Quaternion rotation2 = new Microsoft.Xna.Framework.Quaternion((float)rot.X, (float)rot.Y, (float)rot.Z, (float)rot.W);
+ Microsoft.Xna.Framework.Vector3.Transform(ref value2, ref rotation2, out actual_xna);
+ Vector3 acutual = new Vector3((decimal)actual_xna.X, (decimal)actual_xna.Y, (decimal)actual_xna.Z);
+ Assert.IsTrue(Math.Abs(result.X - acutual.X) < 0.001m);
+ Assert.IsTrue(Math.Abs(result.Y - acutual.Y) < 0.001m);
+ Assert.IsTrue(Math.Abs(result.Z - acutual.Z) < 0.001m);
+
+ }
+ }
+ }
+ }
+}
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDModelLibrary/CoordinateType.cs b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDModelLibrary/CoordinateType.cs
new file mode 100644
index 000000000..3c4630959
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDModelLibrary/CoordinateType.cs
@@ -0,0 +1,20 @@
+
+namespace MikuMikuDance.Model
+{
+ ///
+ /// 座標系を表す列挙体
+ ///
+ public enum CoordinateType
+ {
+ ///
+ /// 左手座標系
+ ///
+ /// MMDの標準座標系
+ LeftHandedCoordinate = 1,
+ ///
+ /// 右手座標系
+ ///
+ /// XNAの標準座標系
+ RightHandedCoordinate = -1,
+ }
+}
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDModelLibrary/MMDModel.cs b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDModelLibrary/MMDModel.cs
new file mode 100644
index 000000000..086af4927
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDModelLibrary/MMDModel.cs
@@ -0,0 +1,46 @@
+using System.IO;
+
+namespace MikuMikuDance.Model
+{
+ ///
+ /// MMDモデルを表すインターフェイス
+ ///
+ ///
+ /// このクラスを継承し、オリジナルのオブジェクトを作成する場合は引数なしコンストラクタを用意すること
+ /// また、Read,Write関数をオーバーライドすること。
+ ///
+ public interface MMDModel
+ {
+ ///
+ /// MMDモデルバージョン番号
+ ///
+ float Version { get; }
+ ///
+ /// Read関数
+ ///
+ /// この関数はModelManagerから呼び出される。呼び出し時にはマジック文字とバージョン番号が読まれた状態で渡される
+ /// マジック文字とバージョン番号読み込み済みのBinaryReader
+ /// 座標系変換指定
+ /// スケール
+ void Read(BinaryReader reader, CoordinateType coordinate, float scale);
+ ///
+ /// Write関数
+ ///
+ /// この関数はModelManagerから呼び出される。呼び出し時にはマジック文字とバージョン番号が書かれた状態で渡される
+ /// マジック文字とバージョン番号書き込み済みのBinaryWriter
+ /// スケール
+ void Write(BinaryWriter writer, float scale);
+ ///
+ /// 保持しているデータの座標系
+ ///
+ CoordinateType Coordinate { get; }
+
+#if false
+ ///
+ /// スケーリング
+ ///
+ /// 拡大倍率
+ void Scale(float ScaleFactor);
+#endif
+ }
+}
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDModelLibrary/ModelManager.cs b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDModelLibrary/ModelManager.cs
new file mode 100644
index 000000000..51bc8df10
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDModelLibrary/ModelManager.cs
@@ -0,0 +1,106 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using MikuMikuDance.Model.Ver1;
+
+namespace MikuMikuDance.Model
+{
+ ///
+ /// MikuMikuDance(MMD)モデルの入出力の管理を行うFactory Class
+ ///
+ public static class ModelManager
+ {
+ ///
+ /// ライブラリユーザー拡張用
+ ///
+ /// ここにMMDモデルを継承したクラスと使用するバージョン番号を登録すると、既存クラスの代わりに、登録したクラスが使用される
+ public static readonly Dictionary OriginalObjects = new Dictionary();
+ ///
+ /// ファイルからMMDモデルを読み込む
+ ///
+ /// MMDモデルファイル
+ /// 変換先座標系
+ /// スケーリング値
+ /// MMDモデルオブジェクト
+ /// MMDの座標系は右手座標系です
+ public static MMDModel Read(string filename, CoordinateType coordinate, float scale=1f)
+ {
+ //フルパス取得
+ filename = Path.GetFullPath(filename);
+ //ファイルチェック
+ if (!File.Exists(filename))
+ throw new FileNotFoundException("MMDモデルファイル:" + filename + "が見つかりません");
+ //戻り値用変数
+ MMDModel result = null;
+ //ファイルリーダー
+ using (FileStream fs = new FileStream(filename, FileMode.Open))
+ {
+ BinaryReader reader = new BinaryReader(fs);
+ //マジック文字列
+ string magic = MMDModel1.encoder.GetString(reader.ReadBytes(3));
+ if (magic != "Pmd")
+ throw new FileLoadException("MMDモデルファイルではありません");
+ //バージョン
+ float version = BitConverter.ToSingle(reader.ReadBytes(4), 0);
+ if (OriginalObjects.ContainsKey(version) &&
+ OriginalObjects[version].BaseType == typeof(MMDModel))
+ {//このバージョンで使用し、利用可能型
+ result = (MMDModel)OriginalObjects[version].InvokeMember(null, System.Reflection.BindingFlags.CreateInstance, null, null, null);
+ }
+ else
+ {
+ if (version == 1.0)
+ result = new MMDModel1();
+ else
+ throw new FileLoadException("version=" + version.ToString() + "モデルは対応していません");
+ }
+ result.Read(reader, coordinate, scale);
+ if (fs.Length != fs.Position)
+ Console.WriteLine("警告:ファイル末尾以降に不明データ?");
+ fs.Close();
+ }
+ return result;
+ }
+ ///
+ /// ファイルにMMDモデルを書きだす
+ ///
+ /// 書きだすファイル名
+ /// モデルオブジェクト
+ /// スケーリング値
+ public static void Write(string filename, MMDModel model, float scale = 1f)
+ {
+ //フルパス取得
+ filename = Path.GetFullPath(filename);
+ //ファイルリーダー
+ using (FileStream fs = new FileStream(filename, FileMode.Create))
+ {
+ BinaryWriter writer = new BinaryWriter(fs);
+
+ //マジック文字列
+ writer.Write(MMDModel1.encoder.GetBytes("Pmd"));
+ //バージョン
+ writer.Write(model.Version);
+ //中身の書きだし
+ try
+ {
+ model.Write(writer, scale);
+ }
+ catch (NullReferenceException e)
+ {
+ throw new ArgumentNullException("modelの中の変数がnull", e);
+ }
+ fs.Close();
+ }
+ }
+ ///
+ /// ファイルからMMDモデルを読み込む
+ ///
+ /// MMDモデルファイル
+ /// MMDモデルオブジェクト
+ /// MMDの座標系は右手座標系です
+ public static MMDModel Read(string filename)
+ {
+ return Read(filename, CoordinateType.LeftHandedCoordinate);
+ }
+ }
+}
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDModelLibrary/Properties/AssemblyInfo.cs b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDModelLibrary/Properties/AssemblyInfo.cs
new file mode 100644
index 000000000..5e98eec66
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDModelLibrary/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// アセンブリに関する一般情報は以下の属性セットをとおして制御されます。
+// アセンブリに関連付けられている情報を変更するには、
+// これらの属性値を変更してください。
+[assembly: AssemblyTitle("MMDModelLibrary")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("MMDModelLibrary")]
+[assembly: AssemblyCopyright("Copyright © 2011 Wilfrem")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// ComVisible を false に設定すると、その型はこのアセンブリ内で COM コンポーネントから
+// 参照不可能になります。COM からこのアセンブリ内の型にアクセスする場合は、
+// その型の ComVisible 属性を true に設定してください。
+[assembly: ComVisible(false)]
+
+// 次の GUID は、このプロジェクトが COM に公開される場合の、typelib の ID です
+[assembly: Guid("cff3de6f-3e61-4425-869b-3080f2bc37e5")]
+
+// アセンブリのバージョン情報は、以下の 4 つの値で構成されています:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// すべての値を指定するか、下のように '*' を使ってビルドおよびリビジョン番号を
+// 既定値にすることができます:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("2.0.0.0")]
+[assembly: AssemblyFileVersion("2.0.0.0")]
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDModelLibrary/Ver1/MMDModel1.cs b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDModelLibrary/Ver1/MMDModel1.cs
new file mode 100644
index 000000000..a3107e89b
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDModelLibrary/Ver1/MMDModel1.cs
@@ -0,0 +1,530 @@
+using System;
+using System.IO;
+using System.Text;
+using DWORD = System.UInt32;
+using WORD = System.UInt16;
+
+namespace MikuMikuDance.Model.Ver1
+{
+ ///
+ /// MMDのモデルver1.0を表すクラス
+ ///
+ public class MMDModel1 : MMDModel
+ {
+ //members and properties...
+ ///
+ /// Version番号。MMDModelから継承されます
+ ///
+ public float Version
+ {
+ get { return 1.0f; }
+ }
+ ///
+ /// ヘッダ情報
+ ///
+ public ModelHeader Header { get; protected set; }
+ ///
+ /// 頂点リスト
+ ///
+ public ModelVertex[] Vertexes { get; set; }
+ ///
+ /// 面リスト
+ ///
+ public WORD[] FaceVertexes { get; set; }
+ ///
+ /// 材質リスト
+ ///
+ public ModelMaterial[] Materials { get; set; }
+ ///
+ /// ボーンリスト
+ ///
+ public ModelBone[] Bones { get; set; }
+ ///
+ /// IKボーンリスト
+ ///
+ public ModelIK[] IKs { get; set; }
+ ///
+ /// 表情リスト
+ ///
+ public ModelSkin[] Skins { get; set; }//表情リスト
+ ///
+ /// 表情枠用の表情番号リスト
+ ///
+ public WORD[] SkinIndex { get; set; }
+ ///
+ /// ボーン枠用の枠名リスト
+ ///
+ public ModelBoneDispName[] BoneDispNames { get; set; }//ボーン枠用枠名リスト
+ ///
+ /// ボーン枠用表示リスト
+ ///
+ public ModelBoneDisp[] BoneDisps { get; set; }//ボーン枠用表示リスト
+ ///
+ /// 拡張1(英語拡張)使用フラグ
+ ///
+ public bool Expantion { get; set; }
+ ///
+ /// 拡張2(トゥーン指定)使用フラグ
+ ///
+ /// 拡張1がtrueでないと出力時トゥーン指定は書きだされない
+ public bool ToonExpantion { get; set; }
+ ///
+ /// トゥーンテクスチャリスト(拡張)
+ ///
+ public string[] ToonFileNames { get; protected set; }//トゥーンテクスチャリスト(拡張)、10個固定
+ const int NumToonFileName = 10;
+
+ ///
+ /// 拡張3(物理演算拡張)使用フラグ
+ ///
+ /// 拡張1,2がtrueでないと物理演算項目は書きだされない
+ public bool PhysicsExpantion { get; set; }
+ ///
+ /// 物理演算用の剛体リスト(拡張)
+ ///
+ public ModelRigidBody[] RigidBodies { get; set; }//物理演算、剛体リスト(拡張)
+ ///
+ /// 物理演算用のジョイントリスト(拡張)
+ ///
+ public ModelJoint[] Joints { get; set; }//物理演算、ジョイントリスト(拡張)
+ ///
+ /// 保持しているデータの座標き
+ ///
+ public CoordinateType Coordinate { get; protected set; }
+ //座標変換用ヘルパ関数
+ float CoordZ { get { return (float)Coordinate; } }
+
+ //constructor
+ ///
+ /// 既定のコンストラクタ
+ ///
+ public MMDModel1()
+ {
+ Header = new ModelHeader();
+ Vertexes = null;
+ Expantion = false;
+ ToonExpantion = false;
+ PhysicsExpantion = false;
+ ToonFileNames = new string[NumToonFileName];
+ Coordinate = CoordinateType.LeftHandedCoordinate;
+ }
+
+ //methods...
+ ///
+ /// Read関数
+ ///
+ /// この関数はModelManagerから呼び出される。呼び出し時にはマジック文字とバージョン番号が読まれた状態で渡される
+ /// マジック文字とバージョン番号読み込み済みのBinaryReader
+ /// 変換先座標系
+ /// スケーリング値
+ public void Read(BinaryReader reader, CoordinateType coordinate, float scale)
+ {
+ Coordinate = coordinate;//座標系セット
+ //通常ヘッダ読み込み(英語ヘッダはBoneIndexの後(ミクなら0x00071167)に書かれている
+ Header.Read(reader);
+ //頂点リスト読み込み
+ DWORD num_vertex = BitConverter.ToUInt32(reader.ReadBytes(4), 0);
+ Vertexes = new ModelVertex[num_vertex];
+ for (DWORD i = 0; i < num_vertex; i++)
+ {
+ Vertexes[i] = new ModelVertex();
+ Vertexes[i].Read(reader, CoordZ, scale);
+ }
+ //面リスト読み込み
+ DWORD face_vert_count = BitConverter.ToUInt32(reader.ReadBytes(4), 0);
+ FaceVertexes = new WORD[face_vert_count];
+ for (DWORD i = 0; i < face_vert_count; i++)
+ {
+ FaceVertexes[i] = BitConverter.ToUInt16(reader.ReadBytes(2), 0);
+ }
+ //材質リスト読み込み
+ DWORD material_count = BitConverter.ToUInt32(reader.ReadBytes(4), 0);
+ Materials = new ModelMaterial[material_count];
+ for (DWORD i = 0; i < material_count; i++)
+ {
+ Materials[i] = new ModelMaterial();
+ Materials[i].Read(reader);
+ }
+ //ボーンリスト読み込み
+ WORD bone_count = BitConverter.ToUInt16(reader.ReadBytes(2), 0);
+ Bones = new ModelBone[bone_count];
+ for (WORD i = 0; i < bone_count; i++)
+ {
+ Bones[i] = new ModelBone();
+ Bones[i].Read(reader, CoordZ, scale);
+ }
+ //IKリスト読み込み
+ WORD ik_count = BitConverter.ToUInt16(reader.ReadBytes(2), 0);
+ IKs = new ModelIK[ik_count];
+ for (WORD i = 0; i < ik_count; i++)
+ {
+ IKs[i] = new ModelIK();
+ IKs[i].Read(reader);
+ }
+ //表情リスト読み込み
+ WORD skin_count = BitConverter.ToUInt16(reader.ReadBytes(2), 0);
+ Skins = new ModelSkin[skin_count];
+ for (WORD i = 0; i < skin_count; i++)
+ {
+ Skins[i] = new ModelSkin();
+ Skins[i].Read(reader, CoordZ, scale);
+ }
+ //表情枠用表示リスト
+ byte skin_disp_count = reader.ReadByte();
+ SkinIndex = new WORD[skin_disp_count];
+ for (byte i = 0; i < SkinIndex.Length; i++)
+ SkinIndex[i] = BitConverter.ToUInt16(reader.ReadBytes(2), 0);
+ //ボーン枠用枠名リスト
+ byte bone_disp_name_count = reader.ReadByte();
+ BoneDispNames = new ModelBoneDispName[bone_disp_name_count];
+ for (byte i = 0; i < BoneDispNames.Length; i++)
+ {
+ BoneDispNames[i] = new ModelBoneDispName();
+ BoneDispNames[i].Read(reader);
+ }
+ //ボーン枠用表示リスト
+ DWORD bone_disp_count = BitConverter.ToUInt32(reader.ReadBytes(4), 0);
+ BoneDisps = new ModelBoneDisp[bone_disp_count];
+ for (DWORD i = 0; i < BoneDisps.Length; i++)
+ {
+ BoneDisps[i] = new ModelBoneDisp();
+ BoneDisps[i].Read(reader);
+ }
+ //英語表記フラグ
+ Expantion = (reader.ReadByte() != 0);
+ if (Expantion)
+ {
+ //英語ヘッダ
+ Header.ReadExpantion(reader);
+ //ボーンリスト(英語)
+ for (WORD i = 0; i < bone_count; i++)
+ {
+ Bones[i].ReadExpantion(reader);
+ }
+ //スキンリスト(英語)
+ for (WORD i = 0; i < skin_count; i++)
+ {
+ if (Skins[i].SkinType != 0)//baseのスキンには英名無し
+ Skins[i].ReadExpantion(reader);
+ }
+ //ボーン枠用枠名リスト(英語)
+ for (byte i = 0; i < BoneDispNames.Length; i++)
+ {
+ BoneDispNames[i].ReadExpantion(reader);
+ }
+ }
+ if (reader.BaseStream.Position >= reader.BaseStream.Length)
+ ToonExpantion = false;
+ else
+ {
+ ToonExpantion = true;
+ //トゥーンテクスチャリスト
+ ToonFileNames = new string[NumToonFileName];//10個固定
+ for (int i = 0; i < ToonFileNames.Length; i++)
+ {
+ ToonFileNames[i] = GetString(reader.ReadBytes(100));
+ }
+ }
+ if (reader.BaseStream.Position >= reader.BaseStream.Length)
+ PhysicsExpantion = false;
+ else
+ {
+ PhysicsExpantion = true;
+ //剛体リスト
+ DWORD rididbody_count = BitConverter.ToUInt32(reader.ReadBytes(4), 0);
+ RigidBodies = new ModelRigidBody[rididbody_count];
+ for (DWORD i = 0; i < rididbody_count; i++)
+ {
+ RigidBodies[i] = new ModelRigidBody();
+ RigidBodies[i].ReadExpantion(reader, CoordZ, scale);
+ }
+ //ジョイントリスト
+ DWORD joint_count = BitConverter.ToUInt32(reader.ReadBytes(4), 0);
+ Joints = new ModelJoint[joint_count];
+ for (DWORD i = 0; i < joint_count; i++)
+ {
+ Joints[i] = new ModelJoint();
+ Joints[i].ReadExpantion(reader, CoordZ, scale);
+ }
+ }
+
+ }
+ ///
+ /// Write関数
+ ///
+ /// この関数はModelManagerから呼び出される。呼び出し時にはマジック文字とバージョン番号が書かれた状態で渡される
+ /// マジック文字とバージョン番号書き込み済みのBinaryWriter
+ /// スケール
+ public void Write(BinaryWriter writer, float scale)
+ {
+ //通常ヘッダ書きだし(英語ヘッダはBoneIndexの後(ミクなら0x00071167)に書かれている
+ Header.Write(writer);
+ //頂点リスト書きだし
+ if (Vertexes == null)
+ writer.Write((DWORD)0);
+ else
+ {
+ writer.Write((DWORD)Vertexes.LongLength);
+ for (DWORD i = 0; i < Vertexes.LongLength; i++)
+ {
+ if (Vertexes[i] == null)
+ throw new ArgumentNullException("Vertexes[" + i.ToString() + "]がnull");
+ Vertexes[i].Write(writer, CoordZ, scale);
+ }
+ }
+ //面リスト書きだし
+ if (FaceVertexes == null)
+ writer.Write((DWORD)0);
+ else
+ {
+ writer.Write((DWORD)FaceVertexes.LongLength);
+ for (DWORD i = 0; i < FaceVertexes.LongLength; i++)
+ {
+ writer.Write(FaceVertexes[i]);
+ }
+ }
+ //材質リスト書きだし
+ if (Materials == null)
+ writer.Write((DWORD)0);
+ else
+ {
+ writer.Write((DWORD)Materials.LongLength);
+ for (DWORD i = 0; i < Materials.LongLength; i++)
+ {
+ if (Materials[i] == null)
+ throw new ArgumentNullException("Materials[" + i.ToString() + "]がnull");
+ Materials[i].Write(writer);
+ }
+ }
+ //ボーンリスト書きだし
+ if (Bones == null)
+ writer.Write((WORD)0);
+ else
+ {
+ writer.Write((WORD)Bones.Length);
+ for (WORD i = 0; i < Bones.Length; i++)
+ {
+ if (Bones[i] == null)
+ throw new ArgumentNullException("Bones[" + i.ToString() + "]がnull");
+ Bones[i].Write(writer, CoordZ,scale);
+ }
+ }
+ //IKリスト書きだし
+ if (IKs == null)
+ writer.Write((WORD)0);
+ else
+ {
+ writer.Write((WORD)IKs.Length);
+ for (WORD i = 0; i < IKs.Length; i++)
+ {
+ if (IKs[i] == null)
+ throw new ArgumentNullException("IKs[" + i.ToString() + "]がnull");
+ IKs[i].Write(writer);
+ }
+ }
+ //表情リスト書きだし
+ if (Skins == null)
+ writer.Write((WORD)0);
+ else
+ {
+ writer.Write((WORD)Skins.Length);
+ for (WORD i = 0; i < Skins.Length; i++)
+ {
+ if (Skins[i] == null)
+ throw new ArgumentNullException("Skins[" + i.ToString() + "]がnull");
+ Skins[i].Write(writer, CoordZ,scale);
+ }
+ }
+ //表情枠用表示リスト書きだし
+ if (SkinIndex == null)
+ writer.Write((byte)0);
+ else
+ {
+ writer.Write((byte)SkinIndex.Length);
+
+ for (byte i = 0; i < SkinIndex.Length; i++)
+ {
+ writer.Write(SkinIndex[i]);
+ }
+ }
+ //ボーン枠用枠名リスト
+ if (BoneDispNames == null)
+ writer.Write((byte)0);
+ else
+ {
+ writer.Write((byte)BoneDispNames.Length);
+ for (byte i = 0; i < BoneDispNames.Length; i++)
+ {
+ if(BoneDispNames[i]==null)
+ throw new ArgumentNullException("BoneDispNames[" + i.ToString() + "]がnull");
+ BoneDispNames[i].Write(writer);
+ }
+ }
+ //ボーン枠用表示リスト
+ if (BoneDisps == null)
+ writer.Write((DWORD)0);
+ else
+ {
+ writer.Write((DWORD)BoneDisps.Length);
+ for (DWORD i = 0; i < BoneDisps.Length; i++)
+ {
+ if (BoneDisps[i] == null)
+ throw new ArgumentNullException("BoneDisps[" + i.ToString() + "]がnull");
+ BoneDisps[i].Write(writer);
+ }
+ }
+ //英語表記フラグ
+ writer.Write((byte)(Expantion ? 1 : 0));
+ if (Expantion)
+ {
+ //英語ヘッダ
+ Header.WriteExpantion(writer);
+ //ボーンリスト(英語)
+ if (Bones != null)
+ {
+ for (WORD i = 0; i < Bones.Length; i++)
+ {
+ Bones[i].WriteExpantion(writer);
+ }
+ }
+ //スキンリスト(英語)
+ if (Skins != null)
+ {
+ for (WORD i = 0; i < Skins.Length; i++)
+ {
+ if (Skins[i].SkinType != 0)//baseのスキンには英名無し
+ Skins[i].WriteExpantion(writer);
+ }
+ }
+ //ボーン枠用枠名リスト(英語)
+ if (BoneDispNames != null)
+ {
+ for (byte i = 0; i < BoneDispNames.Length; i++)
+ {
+ BoneDispNames[i].WriteExpantion(writer);
+ }
+ }
+ }
+ if (ToonExpantion)
+ {
+ //トゥーンテクスチャリスト
+ for (int i = 0; i < ToonFileNames.Length; i++)
+ {
+ writer.Write(GetBytes(ToonFileNames[i], 100));
+ }
+ if (PhysicsExpantion)
+ {
+ //剛体リスト
+ if (RigidBodies == null)
+ writer.Write((DWORD)0);
+ else
+ {
+ writer.Write((DWORD)RigidBodies.LongLength);
+ for (long i = 0; i < RigidBodies.LongLength; i++)
+ {
+ if (RigidBodies[i] == null)
+ throw new ArgumentNullException("RididBodies[" + i.ToString() + "]がnull");
+ RigidBodies[i].WriteExpantion(writer, CoordZ,scale);
+ }
+ }
+ //ジョイントリスト
+ if (Joints == null)
+ writer.Write((DWORD)0);
+ else
+ {
+ writer.Write((DWORD)Joints.LongLength);
+ for (long i = 0; i < Joints.LongLength; i++)
+ {
+ if (Joints[i] == null)
+ throw new ArgumentNullException("Joints[" + i.ToString() + "]がnull");
+ Joints[i].WriteExpantion(writer, CoordZ,scale);
+ }
+ }
+ }
+ }
+
+ }
+#if false
+ ///
+ /// スケーリング
+ ///
+ /// 拡大倍率
+ public void Scale(float ScaleFactor)
+ {
+ if(ScaleFactor<=0)
+ throw new ApplicationException("ScaleFactorは正の実数である必要があります。");
+ //頂点
+ for (long i = 0; i < Vertexes.LongLength; i++)
+ {
+ for (int j = 0; j < Vertexes[i].Pos.Length; j++)
+ Vertexes[i].Pos[j] = Vertexes[i].Pos[j] * ScaleFactor;
+ }
+ //ボーン
+ for (long i = 0; i < Bones.LongLength; i++)
+ {
+ for (int j = 0; j < Bones[i].BoneHeadPos.Length; j++)
+ Bones[i].BoneHeadPos[j] = Vertexes[i].Pos[j] * ScaleFactor;
+ }
+ //表情
+ for (long i = 0; i < Skins.LongLength; i++)
+ {
+ for (long j = 0; j < Skins[i].SkinVertDatas.LongLength; j++)
+ {
+ for (int k = 0; k < Skins[i].SkinVertDatas[j].SkinVertPos.Length; k++)
+ Skins[i].SkinVertDatas[j].SkinVertPos[k] = Skins[i].SkinVertDatas[j].SkinVertPos[k] * ScaleFactor;
+ }
+ }
+ if (PhysicsExpantion)
+ {
+ //剛体
+ for (long i = 0; i < RigidBodies.LongLength; i++)
+ {
+ for (int j = 0; j < RigidBodies[i].Position.Length; j++)
+ RigidBodies[i].Position[j] = RigidBodies[i].Position[j] * ScaleFactor;
+ }
+ //ジョイント
+ for (long i = 0; i < Joints.LongLength; i++)
+ {
+ for (int j = 0; j < Joints[i].ConstrainPosition1.Length; j++)
+ {
+ Joints[i].ConstrainPosition1[j] = Joints[i].ConstrainPosition1[j] * ScaleFactor;
+ Joints[i].ConstrainPosition2[j] = Joints[i].ConstrainPosition2[j] * ScaleFactor;
+ Joints[i].Position[j] = Joints[i].Position[j] * ScaleFactor;
+ Joints[i].SpringPosition[j] = Joints[i].SpringPosition[j] * ScaleFactor;
+ }
+ }
+ }
+ }
+#endif
+ //internal statics...
+ internal static Encoding encoder = Encoding.GetEncoding("shift-jis");
+ internal static string GetString(byte[] bytes)
+ {
+ int i;
+ for (i = 0; i < bytes.Length; i++)
+ if (bytes[i] == 0)
+ break;
+ if (i < bytes.Length)
+ return encoder.GetString(bytes, 0, i);
+ return encoder.GetString(bytes);
+ }
+ internal static byte[] GetBytes(string input, long size)
+ {
+ byte[] result = new byte[size];
+ for (long i = 0; i < size; i++)
+ result[i] = 0;
+ if (input == "")
+ return result;
+ byte[] strs = encoder.GetBytes(input);
+ for (long i = 0; i < strs.LongLength; i++)
+ if (i < result.LongLength)
+ result[i] = strs[i];
+ if (result.LongLength <= strs.LongLength)
+ return result;
+ result[strs.LongLength] = 0;
+ for (long i = strs.LongLength + 1; i < result.Length; i++)
+ result[i] = 0xFD;//何故かこれが挿入されているのでこれを挿入
+ return result;
+ }
+ }
+}
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDModelLibrary/Ver1/ModelBone.cs b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDModelLibrary/Ver1/ModelBone.cs
new file mode 100644
index 000000000..542517c3e
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDModelLibrary/Ver1/ModelBone.cs
@@ -0,0 +1,89 @@
+using System;
+using System.IO;
+using WORD = System.UInt16;
+
+namespace MikuMikuDance.Model.Ver1
+{
+ ///
+ /// ボーン
+ ///
+ public class ModelBone
+ {
+ ///
+ /// ボーン名
+ ///
+ public string BoneName { get; set; } //20byte分char ボーン名
+ ///
+ /// 親ボーン番号
+ ///
+ /// 無い場合は0xFFFFを代入
+ public WORD ParentBoneIndex { get; set; } // 親ボーン番号(ない場合は0xFFFF)
+ ///
+ /// tail位置のボーン番号
+ ///
+ /// チェーン末端の場合は0xFFFF。 親:子は1:多なので、主に位置決め用
+ public WORD TailPosBoneIndex { get; set; } // tail位置のボーン番号(チェーン末端の場合は0xFFFF) // 親:子は1:多なので、主に位置決め用
+ ///
+ /// ボーンの種類
+ ///
+ /// 0:回転 1:回転と移動 2:IK 3:不明 4:IK影響下 5:回転影響下 6:IK接続先 7:非表示 8:捻り 9:回転運動
+ public byte BoneType { get; set; } // ボーンの種類
+ ///
+ /// IKボーン番号
+ ///
+ /// 影響IKボーン。ない場合は0
+ public WORD IKParentBoneIndex { get; set; } // IKボーン番号(影響IKボーン。ない場合は0)
+ ///
+ /// ボーンのヘッドの位置(x,y,z)
+ ///
+ public float[] BoneHeadPos { get; private set; } // x, y, z // ボーンのヘッドの位置
+ ///
+ /// ボーン名(英語、拡張)
+ ///
+ public string BoneNameEnglish { get; set; }////20byte分char ボーン名(英語、拡張(無い場合はnull))
+ ///
+ /// 既定のコンストラクタ
+ ///
+ public ModelBone()
+ {
+ BoneHeadPos = new float[3];
+ }
+ internal void Read(BinaryReader reader, float CoordZ, float scale)
+ {
+ BoneHeadPos = new float[3];
+ BoneName = MMDModel1.GetString(reader.ReadBytes(20));
+ ParentBoneIndex = BitConverter.ToUInt16(reader.ReadBytes(2), 0);
+ TailPosBoneIndex = BitConverter.ToUInt16(reader.ReadBytes(2), 0);
+ BoneType = reader.ReadByte();
+ IKParentBoneIndex = BitConverter.ToUInt16(reader.ReadBytes(2), 0);
+ for (int i = 0; i < BoneHeadPos.Length; i++)
+ BoneHeadPos[i] = BitConverter.ToSingle(reader.ReadBytes(4), 0) * scale;
+ //英名拡張はReadではnullにする(あるならReadEngilishで上書きされる)
+ BoneNameEnglish = null;
+ BoneHeadPos[2] = BoneHeadPos[2] * CoordZ;
+ }
+
+ //英名拡張分読み込み
+ internal void ReadExpantion(BinaryReader reader)
+ {
+ BoneNameEnglish = MMDModel1.GetString(reader.ReadBytes(20));
+ }
+
+ internal void Write(BinaryWriter writer, float CoordZ, float scale)
+ {
+ BoneHeadPos[2] = BoneHeadPos[2] * CoordZ * scale;
+ writer.Write(MMDModel1.GetBytes(BoneName, 20));
+ writer.Write(ParentBoneIndex);
+ writer.Write(TailPosBoneIndex);
+ writer.Write(BoneType);
+ writer.Write(IKParentBoneIndex);
+ for (int i = 0; i < BoneHeadPos.Length; i++)
+ writer.Write(BoneHeadPos[i]);
+ }
+
+ internal void WriteExpantion(BinaryWriter writer)
+ {
+ writer.Write(MMDModel1.GetBytes(BoneNameEnglish, 20));
+ }
+ }
+}
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDModelLibrary/Ver1/ModelBoneDisp.cs b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDModelLibrary/Ver1/ModelBoneDisp.cs
new file mode 100644
index 000000000..38f7d25e6
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDModelLibrary/Ver1/ModelBoneDisp.cs
@@ -0,0 +1,33 @@
+using System;
+using System.IO;
+using WORD = System.UInt16;
+
+namespace MikuMikuDance.Model.Ver1
+{
+ ///
+ /// ボーン枠用表示データ
+ ///
+ public class ModelBoneDisp
+ {
+ ///
+ /// 枠用ボーン番号
+ ///
+ public WORD BoneIndex { get; set; } // 枠用ボーン番号
+ ///
+ /// 表示枠用番号
+ ///
+ public byte BoneDispFrameIndex { get; set; } // 表示枠番号
+
+ internal void Read(BinaryReader reader)
+ {
+ BoneIndex = BitConverter.ToUInt16(reader.ReadBytes(2), 0);
+ BoneDispFrameIndex = reader.ReadByte();
+ }
+
+ internal void Write(BinaryWriter writer)
+ {
+ writer.Write(BoneIndex);
+ writer.Write(BoneDispFrameIndex);
+ }
+ }
+}
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDModelLibrary/Ver1/ModelBoneDispName.cs b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDModelLibrary/Ver1/ModelBoneDispName.cs
new file mode 100644
index 000000000..bacd1892c
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDModelLibrary/Ver1/ModelBoneDispName.cs
@@ -0,0 +1,38 @@
+using System.IO;
+
+namespace MikuMikuDance.Model.Ver1
+{
+ ///
+ /// ボーン枠用の枠名
+ ///
+ public class ModelBoneDispName
+ {
+ ///
+ /// ボーン枠用の枠名
+ ///
+ public string BoneDispName { get; set; }//ボーン枠用枠名
+ ///
+ /// ボーン枠用の枠名(英語、拡張)
+ ///
+ public string BoneDispNameEnglish { get; set; }//ボーン枠用枠名(英語、拡張)
+ internal void Read(BinaryReader reader)
+ {
+ BoneDispName = MMDModel1.GetString(reader.ReadBytes(50));
+ BoneDispNameEnglish = null;
+ }
+ internal void ReadExpantion(BinaryReader reader)
+ {
+ BoneDispNameEnglish = MMDModel1.GetString(reader.ReadBytes(50));
+ }
+
+ internal void Write(BinaryWriter writer)
+ {
+ writer.Write(MMDModel1.GetBytes(BoneDispName, 50));
+ }
+
+ internal void WriteExpantion(BinaryWriter writer)
+ {
+ writer.Write(MMDModel1.GetBytes(BoneDispNameEnglish, 50));
+ }
+ }
+}
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDModelLibrary/Ver1/ModelHeader.cs b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDModelLibrary/Ver1/ModelHeader.cs
new file mode 100644
index 000000000..1246ad039
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDModelLibrary/Ver1/ModelHeader.cs
@@ -0,0 +1,63 @@
+using System.IO;
+
+namespace MikuMikuDance.Model.Ver1
+{
+ ///
+ /// モデルヘッダ情報を表すクラス
+ ///
+ public class ModelHeader
+ {
+ ///
+ /// モデル名
+ ///
+ public string ModelName { get; set; }
+ ///
+ /// モデルコメント
+ ///
+ public string Comment { get; set; }
+ ///
+ /// モデル名(英語、拡張)
+ ///
+ public string ModelNameEnglish { get; set; }
+ ///
+ /// モデルコメント(英語、拡張)
+ ///
+ public string CommentEnglish { get; set; }
+ ///
+ /// 既定のコンストラクタ
+ ///
+ public ModelHeader()
+ {
+ ModelName = "";
+ Comment = "";
+ ModelNameEnglish = null;
+ CommentEnglish = null;
+ }
+ internal void Read(BinaryReader reader)
+ {
+ //モデル名
+ ModelName = MMDModel1.GetString(reader.ReadBytes(20));
+ //コメント
+ Comment = MMDModel1.GetString(reader.ReadBytes(256));
+ }
+
+ internal void ReadExpantion(BinaryReader reader)
+ {
+ ModelNameEnglish = MMDModel1.GetString(reader.ReadBytes(20));
+ CommentEnglish = MMDModel1.GetString(reader.ReadBytes(256));
+ }
+
+ internal void Write(BinaryWriter writer)
+ {
+ writer.Write(MMDModel1.GetBytes(ModelName, 20));
+ writer.Write(MMDModel1.GetBytes(Comment, 256));
+ }
+
+ internal void WriteExpantion(BinaryWriter writer)
+ {
+ writer.Write(MMDModel1.GetBytes(ModelNameEnglish, 20));
+ writer.Write(MMDModel1.GetBytes(CommentEnglish, 256));
+ }
+ }
+
+}
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDModelLibrary/Ver1/ModelIK.cs b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDModelLibrary/Ver1/ModelIK.cs
new file mode 100644
index 000000000..122f80ef7
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDModelLibrary/Ver1/ModelIK.cs
@@ -0,0 +1,60 @@
+using System;
+using System.IO;
+using WORD = System.UInt16;
+
+namespace MikuMikuDance.Model.Ver1
+{
+ ///
+ /// IKボーン
+ ///
+ public class ModelIK
+ {
+ ///
+ /// IKボーン番号
+ ///
+ public WORD IKBoneIndex { get; set; } // IKボーン番号
+ ///
+ /// IKターゲットボーン番号
+ ///
+ /// IKボーンが最初に接続するボーン
+ public WORD IKTargetBoneIndex { get; set; } // IKターゲットボーン番号 // IKボーンが最初に接続するボーン
+ //byte ik_chain_length;//読み込んでるが、ik_child_bone_indexで参照可のため、メンバにしない
+ ///
+ /// 再帰演算回数
+ ///
+ /// IK値1
+ public WORD Iterations { get; set; } // 再帰演算回数 // IK値1
+ ///
+ /// 一回のIK計算での角度制限
+ ///
+ /// IK値2
+ public float AngleLimit { get; set; } // IKの影響度 // IK値2
+ ///
+ /// IK影響下のボーン番号リスト
+ ///
+ public WORD[] IKChildBoneIndex { get; set; } // IK影響下のボーン番号-サイズはik_chain_length
+
+ internal void Read(BinaryReader reader)
+ {
+ IKBoneIndex = BitConverter.ToUInt16(reader.ReadBytes(2), 0);
+ IKTargetBoneIndex = BitConverter.ToUInt16(reader.ReadBytes(2), 0);
+ byte ik_chain_length = reader.ReadByte();
+ Iterations = BitConverter.ToUInt16(reader.ReadBytes(2), 0);
+ AngleLimit = BitConverter.ToSingle(reader.ReadBytes(4), 0);
+ IKChildBoneIndex = new WORD[ik_chain_length];
+ for (int i = 0; i < ik_chain_length; i++)
+ IKChildBoneIndex[i] = BitConverter.ToUInt16(reader.ReadBytes(2), 0);
+ }
+
+ internal void Write(BinaryWriter writer)
+ {
+ writer.Write(IKBoneIndex);
+ writer.Write(IKTargetBoneIndex);
+ writer.Write((byte)IKChildBoneIndex.Length);
+ writer.Write(Iterations);
+ writer.Write(AngleLimit);
+ for (int i = 0; i < IKChildBoneIndex.Length; i++)
+ writer.Write(IKChildBoneIndex[i]);
+ }
+ }
+}
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDModelLibrary/Ver1/ModelJoint.cs b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDModelLibrary/Ver1/ModelJoint.cs
new file mode 100644
index 000000000..1073938fe
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDModelLibrary/Ver1/ModelJoint.cs
@@ -0,0 +1,132 @@
+using System;
+using System.IO;
+using DWORD = System.UInt32;
+
+namespace MikuMikuDance.Model.Ver1
+{
+ ///
+ /// 物理演算用のジョイント
+ ///
+ public class ModelJoint
+ {
+ ///
+ /// 名称
+ ///
+ public string Name { get; set; } // 諸データ:名称 // 右髪1(char*20)
+ ///
+ /// 剛体A
+ ///
+ public DWORD RigidBodyA { get; set; } // 諸データ:剛体A
+ ///
+ /// 剛体B
+ ///
+ public DWORD RigidBodyB { get; set; } // 諸データ:剛体B
+ ///
+ /// 位置(x, y, z)
+ ///
+ public float[] Position { get;private set; } //float*3 諸データ:位置(x, y, z) // 諸データ:位置合せでも設定可
+ ///
+ /// 回転(rad(x), rad(y), rad(z))
+ ///
+ public float[] Rotation { get; private set; } //float*3 諸データ:回転(rad(x), rad(y), rad(z))
+ ///
+ /// 移動制限1(x, y, z)
+ ///
+ public float[] ConstrainPosition1 { get; private set; } //float*3 制限:移動1(x, y, z)
+ ///
+ /// 移動制限2(x, y, z)
+ ///
+ public float[] ConstrainPosition2 { get; private set; } //float*3 制限:移動2(x, y, z)
+ ///
+ /// 回転制限1(rad(x), rad(y), rad(z))
+ ///
+ public float[] ConstrainRotation1 { get; private set; } //float*3 制限:回転1(rad(x), rad(y), rad(z))
+ ///
+ /// 回転制限2(rad(x), rad(y), rad(z))
+ ///
+ public float[] ConstrainRotation2 { get; private set; } //float*3 制限:回転2(rad(x), rad(y), rad(z))
+ ///
+ /// 平行移動に対するばねの戻る強さ:移動(x, y, z)
+ ///
+ public float[] SpringPosition { get; private set; } //float*3 ばね:移動(x, y, z)
+ ///
+ /// 回転に対するばねの戻る強さ:回転(rad(x), rad(y), rad(z))
+ ///
+ public float[] SpringRotation { get; private set; } //float*3 ばね:回転(rad(x), rad(y), rad(z))
+ ///
+ /// 既定のコンストラクタ
+ ///
+ public ModelJoint()
+ {
+ Position = new float[3];
+ Rotation = new float[3];
+ ConstrainPosition1 = new float[3];
+ ConstrainPosition2 = new float[3];
+ ConstrainRotation1 = new float[3];
+ ConstrainRotation2 = new float[3];
+ SpringPosition = new float[3];
+ SpringRotation = new float[3];
+ }
+ internal void ReadExpantion(BinaryReader reader, float CoordZ, float scale)
+ {
+ Name = MMDModel1.GetString(reader.ReadBytes(20));
+ RigidBodyA = BitConverter.ToUInt32(reader.ReadBytes(4), 0);
+ RigidBodyB = BitConverter.ToUInt32(reader.ReadBytes(4), 0);
+ for (int i = 0; i < Position.Length; i++)
+ Position[i] = BitConverter.ToSingle(reader.ReadBytes(4), 0) *scale;
+ for (int i = 0; i < Rotation.Length; i++)
+ Rotation[i] = BitConverter.ToSingle(reader.ReadBytes(4), 0);
+ for (int i = 0; i < ConstrainPosition1.Length; i++)
+ ConstrainPosition1[i] = BitConverter.ToSingle(reader.ReadBytes(4), 0) *scale;
+ for (int i = 0; i < ConstrainPosition2.Length; i++)
+ ConstrainPosition2[i] = BitConverter.ToSingle(reader.ReadBytes(4), 0) *scale;
+ for (int i = 0; i < ConstrainRotation1.Length; i++)
+ ConstrainRotation1[i] = BitConverter.ToSingle(reader.ReadBytes(4), 0);
+ for (int i = 0; i < ConstrainRotation2.Length; i++)
+ ConstrainRotation2[i] = BitConverter.ToSingle(reader.ReadBytes(4), 0);
+ for (int i = 0; i < SpringPosition.Length; i++)
+ SpringPosition[i] = BitConverter.ToSingle(reader.ReadBytes(4), 0);
+ for (int i = 0; i < SpringRotation.Length; i++)
+ SpringRotation[i] = BitConverter.ToSingle(reader.ReadBytes(4), 0);
+ Position[2] *= CoordZ;
+ //メモ:左手→右手では位置が変換される際に一緒に回転成分が変換されるため、回転の変換は必要ない
+ //ただし、ジョイントの回転(使用してないっぽい)は変換しておく
+ ConstrainRotation1[0] *= CoordZ;
+ ConstrainRotation1[1] *= CoordZ;
+ ConstrainRotation2[0] *= CoordZ;
+ ConstrainRotation2[1] *= CoordZ;
+ ConstrainPosition1[2] *= CoordZ;
+ ConstrainPosition2[2] *= CoordZ;
+ }
+
+ internal void WriteExpantion(BinaryWriter writer, float CoordZ, float scale)
+ {
+ Position[2] *= CoordZ;
+ ConstrainRotation1[0] *= CoordZ;
+ ConstrainRotation1[1] *= CoordZ;
+ ConstrainRotation2[0] *= CoordZ;
+ ConstrainRotation2[1] *= CoordZ;
+ ConstrainPosition1[2] *= CoordZ;
+ ConstrainPosition2[2] *= CoordZ;
+ writer.Write(MMDModel1.GetBytes(Name, 20));
+ writer.Write(RigidBodyA);
+ writer.Write(RigidBodyB);
+ for (int i = 0; i < Position.Length; i++)
+ writer.Write(Position[i]* scale);
+ for (int i = 0; i < Rotation.Length; i++)
+ writer.Write(Rotation[i]);
+ for (int i = 0; i < ConstrainPosition1.Length; i++)
+ writer.Write(ConstrainPosition1[i]*scale);
+ for (int i = 0; i < ConstrainPosition2.Length; i++)
+ writer.Write(ConstrainPosition2[i]*scale);
+ for (int i = 0; i < ConstrainRotation1.Length; i++)
+ writer.Write(ConstrainRotation1[i]);
+ for (int i = 0; i < ConstrainRotation2.Length; i++)
+ writer.Write(ConstrainRotation2[i]);
+ for (int i = 0; i < SpringPosition.Length; i++)
+ writer.Write(SpringPosition[i]*scale);
+ for (int i = 0; i < SpringRotation.Length; i++)
+ writer.Write(SpringRotation[i]);
+ }
+ }
+}
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDModelLibrary/Ver1/ModelMaterial.cs b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDModelLibrary/Ver1/ModelMaterial.cs
new file mode 100644
index 000000000..d7be53489
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDModelLibrary/Ver1/ModelMaterial.cs
@@ -0,0 +1,126 @@
+using System;
+using System.IO;
+using DWORD = System.UInt32;
+
+namespace MikuMikuDance.Model.Ver1
+{
+ ///
+ /// モデルの材質
+ ///
+ public class ModelMaterial
+ {
+ ///
+ /// rgbの減衰色
+ ///
+ public float[] DiffuseColor { get; private set; } // dr, dg, db // 減衰色
+ ///
+ /// α値
+ ///
+ public float Alpha { get; set; }
+ ///
+ /// 光沢
+ ///
+ public float Specularity { get; set; }
+ ///
+ /// 光沢色(rgb)
+ ///
+ public float[] SpecularColor { get; private set; } // sr, sg, sb // 光沢色
+ ///
+ /// 環境色(ambient)(rgb)
+ ///
+ public float[] MirrorColor { get; private set; } // mr, mg, mb // 環境色(ambient)
+ ///
+ /// 使用するトゥーンbmp番号
+ ///
+ /// 使用する場合は0から9までの番号。使用しない場合は0xFF
+ public byte ToonIndex { get; set; } // toon??.bmp // 0.bmp:0xFF, 1(01).bmp:0x00 ・・・ 10.bmp:0x09
+ ///
+ /// 輪郭、影
+ ///
+ public byte EdgeFlag { get; set; } // 輪郭、影
+ ///
+ /// 面頂点数
+ ///
+ public DWORD FaceVertCount { get; set; } // 面頂点数 // インデックスに変換する場合は、材質0から順に加算
+ ///
+ /// テクスチャファイル名
+ ///
+ public string TextureFileName { get; set; } //20byte分char テクスチャファイル名 // 20バイトぎりぎりまで使える(終端の0x00は無くても動く)
+ ///
+ /// スフィアマップファイル名
+ ///
+ public string SphereTextureFileName { get; set; }
+ ///
+ /// 既定のコンストラクタ
+ ///
+ public ModelMaterial()
+ {
+ DiffuseColor = new float[3];
+ SpecularColor = new float[3];
+ MirrorColor = new float[3];
+ TextureFileName = "";
+ SphereTextureFileName = "";
+ }
+ internal void Read(BinaryReader reader)
+ {
+ DiffuseColor = new float[3];
+ SpecularColor = new float[3];
+ MirrorColor = new float[3];
+ for (int i = 0; i < DiffuseColor.Length; i++)
+ DiffuseColor[i] = BitConverter.ToSingle(reader.ReadBytes(4), 0);
+ Alpha = BitConverter.ToSingle(reader.ReadBytes(4), 0);
+ Specularity = BitConverter.ToSingle(reader.ReadBytes(4), 0);
+ for (int i = 0; i < SpecularColor.Length; i++)
+ SpecularColor[i] = BitConverter.ToSingle(reader.ReadBytes(4), 0);
+ for (int i = 0; i < MirrorColor.Length; i++)
+ MirrorColor[i] = BitConverter.ToSingle(reader.ReadBytes(4), 0);
+ ToonIndex = reader.ReadByte();
+ EdgeFlag = reader.ReadByte();
+ FaceVertCount = BitConverter.ToUInt32(reader.ReadBytes(4), 0);
+ string FileName = MMDModel1.GetString(reader.ReadBytes(20));
+ string[] FileNames = FileName.Split('*');
+ TextureFileName = "";
+ SphereTextureFileName = "";
+ foreach (string s in FileNames)
+ {
+ string ext = Path.GetExtension(s).ToLower();
+ if (ext == ".sph" || ext == ".spa")
+ {
+ SphereTextureFileName = s.Trim();
+ }
+ else
+ {
+ TextureFileName = s.Trim();
+ }
+ }
+ }
+
+ internal void Write(BinaryWriter writer)
+ {
+ for (int i = 0; i < DiffuseColor.Length; i++)
+ writer.Write(DiffuseColor[i]);
+ writer.Write(Alpha);
+ writer.Write(Specularity);
+ for (int i = 0; i < SpecularColor.Length; i++)
+ writer.Write(SpecularColor[i]);
+ for (int i = 0; i < MirrorColor.Length; i++)
+ writer.Write(MirrorColor[i]);
+ writer.Write(ToonIndex);
+ writer.Write(EdgeFlag);
+ writer.Write(FaceVertCount);
+ string FileName = TextureFileName;
+ if (string.IsNullOrEmpty(FileName))
+ {
+ FileName = SphereTextureFileName;
+ }
+ else
+ {
+ if (!string.IsNullOrEmpty(SphereTextureFileName))
+ {
+ FileName += "*" + SphereTextureFileName;
+ }
+ }
+ writer.Write(MMDModel1.GetBytes(FileName, 20));
+ }
+ }
+}
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDModelLibrary/Ver1/ModelRigidBody.cs b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDModelLibrary/Ver1/ModelRigidBody.cs
new file mode 100644
index 000000000..8ba64c776
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDModelLibrary/Ver1/ModelRigidBody.cs
@@ -0,0 +1,140 @@
+using System;
+using System.IO;
+using WORD = System.UInt16;
+
+namespace MikuMikuDance.Model.Ver1
+{
+ ///
+ /// 剛体(物理演算用)
+ ///
+ public class ModelRigidBody
+ {
+ ///
+ /// 名称
+ ///
+ public string Name { get; set; } // 諸データ:名称 // 頭(20byte char)
+ ///
+ /// 関連ボーン番号
+ ///
+ public WORD RelatedBoneIndex { get; set; } // 諸データ:関連ボーン番号 // 03 00 == 3 // 頭
+ ///
+ /// グループ番号
+ ///
+ public byte GroupIndex { get; set; } // 諸データ:グループ // 00
+ ///
+ /// 衝突対象グループ
+ ///
+ /// 各ビットがグループ番号に対応しており、ビットが立ってなければそのグループとは衝突しないという実装
+ public WORD GroupTarget { get; set; } // 諸データ:グループ:対象 // 0xFFFFとの差 // 38 FE
+ ///
+ /// 形状
+ ///
+ /// 0:球、1:箱、2:カプセル
+ public byte ShapeType { get; set; } // 形状:タイプ(0:球、1:箱、2:カプセル) // 00 // 球
+ ///
+ /// 半径(幅)
+ ///
+ public float ShapeWidth { get; set; } // 形状:半径(幅) // CD CC CC 3F // 1.6
+ ///
+ /// 高さ
+ ///
+ public float ShapeHeight { get; set; } // 形状:高さ // CD CC CC 3D // 0.1
+ ///
+ /// 奥行き
+ ///
+ public float ShapeDepth { get; set; } // 形状:奥行 // CD CC CC 3D // 0.1
+ ///
+ /// 位置(x,y,z)
+ ///
+ public float[] Position { get; protected set; } //float*3 位置:位置(x, y, z)
+ ///
+ /// 回転
+ ///
+ public float[] Rotation { get; protected set; } //float*3 位置:回転(rad(x), rad(y), rad(z))
+ ///
+ /// 質量
+ ///
+ public float Weight { get; set; } // 諸データ:質量 // 00 00 80 3F // 1.0
+ ///
+ /// ダンピング1
+ ///
+ public float LinerDamping { get; set; } // 諸データ:移動減 // 00 00 00 00
+ ///
+ /// ダンピング2
+ ///
+ public float AngularDamping { get; set; } // 諸データ:回転減 // 00 00 00 00
+ ///
+ /// 反発係数
+ ///
+ public float Restitution { get; set; } // 諸データ:反発力 // 00 00 00 00
+ ///
+ /// 摩擦力
+ ///
+ public float Friction { get; set; } // 諸データ:摩擦力 // 00 00 00 00
+ ///
+ /// 剛体タイプ
+ ///
+ /// 0:Bone追従、1:物理演算、2:物理演算(Bone位置合せ)
+ public byte Type { get; set; } // 諸データ:タイプ(0:Bone追従、1:物理演算、2:物理演算(Bone位置合せ)) // 00 // Bone追従
+ ///
+ /// 既定のコンストラクタ
+ ///
+ public ModelRigidBody()
+ {
+ Position = new float[3];
+ Rotation = new float[3];
+ }
+
+ internal void ReadExpantion(BinaryReader reader, float CoordZ, float scale)
+ {
+ Name = MMDModel1.GetString(reader.ReadBytes(20));
+ RelatedBoneIndex = BitConverter.ToUInt16(reader.ReadBytes(2), 0);
+ GroupIndex = reader.ReadByte();
+ GroupTarget = BitConverter.ToUInt16(reader.ReadBytes(2), 0);
+ ShapeType = reader.ReadByte();
+ ShapeWidth = BitConverter.ToSingle(reader.ReadBytes(4), 0)*scale;
+ ShapeHeight = BitConverter.ToSingle(reader.ReadBytes(4), 0)*scale;
+ ShapeDepth = BitConverter.ToSingle(reader.ReadBytes(4), 0)*scale;
+ for (int i = 0; i < Position.Length; i++)
+ Position[i] = BitConverter.ToSingle(reader.ReadBytes(4), 0) * scale;
+ for (int i = 0; i < Rotation.Length; i++)
+ Rotation[i] = BitConverter.ToSingle(reader.ReadBytes(4), 0);
+ Weight = BitConverter.ToSingle(reader.ReadBytes(4), 0);
+ LinerDamping = BitConverter.ToSingle(reader.ReadBytes(4), 0);
+ AngularDamping = BitConverter.ToSingle(reader.ReadBytes(4), 0);
+ Restitution = BitConverter.ToSingle(reader.ReadBytes(4), 0);
+ Friction = BitConverter.ToSingle(reader.ReadBytes(4), 0);
+ Type = reader.ReadByte();
+ Position[2] *= CoordZ;
+ //メモ:左手→右手では位置が変換される際に一緒に回転成分が変換されるため、回転の変換は必要ない……のだが
+ //剛体はモデルと違い、位置と回転情報だけなので、回転を変換する必要がある
+ Rotation[0] *= CoordZ;
+ Rotation[1] *= CoordZ;
+ }
+
+ internal void WriteExpantion(BinaryWriter writer, float CoordZ, float scale)
+ {
+ Position[2] *= CoordZ;
+ Rotation[0] *= CoordZ;
+ Rotation[1] *= CoordZ;
+ writer.Write(MMDModel1.GetBytes(Name, 20));
+ writer.Write(RelatedBoneIndex);
+ writer.Write(GroupIndex);
+ writer.Write(GroupTarget);
+ writer.Write(ShapeType);
+ writer.Write(ShapeWidth * scale);
+ writer.Write(ShapeHeight * scale);
+ writer.Write(ShapeDepth * scale);
+ for (int i = 0; i < Position.Length; i++)
+ writer.Write(Position[i] * scale);
+ for (int i = 0; i < Rotation.Length; i++)
+ writer.Write(Rotation[i]);
+ writer.Write(Weight);
+ writer.Write(LinerDamping);
+ writer.Write(AngularDamping);
+ writer.Write(Restitution);
+ writer.Write(Friction);
+ writer.Write(Type);
+ }
+ }
+}
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDModelLibrary/Ver1/ModelSkin.cs b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDModelLibrary/Ver1/ModelSkin.cs
new file mode 100644
index 000000000..bd3c50abe
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDModelLibrary/Ver1/ModelSkin.cs
@@ -0,0 +1,114 @@
+using System;
+using System.IO;
+using DWORD = System.UInt32;
+
+namespace MikuMikuDance.Model.Ver1
+{
+ ///
+ /// 表情用の頂点のデータ
+ ///
+ public class ModelSkinVertexData
+ {
+
+ //base時=表情用の頂点の番号(頂点リストにある番号)
+ //base以外=表情用の頂点の番号(baseの番号。skin_vert_index)
+ ///
+ /// 頂点番号
+ ///
+ ///
+ /// base時=表情用の頂点の番号(頂点リストにある番号)
+ /// base以外=表情用の頂点の番号(baseの番号。skin_vert_index)
+ ///
+ public DWORD SkinVertIndex { get; set; }
+
+ //base時=x, y, z // 表情用の頂点の座標(頂点自体の座標)
+ //base以外=x, y, z // 表情用の頂点の座標オフセット値(baseに対するオフセット)
+ ///
+ /// 表情用の頂点の座標リスト
+ ///
+ ///
+ /// base時=x, y, z // 表情用の頂点の座標(頂点自体の座標)
+ /// base以外=x, y, z // 表情用の頂点の座標オフセット値(baseに対するオフセット)
+ ///
+ public float[] SkinVertPos { get; private set; } //
+ ///
+ /// 既定のコンストラクタ
+ ///
+ public ModelSkinVertexData()
+ {
+ SkinVertPos = new float[3];
+ }
+ internal void Read(BinaryReader reader, float CoordZ, float scale)
+ {
+ SkinVertIndex = BitConverter.ToUInt32(reader.ReadBytes(4), 0);
+ for (int i = 0; i < SkinVertPos.Length; i++)
+ SkinVertPos[i] = BitConverter.ToSingle(reader.ReadBytes(4), 0)* scale;
+ SkinVertPos[2] *= CoordZ;
+ }
+
+ internal void Write(BinaryWriter writer, float CoordZ, float scale)
+ {
+ SkinVertPos[2] *= CoordZ;
+ writer.Write(SkinVertIndex);
+ for (int i = 0; i < SkinVertPos.Length; i++)
+ writer.Write(SkinVertPos[i] * scale);
+ }
+ }
+ ///
+ /// 表情
+ ///
+ public class ModelSkin
+ {
+ ///
+ /// 表情名
+ ///
+ public string SkinName { get; set; } // 表情名(char[20])
+ //public DWORD skin_vert_count { get; set; } // 表情用の頂点数-SkinVertDatasのLengthで参照
+ ///
+ /// 表情の種類
+ ///
+ /// 0:base、1:まゆ、2:目、3:リップ、4:その他
+ public byte SkinType { get; set; } // 表情の種類(byte) // 0:base、1:まゆ、2:目、3:リップ、4:その他
+ ///
+ /// 表情用の頂点のデータリスト
+ ///
+ public ModelSkinVertexData[] SkinVertDatas { get; set; } // 表情用の頂点のデータ(16Bytes/vert) *skin_vert_count
+ ///
+ /// 表情名(英語、拡張)
+ ///
+ public string SkinNameEnglish { get; set; }//表示名(char[20]、英語)(拡張)
+ internal void Read(BinaryReader reader, float CoordZ, float scale)
+ {
+ SkinName = MMDModel1.GetString(reader.ReadBytes(20));
+ DWORD skin_vert_count = BitConverter.ToUInt32(reader.ReadBytes(4), 0);
+ SkinType = reader.ReadByte();
+ SkinVertDatas = new ModelSkinVertexData[skin_vert_count];
+ for (int i = 0; i < SkinVertDatas.Length; i++)
+ {
+ SkinVertDatas[i] = new ModelSkinVertexData();
+ SkinVertDatas[i].Read(reader, CoordZ, scale);
+ }
+ SkinNameEnglish = null;
+ }
+ internal void ReadExpantion(BinaryReader reader)
+ {
+ SkinNameEnglish = MMDModel1.GetString(reader.ReadBytes(20));
+ }
+
+ internal void Write(BinaryWriter writer, float CoordZ, float scale)
+ {
+ writer.Write(MMDModel1.GetBytes(SkinName,20));
+ writer.Write((DWORD)SkinVertDatas.Length);
+ writer.Write(SkinType);
+ for (int i = 0; i < SkinVertDatas.Length; i++)
+ {
+ SkinVertDatas[i].Write(writer, CoordZ, scale);
+ }
+ }
+
+ internal void WriteExpantion(BinaryWriter writer)
+ {
+ writer.Write(MMDModel1.GetBytes(SkinNameEnglish, 20));
+ }
+ }
+}
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDModelLibrary/Ver1/ModelVertex.cs b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDModelLibrary/Ver1/ModelVertex.cs
new file mode 100644
index 000000000..e73781d6b
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDModelLibrary/Ver1/ModelVertex.cs
@@ -0,0 +1,89 @@
+using System;
+using System.IO;
+using WORD = System.UInt16;
+
+namespace MikuMikuDance.Model.Ver1
+{
+ ///
+ /// モデルの頂点
+ ///
+ public class ModelVertex
+ {
+ ///
+ /// x,y,z座標
+ ///
+ public float[] Pos { get; private set; } // x, y, z // 座標
+ ///
+ /// x,y,zの法線ベクトル
+ ///
+ public float[] NormalVector { get; private set; } // nx, ny, nz // 法線ベクトル
+ ///
+ /// UV座標(頂点UV)
+ ///
+ public float[] UV { get; private set; } // u, v // UV座標 // MMDは頂点UV
+ ///
+ /// ボーン番号
+ ///
+ /// 番号は1または2。モデル変形(頂点移動)時に影響
+ public WORD[] BoneNum { get; private set; } // ボーン番号1、番号2 // モデル変形(頂点移動)時に影響
+ ///
+ /// 影響度
+ ///
+ /// ボーン1に与える影響度。min:0 max:100。ボーン2への影響度は、(100 - BoneWeight)
+ public byte BoneWeight { get; private set; } // ボーン1に与える影響度 // min:0 max:100 // ボーン2への影響度は、(100 - bone_weight)
+ ///
+ /// エッジフラグ
+ ///
+ /// 0:通常、1:エッジ無効(エッジ(輪郭)が有効の場合)
+ public byte NonEdgeFlag { get; private set; } // 0:通常、1:エッジ無効 // エッジ(輪郭)が有効の場合
+ ///
+ /// 既定のコンストラクタ
+ ///
+ public ModelVertex()
+ {
+ Pos = new float[3];
+ NormalVector = new float[3];
+ UV = new float[2];
+ BoneNum = new WORD[2];
+ BoneWeight = 0;
+ NonEdgeFlag = 0;
+ }
+ internal void Read(BinaryReader reader, float CoordZ, float scale)
+ {
+ //サイズ
+ Pos = new float[3];
+ NormalVector = new float[3];
+ UV = new float[2];
+ BoneNum = new WORD[2];
+ for (int i = 0; i < Pos.Length; i++)
+ Pos[i] = BitConverter.ToSingle(reader.ReadBytes(4), 0) * scale;
+ for (int i = 0; i < NormalVector.Length; i++)
+ NormalVector[i] = BitConverter.ToSingle(reader.ReadBytes(4), 0);
+ for (int i = 0; i < UV.Length; i++)
+ UV[i] = BitConverter.ToSingle(reader.ReadBytes(4), 0);
+ for (int i = 0; i < BoneNum.Length; i++)
+ BoneNum[i] = BitConverter.ToUInt16(reader.ReadBytes(2), 0);
+ BoneWeight = reader.ReadByte();
+ NonEdgeFlag = reader.ReadByte();
+ Pos[2] = Pos[2] * CoordZ;
+ NormalVector[2] = NormalVector[2] * CoordZ;
+ }
+
+ internal void Write(BinaryWriter writer, float CoordZ, float scale)
+ {
+ Pos[2] = Pos[2] * CoordZ;
+ NormalVector[2] = NormalVector[2] * CoordZ*scale;
+ for (int i = 0; i < Pos.Length; i++)
+ writer.Write(Pos[i]);
+ for (int i = 0; i < NormalVector.Length; i++)
+ writer.Write(NormalVector[i]);
+ for (int i = 0; i < UV.Length; i++)
+ writer.Write(UV[i]);
+ for (int i = 0; i < BoneNum.Length; i++)
+ writer.Write(BoneNum[i]);
+ writer.Write(BoneWeight);
+ writer.Write(NonEdgeFlag);
+ }
+
+ }
+}
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDMotionLibrary/CoordinateType.cs b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDMotionLibrary/CoordinateType.cs
new file mode 100644
index 000000000..5f867a2b0
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDMotionLibrary/CoordinateType.cs
@@ -0,0 +1,20 @@
+
+namespace MikuMikuDance.Motion
+{
+ ///
+ /// 座標系を表す列挙体
+ ///
+ public enum CoordinateType
+ {
+ ///
+ /// 左手座標系
+ ///
+ /// MMDの標準座標系
+ LeftHandedCoordinate = 1,
+ ///
+ /// 右手座標系
+ ///
+ /// XNAの標準座標系
+ RightHandedCoordinate = -1,
+ }
+}
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDMotionLibrary/MMDMotion.cs b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDMotionLibrary/MMDMotion.cs
new file mode 100644
index 000000000..56d517c37
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDMotionLibrary/MMDMotion.cs
@@ -0,0 +1,40 @@
+using System.IO;
+
+namespace MikuMikuDance.Motion
+{
+ ///
+ /// MMDモーションを表すインターフェイス
+ ///
+ public interface MMDMotion
+ {
+ ///
+ /// MMDモーションバージョン番号
+ ///
+ int Version { get; }
+ ///
+ /// Read関数
+ ///
+ /// この関数はModelManagerから呼び出される。呼び出し時にはマジック文字とバージョン番号が読まれた状態で渡される
+ /// マジック文字とバージョン番号読み込み済みのBinaryReader
+ /// 変換先座標系
+ /// スケーリング値
+ void Read(BinaryReader reader, CoordinateType coordinate, float scale);
+ ///
+ /// 保持しているデータの座標系
+ ///
+ CoordinateType Coordinate { get; }
+#if false
+ ///
+ /// スケーリング
+ ///
+ /// 拡大倍率
+ void Scale(float ScaleFactor);
+#endif
+ ///
+ /// モーションの書き出し
+ ///
+ /// 書き出し
+ /// スケーリング値
+ void Write(BinaryWriter writer, float scale);
+ }
+}
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDMotionLibrary/Motion2/CameraMotionData.cs b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDMotionLibrary/Motion2/CameraMotionData.cs
new file mode 100644
index 000000000..503e3d8ce
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDMotionLibrary/Motion2/CameraMotionData.cs
@@ -0,0 +1,93 @@
+using System;
+using System.IO;
+using DWORD = System.UInt32;
+using WORD = System.UInt16;
+
+namespace MikuMikuDance.Motion.Motion2
+{
+ ///
+ /// カメラモーションデータ
+ ///
+ public class CameraMotionData
+ {
+ ///
+ /// フレーム番号
+ ///
+ public DWORD FrameNo { get; set; }
+ ///
+ /// 長さ
+ ///
+ public float Length { get; set; }
+ ///
+ /// 位置
+ ///
+ public float[] Location { get; protected set; }
+ ///
+ /// 回転
+ ///
+ public float[] Rotate { get; protected set; }
+ ///
+ /// 補完データ
+ ///
+ public byte[][] Interpolation { get; protected set; }
+ ///
+ /// 視野角
+ ///
+ public WORD ViewingAngle { get; protected set; }
+ ///
+ /// 不明データ
+ ///
+ /// だれか教えてくれ(´・ω・`)
+ public byte[] Unknown { get; protected set; }
+ ///
+ /// 既定のコンストラクタ
+ ///
+ public CameraMotionData()
+ {
+ Location = new float[3];
+ Rotate = new float[3];
+ Interpolation = new byte[6][];
+ for (int i = 0; i < 6; i++)
+ Interpolation[i] = new byte[4];
+ Unknown = new byte[3];
+ }
+
+ internal void Read(BinaryReader reader, float CoordZ)
+ {
+ FrameNo = BitConverter.ToUInt32(reader.ReadBytes(4), 0);
+ Length = BitConverter.ToSingle(reader.ReadBytes(4), 0);
+ for (int i = 0; i < 3; i++)
+ Location[i] = BitConverter.ToSingle(reader.ReadBytes(4), 0);
+ for (int i = 0; i < 3; i++)
+ Rotate[i] = BitConverter.ToSingle(reader.ReadBytes(4), 0);
+ for (int i = 0; i < 6; i++)
+ for (int j = 0; j < 4; j++)
+ Interpolation[i][j] = reader.ReadByte();
+ ViewingAngle = BitConverter.ToUInt16(reader.ReadBytes(2), 0);
+ for (int i = 0; i < 3; i++)
+ Unknown[i] = reader.ReadByte();
+ Location[2] *= CoordZ;
+ Rotate[2] *= CoordZ;
+ /*Rotate[0] *= CoordZ;
+ Rotate[1] *= CoordZ;*/
+ }
+
+ internal void Write(BinaryWriter writer, float CoordZ)
+ {
+ writer.Write((DWORD)FrameNo);
+ writer.Write((Single)Length);
+ writer.Write((Single)Location[0]);
+ writer.Write((Single)Location[1]);
+ writer.Write((Single)Location[2] * CoordZ);
+ writer.Write((Single)Rotate[0]);
+ writer.Write((Single)Rotate[1]);
+ writer.Write((Single)Rotate[2] * CoordZ);
+ for (int i = 0; i < 6; i++)
+ for (int j = 0; j < 4; j++)
+ writer.Write((byte)Interpolation[i][j]);
+ writer.Write((WORD)ViewingAngle);
+ for (int i = 0; i < 3; i++)
+ writer.Write((byte)Unknown[i]);
+ }
+ }
+}
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDMotionLibrary/Motion2/FaceMotionData.cs b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDMotionLibrary/Motion2/FaceMotionData.cs
new file mode 100644
index 000000000..5f6e20af9
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDMotionLibrary/Motion2/FaceMotionData.cs
@@ -0,0 +1,39 @@
+using System;
+using System.IO;
+using DWORD = System.UInt32;
+
+namespace MikuMikuDance.Motion.Motion2
+{
+ ///
+ /// フェイスモーションデータ
+ ///
+ public class FaceMotionData
+ {
+ ///
+ /// 表情適応割合
+ ///
+ public float Rate { get; set; }
+ ///
+ /// 表情名
+ ///
+ public string FaceName { get; set; }//[15];
+ ///
+ /// フレームナンバー
+ ///
+ public DWORD FrameNo { get; set; }
+ internal void Read(BinaryReader reader)
+ {
+ FaceName = MMDMotion2.GetString(reader.ReadBytes(15));
+ FrameNo = BitConverter.ToUInt32(reader.ReadBytes(4), 0);
+ //Wait = BitConverter.ToUInt32(reader.ReadBytes(4), 0);
+ Rate = BitConverter.ToSingle(reader.ReadBytes(4), 0);
+ }
+
+ internal void Write(BinaryWriter writer)
+ {
+ writer.Write(MMDMotion2.GetBytes(FaceName, 15));
+ writer.Write((DWORD)FrameNo);
+ writer.Write((Single)Rate);
+ }
+ }
+}
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDMotionLibrary/Motion2/LightMotionData.cs b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDMotionLibrary/Motion2/LightMotionData.cs
new file mode 100644
index 000000000..9962f4394
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDMotionLibrary/Motion2/LightMotionData.cs
@@ -0,0 +1,46 @@
+using System;
+using System.IO;
+using DWORD = System.UInt32;
+
+namespace MikuMikuDance.Motion.Motion2
+{
+ ///
+ /// ライトモーションデータ
+ ///
+ public class LightMotionData
+ {
+ ///
+ /// フレームナンバー
+ ///
+ public DWORD FrameNo { get; set; }
+ ///
+ /// ライトの色
+ ///
+ public float[] Color { get; protected set; }
+ ///
+ /// ライトの位置
+ ///
+ public float[] Location { get; protected set; }
+ internal void Read(BinaryReader reader, float CoordZ)
+ {
+ FrameNo = BitConverter.ToUInt32(reader.ReadBytes(4), 0);
+ Color = new float[3];
+ Location = new float[3];
+ for (int i = 0; i < 3; i++)
+ Color[i] = BitConverter.ToSingle(reader.ReadBytes(4), 0);
+ for (int i = 0; i < 3; i++)
+ Location[i] = BitConverter.ToSingle(reader.ReadBytes(4), 0);
+ Location[2] *= CoordZ;
+ }
+
+ internal void Write(BinaryWriter writer, float CoordZ)
+ {
+ writer.Write((DWORD)FrameNo);
+ for (int i = 0; i < 3; i++)
+ writer.Write((Single)Color[i]);
+ writer.Write((Single)Location[0]);
+ writer.Write((Single)Location[1]);
+ writer.Write((Single)Location[2] * CoordZ);
+ }
+ }
+}
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDMotionLibrary/Motion2/MMDMotion2.cs b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDMotionLibrary/Motion2/MMDMotion2.cs
new file mode 100644
index 000000000..e6494972e
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDMotionLibrary/Motion2/MMDMotion2.cs
@@ -0,0 +1,197 @@
+using System;
+using System.IO;
+using System.Text;
+using DWORD = System.UInt32;
+
+namespace MikuMikuDance.Motion.Motion2
+{
+ ///
+ /// MMDのモーションデータVer2を読み込むためのクラス
+ ///
+ ///
+ /// ver2はモーションのヘッダがVocaloid Motion Data 0002と書かれてるから。
+ /// 正式なバージョンは知らんw
+ ///
+ public class MMDMotion2 : MMDMotion
+ {
+ internal MotionData[] m_Motions;
+ ///
+ /// モーションで使用するモデル名
+ ///
+ public string ModelName { get; set; }
+ ///
+ /// ボーンモーションリスト
+ ///
+ public MotionData[] Motions { get { return m_Motions; } set { m_Motions = value; } }
+ ///
+ /// フェイスモーションリスト
+ ///
+ public FaceMotionData[] FaceMotions { get; set; }
+ ///
+ /// カメラモーションリスト
+ ///
+ public CameraMotionData[] CameraMotions { get; set; }
+ ///
+ /// ライトモーションリスト
+ ///
+ public LightMotionData[] LightMotions { get; set; }
+ //members and properties...
+ ///
+ /// Version番号。MMDMotionから継承されます
+ ///
+ public int Version
+ {
+ get { return 2; }
+ }
+ ///
+ /// 保持しているデータの座標き
+ ///
+ public CoordinateType Coordinate { get; set; }
+ //座標変換用ヘルパ関数
+ float CoordZ { get { return (float)Coordinate; } }
+
+ //methods...
+ ///
+ /// Read関数
+ ///
+ /// この関数はMotionManagerから呼び出される。呼び出し時にはマジック文字とバージョン番号が読まれた状態で渡される
+ /// ヘッダ読み込み済みのBinaryReader
+ /// 変換先座標系
+ /// スケーリング値
+ public void Read(BinaryReader reader, CoordinateType coordinate, float scale)
+ {
+ Coordinate = coordinate;//座標系セット
+ //モデル名読み込み
+ ModelName = GetString(reader.ReadBytes(20));
+ //ボーンモーションデータ読み込み
+ DWORD motion_count = BitConverter.ToUInt32(reader.ReadBytes(4), 0);
+ Motions = new MotionData[motion_count];
+ for (long i = 0; i < Motions.LongLength; i++)
+ {
+ Motions[i] = new MotionData();
+ Motions[i].Read(reader, CoordZ, scale);
+ }
+ //フェイスモーションデータ読み込み
+ DWORD face_count = BitConverter.ToUInt32(reader.ReadBytes(4), 0);
+ FaceMotions = new FaceMotionData[face_count];
+ for (long i = 0; i < FaceMotions.LongLength; i++)
+ {
+ FaceMotions[i] = new FaceMotionData();
+ FaceMotions[i].Read(reader);
+ }
+ //カメラモーション読み込み
+ DWORD camera_count = BitConverter.ToUInt32(reader.ReadBytes(4), 0);
+ CameraMotions = new CameraMotionData[camera_count];
+ for (long i = 0; i < CameraMotions.LongLength; i++)
+ {
+ CameraMotions[i] = new CameraMotionData();
+ CameraMotions[i].Read(reader, CoordZ);
+ }
+ //ライトモーション読み込み
+ DWORD light_count = BitConverter.ToUInt32(reader.ReadBytes(4), 0);
+ LightMotions = new LightMotionData[light_count];
+ for (long i = 0; i < LightMotions.LongLength; i++)
+ {
+ LightMotions[i] = new LightMotionData();
+ LightMotions[i].Read(reader, CoordZ);
+ }
+ }
+ ///
+ /// ヘッダ以外の書き出し
+ ///
+ /// ファイル書き出し用のBinaryWriter
+ /// スケーリング値
+ public void Write(BinaryWriter writer, float scale)
+ {
+ //モデル名読み込み
+ writer.Write(GetBytes(ModelName, 20));
+ //ボーンモーションデータ読み込み
+ writer.Write((DWORD)Motions.LongLength);
+ for (long i = 0; i < Motions.LongLength; i++)
+ {
+ Motions[i].Write(writer, CoordZ, scale);
+ }
+ //フェイスモーションデータ読み込み
+ writer.Write((DWORD)FaceMotions.LongLength);
+ for (long i = 0; i < FaceMotions.LongLength; i++)
+ {
+ FaceMotions[i].Write(writer);
+ }
+ //カメラモーション読み込み
+ writer.Write((DWORD)CameraMotions.LongLength);
+ for (long i = 0; i < CameraMotions.LongLength; i++)
+ {
+ CameraMotions[i].Write(writer, CoordZ);
+ }
+ //ライトモーション読み込み
+ writer.Write((DWORD)LightMotions.LongLength);
+ for (long i = 0; i < LightMotions.LongLength; i++)
+ {
+ LightMotions[i].Write(writer, CoordZ);
+ }
+ }
+#if false
+ ///
+ /// スケーリング
+ ///
+ /// 拡大倍率
+ public void Scale(float ScaleFactor)
+ {
+ if (ScaleFactor <= 0)
+ throw new ApplicationException("ScaleFactorは正の実数である必要があります。");
+ //ボーン
+ for (long i = 0; i < Motions.LongLength; i++)
+ {
+ for (int j = 0; j < Motions[i].Location.Length; j++)
+ {
+ Motions[i].Location[j] = Motions[i].Location[j] * ScaleFactor;
+ }
+
+ }
+ //カメラ
+ for (long i = 0; i < CameraMotions.LongLength; i++)
+ {
+ CameraMotions[i].Length=CameraMotions[i].Length*ScaleFactor;
+ for (int j = 0; j < CameraMotions[i].Location.Length; j++)
+ CameraMotions[i].Location[j] = CameraMotions[i].Location[j] * ScaleFactor;
+ }
+ //ライトモーション
+ for (long i = 0; i < LightMotions.LongLength; i++)
+ {
+ for (int j = 0; j < LightMotions[i].Location.Length; j++)
+ LightMotions[i].Location[j] = LightMotions[i].Location[j] * ScaleFactor;
+ }
+ }
+#endif
+ //internal statics...
+ internal static Encoding encoder = Encoding.GetEncoding("shift-jis");
+ internal static string GetString(byte[] bytes)
+ {
+ int i;
+ for (i = 0; i < bytes.Length; i++)
+ if (bytes[i] == 0)
+ break;
+ if (i < bytes.Length)
+ return encoder.GetString(bytes, 0, i);
+ return encoder.GetString(bytes);
+ }
+ internal static byte[] GetBytes(string input, long size)
+ {
+ byte[] result = new byte[size];
+ for (long i = 0; i < size; i++)
+ result[i] = 0;
+ if (input == "")
+ return result;
+ byte[] strs = encoder.GetBytes(input);
+ for (long i = 0; i < strs.LongLength; i++)
+ if (i < result.LongLength)
+ result[i] = strs[i];
+ if (result.LongLength <= strs.LongLength)
+ return result;
+ result[strs.LongLength] = 0;
+ for (long i = strs.LongLength + 1; i < result.Length; i++)
+ result[i] = 0xFD;//何故かこれが挿入されているのでこれを挿入
+ return result;
+ }
+ }
+}
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDMotionLibrary/Motion2/MotionData.cs b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDMotionLibrary/Motion2/MotionData.cs
new file mode 100644
index 000000000..ceb9de665
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDMotionLibrary/Motion2/MotionData.cs
@@ -0,0 +1,81 @@
+using System;
+using System.IO;
+using DWORD = System.UInt32;
+
+namespace MikuMikuDance.Motion.Motion2
+{
+ ///
+ /// ボーンモーションデータ
+ ///
+ public class MotionData
+ {
+ ///
+ /// ボーン名
+ ///
+ public string BoneName { get; set; }//[15];
+ ///
+ /// フレーム番号
+ ///
+ public DWORD FrameNo { get; set; }
+ ///
+ /// 位置ベクトル
+ ///
+ public float[] Location { get; protected set; }
+ ///
+ /// クォータニオン
+ ///
+ public float[] Quatanion { get; protected set; }
+ ///
+ /// 補完データ
+ ///
+ public byte[][][] Interpolation { get; protected set; }
+ ///
+ /// 既定のコンストラクタ
+ ///
+ public MotionData()
+ {
+ Location = new float[3];
+ Quatanion = new float[4];
+ Interpolation = new byte[4][][];
+ for (int i = 0; i < 4; i++)
+ {
+ Interpolation[i] = new byte[4][];
+ for (int j = 0; j < 4; j++)
+ Interpolation[i][j] = new byte[4];
+ }
+ }
+ internal void Read(BinaryReader reader, float CoordZ, float scale)
+ {
+ BoneName = MMDMotion2.GetString(reader.ReadBytes(15));
+ FrameNo = BitConverter.ToUInt32(reader.ReadBytes(4), 0);
+ for (int i = 0; i < 3; i++)
+ Location[i] = BitConverter.ToSingle(reader.ReadBytes(4), 0) * scale;
+ for (int i = 0; i < 4; i++)
+ Quatanion[i] = BitConverter.ToSingle(reader.ReadBytes(4), 0);
+ for (int i = 0; i < 4; i++)
+ for (int j = 0; j < 4; j++)
+ for (int k = 0; k < 4; k++)
+ Interpolation[i][j][k] = reader.ReadByte();
+ Location[2] *= CoordZ;
+ Quatanion[0] *= CoordZ;
+ Quatanion[1] *= CoordZ;
+ }
+
+ internal void Write(BinaryWriter writer, float CoordZ, float scale)
+ {
+ writer.Write(MMDMotion2.GetBytes(BoneName, 15));
+ writer.Write((DWORD)FrameNo);
+ writer.Write((Single)Location[0]*scale);
+ writer.Write((Single)Location[1]*scale);
+ writer.Write((Single)Location[2] * CoordZ*scale);
+ writer.Write((Single)Quatanion[0] * CoordZ);
+ writer.Write((Single)Quatanion[1] * CoordZ);
+ writer.Write((Single)Quatanion[2]);
+ writer.Write((Single)Quatanion[3]);
+ for (int i = 0; i < 4; i++)
+ for (int j = 0; j < 4; j++)
+ for (int k = 0; k < 4; k++)
+ writer.Write((byte)Interpolation[i][j][k]);
+ }
+ }
+}
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDMotionLibrary/MotionManager.cs b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDMotionLibrary/MotionManager.cs
new file mode 100644
index 000000000..53b92e2f5
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDMotionLibrary/MotionManager.cs
@@ -0,0 +1,89 @@
+using System;
+using System.IO;
+using MikuMikuDance.Motion.Motion2;
+
+namespace MikuMikuDance.Motion
+{
+ ///
+ /// MikuMikuDance(MMD)モーションの読み込みを行うFactory Class
+ ///
+ public static class MotionManager
+ {
+ ///
+ /// ファイルからMMDモーションを読み込む
+ ///
+ /// MMDモーションファイル
+ /// 変換先座標系
+ /// MMDモーションオブジェクト
+ /// スケーリング値
+ public static MMDMotion Read(string filename, CoordinateType coordinate, float scale=1.0f)
+ {
+ //フルパス取得
+ filename = Path.GetFullPath(filename);
+ //ファイルチェック
+ if (!File.Exists(filename))
+ throw new FileNotFoundException("MMDモーションファイル:" + filename + "が見つかりません");
+ //戻り値用変数
+ MMDMotion result = null;
+ //ファイルリーダー
+ using (FileStream fs = new FileStream(filename, FileMode.Open))
+ {
+ BinaryReader reader = new BinaryReader(fs);
+ //マジック文字列
+ string magic = MMDMotion2.GetString(reader.ReadBytes(30));
+ if (magic.Substring(0, 20) != "Vocaloid Motion Data")
+ throw new FileLoadException("MMDモーションファイルではありません");
+ //バージョン
+ int version = Convert.ToInt32(magic.Substring(21));
+ if (version == 2)
+ result = new MMDMotion2();
+ else
+ throw new FileLoadException("version=" + version.ToString() + "モデルは対応していません");
+
+ result.Read(reader, coordinate,scale);
+ if (fs.Length != fs.Position)
+ Console.WriteLine("警告:ファイル末尾以降に不明データ?");
+ fs.Close();
+ }
+ return result;
+ }
+ ///
+ /// ファイルからMMDモーションを読み込む
+ ///
+ /// MMDモーションファイル
+ /// スケーリング値
+ /// MMDモーションオブジェクト
+ public static MMDMotion Read(string filename, float scale=0.1f)
+ {
+ return Read(filename, CoordinateType.LeftHandedCoordinate, scale);
+ }
+ ///
+ /// ファイルへの書き出し
+ ///
+ /// ファイル名
+ /// モーション
+ /// スケーリング値
+ public static void Write(string filename, MMDMotion motion, float scale=1f)
+ {
+ //フルパス取得
+ filename = Path.GetFullPath(filename);
+ //ファイルリーダー
+ using (FileStream fs = new FileStream(filename, FileMode.Create))
+ {
+ BinaryWriter writer = new BinaryWriter(fs);
+ //マジック文字列
+ if (motion is MMDMotion2)
+ {
+ writer.Write(MMDMotion2.GetBytes("Vocaloid Motion Data 0002", 25));
+ writer.Write((byte)0);
+ writer.Write(MMDMotion2.GetBytes("JKLM", 4));
+ }
+ else
+ new NotImplementedException("その他のバーションは未作成");
+
+ motion.Write(writer, scale);
+ fs.Close();
+ }
+ }
+ }
+}
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDMotionLibrary/Properties/AssemblyInfo.cs b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDMotionLibrary/Properties/AssemblyInfo.cs
new file mode 100644
index 000000000..2844cd0a6
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/MMDMotionLibrary/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// アセンブリに関する一般情報は以下の属性セットをとおして制御されます。
+// アセンブリに関連付けられている情報を変更するには、
+// これらの属性値を変更してください。
+[assembly: AssemblyTitle("MMDMotionLibrary")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("MMDMotionLibrary")]
+[assembly: AssemblyCopyright("Copyright © 2011 Wilfrem")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// ComVisible を false に設定すると、その型はこのアセンブリ内で COM コンポーネントから
+// 参照不可能になります。COM からこのアセンブリ内の型にアクセスする場合は、
+// その型の ComVisible 属性を true に設定してください。
+[assembly: ComVisible(false)]
+
+// 次の GUID は、このプロジェクトが COM に公開される場合の、typelib の ID です
+[assembly: Guid("0584ce0b-5284-42b4-9c40-1afe2917ccbd")]
+
+// アセンブリのバージョン情報は、以下の 4 つの値で構成されています:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// すべての値を指定するか、下のように '*' を使ってビルドおよびリビジョン番号を
+// 既定値にすることができます:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("2.0.0.0")]
+[assembly: AssemblyFileVersion("2.0.0.0")]
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/TraceAndTestImpact.testsettings b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/TraceAndTestImpact.testsettings
new file mode 100644
index 000000000..72e796275
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/.MMDIKBaker/TraceAndTestImpact.testsettings
@@ -0,0 +1,9 @@
+
+
+ これらは、トレースおよびテストの影響のテスト設定です。
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/.gitignore b/Assets/Scripts/3rd/mmd-for-unity-master/.gitignore
new file mode 100644
index 000000000..3257b55d6
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/.gitignore
@@ -0,0 +1,10 @@
+[Ll]ibrary/
+[Tt]emp/
+[Oo]bj/
+
+# Autogenerated VS/MD solution and project files
+*.csproj
+*.unityproj
+*.sln
+*.asset
+*.meta
\ No newline at end of file
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/CHANGE-LOG b/Assets/Scripts/3rd/mmd-for-unity-master/CHANGE-LOG
new file mode 100644
index 000000000..2ea7ed191
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/CHANGE-LOG
@@ -0,0 +1,74 @@
+-----ここからGitHUBでの開発-----
+【2.0b】
+GitHUBで開発された分をリリース.
+
+【2.0.14b】
+Configがうまくロードされない場合があるので対処
+マイナー以降のナンバリングはGitHUBのPullRequestに準拠
+
+-----ここまでSorceForge.jpのSVNで開発-----
+
+【r240】
+ここまでで対応したこと
+・PMXConverter
+ 頂点モーフ,UVモーフ,材質モーフ等
+・透過不透明,エッシ有無,影放ち有無,背面カリング有無の16種類のシェーダを使い分ける様に対応
+ 不透明度0.99の時に両面描画
+ 不透明度0.98の時にセルフシャドウを受けないマテリアル
+ エッジが無ければ影を放たない
+・物理演算のグローバル座標化等々
+・詳しい対応については以下のURL参照
+ http://sourceforge.jp/projects/mmd-for-unity/scm/svn/listCommit?skip=0
+
+【r121】
+・[readme.html] 使い方を追記
+ UnityでMMDを動かす会 として使い方を用意したほうがよさそうな.
+ SourceForgeのwikiとかバグ管理とか活用したいところ
+・[AvatarSettingScript.cs]Animator.MatchTargetの引数にWeightMaskが必要らしいので追加
+ 但し、これで正しいのかわからない。要検証
+・CCDIK周りの整理
+ 余計なコメント・ファイルの削除など
+
+既知の問題
+・Mechanim(Animator?)を使うのに必要なAvatorが生成されないため、Mechanimが使えない
+ -> http://forum.unity3d.com/threads/156951-Create-Mechanim-Avatar-in-editor-script
+ "in 4.0 we can only create Avatars in the ModelImporter" とのこと。
+ ばーじょんあっぷ待ち。
+
+
+【r120】
+MMDIKBakerのGUI版を追加。
+コンソール+VisualStudio必須だったものをそうでもない具合に。
+
+
+【r119】
+読み込み部分、移動の抽出を変更。ズレがなくなった模様
+
+
+【r117】
+改善したこと
+・IKの実装
+・VMD読み込み時の座標修正
+・Unity側に表示されるWarningの改善
+
+既知のバグ
+・VMD読み込み時にズレがでている(気がする
+・VMDの補間がUnity側に反映されていない
+
+
+【1.1a-r109】
+61回もマイナーバージョンアップしているわけではないので表記を変更
+
+改善したこと
+・トゥーンシェーダーに対応
+・表情を実装
+・剛体にも対応
+・一部、バグっているモデルについても対応
+
+既知のバグ
+・Lat式ミクの読み込みが不完全
+・複数の表情を動かせない
+・同じ複数のモデルを一つのシーンに入れて表情を動かすと全部同じ顔になる
+
+【1.61a】
+ひとまず動いている版
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/Editor/Config/Config.cs b/Assets/Scripts/3rd/mmd-for-unity-master/Editor/Config/Config.cs
new file mode 100644
index 000000000..9539ad53c
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/Editor/Config/Config.cs
@@ -0,0 +1,233 @@
+using UnityEngine;
+using UnityEditor;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using MMD.PMD;
+
+namespace MMD
+{
+ ///
+ /// MFU全体で必要そうなコンフィグ管理
+ ///
+ [Serializable]
+ public class Config : ScriptableObject
+ {
+ static Config config_ = null;
+ public InspectorConfig inspector_config = null;
+ public PMDImportConfig pmd_config = null;
+ public VMDImportConfig vmd_config = null;
+
+ private List update_list = null;
+ public void OnEnable()
+ {
+ if (inspector_config == null)
+ {
+ inspector_config = new InspectorConfig();
+ }
+ if (pmd_config == null)
+ {
+ pmd_config = new PMDImportConfig();
+ }
+ if (vmd_config == null)
+ {
+ vmd_config = new VMDImportConfig();
+ }
+ if (update_list == null)
+ {
+ update_list = new List();
+ update_list.Add(inspector_config);
+ update_list.Add(pmd_config);
+ update_list.Add(vmd_config);
+ }
+
+ hideFlags = HideFlags.None; //以前の書き換え不可assetが残っているかもしれないので明示的に書き換え可能を設定
+ }
+
+ ///
+ /// GUI描画処理
+ ///
+ public void OnGUI()
+ {
+ if (update_list == null) return;
+ update_list.ForEach((item) =>
+ {
+ item.OnGUI();
+ });
+
+ //変更確認
+ if (GUI.changed) {
+ EditorUtility.SetDirty(config_);
+ }
+ }
+
+ ///
+ /// Configが配置された場所から保存先を生成します
+ ///
+ /// アセット保存先のパス
+ public static string GetConfigPath()
+ {
+ var path = AssetDatabase.GetAllAssetPaths().Where(item => item.Contains("Config.cs")).First();
+ path = path.Substring(0, path.LastIndexOf('/') + 1) + "Config.asset";
+ return path;
+ }
+
+ ///
+ /// Config.assetを読み込みます。なかったら作ります。
+ ///
+ /// 読み込んで生成したConfigオブジェクト
+ public static Config LoadAndCreate()
+ {
+ if (config_ == null)
+ {
+ var path = Config.GetConfigPath();
+ config_ = (Config)AssetDatabase.LoadAssetAtPath(path, typeof(Config));
+
+ //// なかったら作成する
+ if (config_ == null)
+ {
+ config_ = CreateInstance();
+ AssetDatabase.CreateAsset(config_, path);
+ EditorUtility.SetDirty(config_);
+ }
+ }
+ return config_;
+ }
+ }
+
+ ///
+ ///インスペクタのコンフィグ
+ ///
+ [Serializable]
+ public class InspectorConfig : ConfigBase
+ {
+ public bool use_pmd_preload = true;
+ public bool use_vmd_preload = true;
+
+ public override string GetTitle()
+ {
+ return "Inspector Config";
+ }
+
+ public override void OnGUIFunction()
+ {
+ use_pmd_preload = EditorGUILayout.Toggle("Use PMD Preload", use_pmd_preload);
+ use_vmd_preload = EditorGUILayout.Toggle("Use VMD Preload", use_vmd_preload);
+ }
+
+ public InspectorConfig Clone()
+ {
+ return (InspectorConfig)MemberwiseClone();
+ }
+ }
+
+ ///
+ /// PMDインポートのコンフィグ
+ ///
+ [Serializable]
+ public class PMDImportConfig : ConfigBase
+ {
+ public PMDConverter.ShaderType shader_type = PMDConverter.ShaderType.MMDShader;
+ public PMXConverter.AnimationType animation_type = PMXConverter.AnimationType.LegacyAnimation;
+ public bool rigidFlag = true;
+ public bool use_ik = true;
+ public float scale = 0.085f;
+ public bool is_pmx_base_import = true;
+
+ public override string GetTitle()
+ {
+ return "Default PMD Import Config";
+ }
+
+ public override void OnGUIFunction()
+ {
+ shader_type = (PMDConverter.ShaderType)EditorGUILayout.EnumPopup("Shader Type", shader_type);
+ rigidFlag = EditorGUILayout.Toggle("Rigidbody", rigidFlag);
+ animation_type = (PMXConverter.AnimationType)EditorGUILayout.EnumPopup("Animation Type", animation_type);
+ use_ik = EditorGUILayout.Toggle("Use IK", use_ik);
+ scale = EditorGUILayout.Slider("Scale", scale, 0.001f, 1.0f);
+ EditorGUILayout.BeginHorizontal();
+ {
+ EditorGUILayout.PrefixLabel(" ");
+ if (GUILayout.Button("Original", EditorStyles.miniButtonLeft)) {
+ scale = 0.085f;
+ }
+ if (GUILayout.Button("1.0", EditorStyles.miniButtonRight)) {
+ scale = 1.0f;
+ }
+ }
+ EditorGUILayout.EndHorizontal();
+ is_pmx_base_import = EditorGUILayout.Toggle("Use PMX Base Import", is_pmx_base_import);
+ }
+
+ public PMDImportConfig Clone()
+ {
+ return (PMDImportConfig)MemberwiseClone();
+ }
+ }
+
+ ///
+ /// VMDインポートのコンフィグ
+ ///
+ [Serializable]
+ public class VMDImportConfig : ConfigBase
+ {
+ public bool createAnimationFile = false;
+ public int interpolationQuality = 1;
+
+ public override string GetTitle()
+ {
+ return "Default VMD Import Config";
+ }
+
+ public override void OnGUIFunction()
+ {
+ createAnimationFile = EditorGUILayout.Toggle("Create Asset", createAnimationFile);
+ interpolationQuality = EditorGUILayout.IntSlider("Interpolation Quality", interpolationQuality, 1, 10);
+ }
+
+ public VMDImportConfig Clone()
+ {
+ return (VMDImportConfig)MemberwiseClone();
+ }
+ }
+
+ ///
+ /// コンフィグ用のベースクラスです
+ ///
+ public class ConfigBase
+ {
+ ///
+ /// 開け閉めの状態
+ ///
+ private bool fold = true;
+
+ ///
+ /// GUI処理を行います
+ ///
+ public void OnGUI()
+ {
+ var title = GetTitle();
+ fold = EditorGUILayout.Foldout(fold, title);
+ if (fold) {
+ OnGUIFunction();
+ }
+ EditorGUILayout.Space();
+ }
+
+ ///
+ /// このコンフィグのタイトルを取得します
+ ///
+ public virtual string GetTitle()
+ {
+ return "";
+ }
+
+ ///
+ /// GUI処理を行います
+ ///
+ public virtual void OnGUIFunction()
+ {
+ }
+ }
+}
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/Editor/Config/ConfigWindow.cs b/Assets/Scripts/3rd/mmd-for-unity-master/Editor/Config/ConfigWindow.cs
new file mode 100644
index 000000000..c4dc2a78d
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/Editor/Config/ConfigWindow.cs
@@ -0,0 +1,34 @@
+using UnityEngine;
+using UnityEditor;
+
+namespace MMD
+{
+ public class ConfigWindow : EditorWindow
+ {
+ private Config config;
+
+ [MenuItem("MMD for Unity/Config")]
+ public static void Init()
+ {
+ GetWindow("MFU Config");
+ }
+
+ // Windowが有効化されたとき
+ // フォーカスが外れて戻ってきたときや再度開かれたときなど
+ void OnEnable()
+ {
+ if (config == null)
+ {
+ // 読み込む
+ config = MMD.Config.LoadAndCreate();
+ }
+ }
+
+ // ウィンドウの描画処理
+ void OnGUI()
+ {
+ // あとは任せる
+ config.OnGUI();
+ }
+ }
+}
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/Editor/ExpressionManagerEditor.cs b/Assets/Scripts/3rd/mmd-for-unity-master/Editor/ExpressionManagerEditor.cs
new file mode 100644
index 000000000..a3ee36168
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/Editor/ExpressionManagerEditor.cs
@@ -0,0 +1,104 @@
+using UnityEngine;
+using UnityEditor;
+using System;
+using System.Collections.Generic;
+
+///
+/// 表情用Inspector拡張
+///
+[CustomEditor(typeof(ExpressionManagerScript))]
+public sealed class ExpressionManagerEditor : Editor
+{
+ ///
+ /// スタティックコンストラクタ
+ ///
+ static ExpressionManagerEditor()
+ {
+ skin_displays_ = new bool[Enum.GetValues(typeof(MMDSkinsScript.SkinType)).Length];
+ for (int i = 0, i_max = skin_displays_.Length; i < i_max; ++i) {
+ skin_displays_[i] = true;
+ }
+ }
+
+ ///
+ /// 初回処理
+ ///
+ public void Awake()
+ {
+ children_ = new List[Enum.GetValues(typeof(MMDSkinsScript.SkinType)).Length];
+ for (int i = 0, i_max = children_.Length; i < i_max; ++i) {
+ children_[i] = new List();
+ }
+ //子登録
+ foreach (Transform child in Selection.activeTransform) {
+ MMDSkinsScript skins = child.GetComponent();
+ children_[(int)skins.skinType].Add(child);
+ }
+ }
+
+ ///
+ /// Inspector描画
+ ///
+ public override void OnInspectorGUI()
+ {
+ ExpressionManagerScript self = (ExpressionManagerScript)target;
+ bool is_dirty = false;
+
+ //mesh
+ self.mesh = (Mesh)EditorGUILayout.ObjectField("Mesh", self.mesh, typeof(Mesh), false);
+
+ //skin_script
+ for (int i = 0, i_max = children_.Length; i < i_max; ++i) {
+ if (MMDSkinsScript.SkinType.Base == (MMDSkinsScript.SkinType)i) {
+ //Baseだったらスキップ
+ continue;
+ }
+
+ //スキンツリータイトル
+ string skin_name = ((MMDSkinsScript.SkinType)i).ToString();
+ skin_displays_[i] = EditorGUILayout.Foldout(skin_displays_[i], skin_name);
+ //スキンツリー内部
+ if (skin_displays_[i]) {
+ //このスキンを表示するなら
+ GUIStyle style = new GUIStyle();
+ style.margin.left = 10;
+ EditorGUILayout.BeginVertical(style);
+ {
+ //モーフオブジェクト走査
+ foreach (Transform child in children_[i]) {
+ float value = child.localPosition.z;
+ value = EditorGUILayout.Slider(child.name, value, 0.0f, 1.0f);
+ if (child.localPosition.z != value) {
+ //変更が掛かったなら
+ //Undo登録
+#if !UNITY_4_2 //4.3以降
+ Undo.RecordObject(child, "Expression Change");
+#else
+ Undo.RegisterUndo(child, "Expression Change");
+#endif
+ //Z位置更新
+ Vector3 position = child.localPosition;
+ position.z = value;
+ child.localPosition = position;
+ //改変モーフオブジェクトのInspector更新
+ EditorUtility.SetDirty(child.transform);
+
+ is_dirty = true;
+ }
+ }
+ }
+ EditorGUILayout.EndVertical();
+ }
+
+ }
+
+ if (is_dirty) {
+ //更新が有ったなら
+ //Inspector更新
+ EditorUtility.SetDirty(target);
+ }
+ }
+
+ private static bool[] skin_displays_; //スキンの表示
+ private List[] children_; //スキン別子モーフオブジェクト
+}
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/Editor/Inspector/InspectorBase.cs b/Assets/Scripts/3rd/mmd-for-unity-master/Editor/Inspector/InspectorBase.cs
new file mode 100644
index 000000000..5459f6882
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/Editor/Inspector/InspectorBase.cs
@@ -0,0 +1,66 @@
+// Inspectorからインポートなどができるようになります
+// 他スクリプトと競合してしまう時はコメントアウトしてください
+
+#define USE_INSPECTOR
+
+//----------
+
+#if USE_INSPECTOR
+using System.IO;
+using System.Linq;
+using UnityEditor;
+using UnityEditor.Callbacks;
+using UnityEngine;
+
+namespace MMD
+{
+ [InitializeOnLoad]
+ public class InspectorBase : Editor
+ {
+ static InspectorBase()
+ {
+ EntryEditorApplicationUpdate();
+ }
+
+ [DidReloadScripts]
+ static void OnDidReloadScripts()
+ {
+ EntryEditorApplicationUpdate();
+ }
+
+ static void EntryEditorApplicationUpdate()
+ {
+ EditorApplication.update += Update;
+ }
+
+ static void Update()
+ {
+ if (Selection.objects.Length != 0)
+ {
+ string path = AssetDatabase.GetAssetPath(Selection.activeObject);
+ string extension = Path.GetExtension(path).ToLower();
+
+ if (extension == ".pmd" || extension == ".pmx")
+ {
+ //SetupScriptableObject(path);
+ }
+ else if (extension == ".vmd")
+ {
+ //SetupScriptableObject(path);
+ }
+ }
+ }
+
+ static void SetupScriptableObject(string path) where T : ScriptableObjectBase
+ {
+ int count = Selection.objects.OfType().Count();
+ if (count != 0) return;
+ T scriptableObject = ScriptableObject.CreateInstance();
+ scriptableObject.assetPath = path;
+ Selection.activeObject = scriptableObject;
+ EditorUtility.UnloadUnusedAssetsImmediate();
+ }
+ }
+}
+
+#endif
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/Editor/Inspector/PMDInspector.cs b/Assets/Scripts/3rd/mmd-for-unity-master/Editor/Inspector/PMDInspector.cs
new file mode 100644
index 000000000..5eda14bb1
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/Editor/Inspector/PMDInspector.cs
@@ -0,0 +1,87 @@
+using UnityEngine;
+using UnityEditor;
+using System.Collections;
+using MMD.PMD;
+using System.IO;
+
+namespace MMD
+{
+ [CustomEditor(typeof(PMDScriptableObject))]
+ public class PMDInspector : Editor
+ {
+ PMDImportConfig pmd_config;
+
+ // last selected item
+ private ModelAgent model_agent;
+ private string message = "";
+
+ ///
+ /// 有効化処理
+ ///
+ private void OnEnable()
+ {
+ // デフォルトコンフィグ
+ var config = MMD.Config.LoadAndCreate();
+ pmd_config = config.pmd_config.Clone();
+
+ // モデル情報
+ if (config.inspector_config.use_pmd_preload)
+ {
+ var obj = (PMDScriptableObject)target;
+ model_agent = new ModelAgent(obj.assetPath);
+ }
+ else
+ {
+ model_agent = null;
+ }
+ }
+
+ ///
+ /// Inspector上のGUI描画処理を行います
+ ///
+ public override void OnInspectorGUI()
+ {
+ // GUIの有効化
+ GUI.enabled = !EditorApplication.isPlaying;
+
+ // GUI描画
+ pmd_config.OnGUIFunction();
+
+ // Convertボタン
+ EditorGUILayout.Space();
+ if (message.Length != 0)
+ {
+ GUILayout.Label(message);
+ }
+ else
+ {
+ if (GUILayout.Button("Convert to Prefab"))
+ {
+ if (null == model_agent) {
+ var obj = (PMDScriptableObject)target;
+ model_agent = new ModelAgent(obj.assetPath);
+ }
+ model_agent.CreatePrefab(pmd_config.shader_type
+ , pmd_config.rigidFlag
+ , pmd_config.animation_type
+ , pmd_config.use_ik
+ , pmd_config.scale
+ , pmd_config.is_pmx_base_import
+ );
+ message = "Loading done.";
+ }
+ }
+ GUILayout.Space(40);
+
+ // モデル情報
+ if (model_agent == null) return;
+ EditorGUILayout.LabelField("Model Name");
+ EditorGUILayout.LabelField(model_agent.name, EditorStyles.textField);
+
+ EditorGUILayout.Space();
+
+ EditorGUILayout.LabelField("Comment");
+ EditorGUILayout.LabelField(model_agent.comment, EditorStyles.textField, GUILayout.Height(300));
+ }
+ }
+}
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/Editor/Inspector/PMDScriptableObject.cs b/Assets/Scripts/3rd/mmd-for-unity-master/Editor/Inspector/PMDScriptableObject.cs
new file mode 100644
index 000000000..d1129815a
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/Editor/Inspector/PMDScriptableObject.cs
@@ -0,0 +1,7 @@
+using UnityEngine;
+using System.Collections;
+
+public class PMDScriptableObject : ScriptableObjectBase
+{
+
+}
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/Editor/Inspector/ScriptableObjectBase.cs b/Assets/Scripts/3rd/mmd-for-unity-master/Editor/Inspector/ScriptableObjectBase.cs
new file mode 100644
index 000000000..5298c44f0
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/Editor/Inspector/ScriptableObjectBase.cs
@@ -0,0 +1,10 @@
+using UnityEngine;
+using System.Collections;
+
+public class ScriptableObjectBase
+#if !(UNITY_3_5 || UNITY_3_4 || UNITY_3_3)
+ : ScriptableObject
+#endif
+{
+ public string assetPath;
+}
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/Editor/Inspector/VMDInspector.cs b/Assets/Scripts/3rd/mmd-for-unity-master/Editor/Inspector/VMDInspector.cs
new file mode 100644
index 000000000..e564939ec
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/Editor/Inspector/VMDInspector.cs
@@ -0,0 +1,84 @@
+using UnityEngine;
+using UnityEditor;
+using System.Collections;
+using MMD.PMD;
+using System.IO;
+
+namespace MMD
+{
+ [CustomEditor(typeof(VMDScriptableObject))]
+ public class VMDInspector : Editor
+ {
+ // VMD Load option
+ public GameObject pmdPrefab;
+ VMDImportConfig vmd_config;
+
+ // last selected item
+ private MotionAgent motion_agent;
+ private string message = "";
+
+ ///
+ /// 有効化処理
+ ///
+ void OnEnable()
+ {
+ // デフォルトコンフィグ
+ var config = MMD.Config.LoadAndCreate();
+ vmd_config = config.vmd_config.Clone();
+
+ // モデル情報
+ if (config.inspector_config.use_vmd_preload)
+ {
+ var obj = (VMDScriptableObject)target;
+ motion_agent = new MotionAgent(obj.assetPath);
+ }
+ else
+ {
+ motion_agent = null;
+ }
+ }
+
+ ///
+ /// Inspector上のGUI描画処理を行います
+ ///
+ public override void OnInspectorGUI()
+ {
+ // GUIの有効化
+ GUI.enabled = !EditorApplication.isPlaying;
+
+ pmdPrefab = (GameObject)EditorGUILayout.ObjectField("PMD Prefab", pmdPrefab, typeof(Object), false);
+ vmd_config.OnGUIFunction();
+
+ // Convertボタン
+ EditorGUILayout.Space();
+ if (message.Length != 0)
+ {
+ GUILayout.Label(message);
+ }
+ else
+ {
+ bool gui_enabled_old = GUI.enabled;
+ GUI.enabled = (null != pmdPrefab);
+ if (GUILayout.Button("Convert"))
+ {
+ if (null == motion_agent) {
+ var obj = (VMDScriptableObject)target;
+ motion_agent = new MotionAgent(obj.assetPath);
+ }
+ motion_agent.CreateAnimationClip(pmdPrefab
+ , vmd_config.createAnimationFile
+ , vmd_config.interpolationQuality
+ );
+ message = "Loading done.";
+ }
+ GUI.enabled = gui_enabled_old;
+ }
+ GUILayout.Space(40);
+
+ // モデル情報
+ if (motion_agent == null) return;
+ EditorGUILayout.LabelField("Model Name");
+ EditorGUILayout.LabelField(motion_agent.model_name, EditorStyles.textField);
+ }
+ }
+}
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/Editor/Inspector/VMDScriptableObject.cs b/Assets/Scripts/3rd/mmd-for-unity-master/Editor/Inspector/VMDScriptableObject.cs
new file mode 100644
index 000000000..3c43d68b2
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/Editor/Inspector/VMDScriptableObject.cs
@@ -0,0 +1,7 @@
+using UnityEngine;
+using System.Collections;
+
+public class VMDScriptableObject : ScriptableObjectBase
+{
+
+}
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/Editor/MMDEngineEditor.cs b/Assets/Scripts/3rd/mmd-for-unity-master/Editor/MMDEngineEditor.cs
new file mode 100644
index 000000000..01934f0de
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/Editor/MMDEngineEditor.cs
@@ -0,0 +1,562 @@
+using UnityEngine;
+using UnityEditor;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+///
+/// MMDEngine用Inspector拡張
+///
+[CustomEditor(typeof(MMDEngine))]
+public sealed class MMDEngineEditor : Editor
+{
+ ///
+ /// スタティックコンストラクタ
+ ///
+ static MMDEngineEditor()
+ {
+ ik_list_display_ = false;
+ shader_display_ = false;
+ }
+
+ ///
+ /// 初回処理
+ ///
+ public void Awake()
+ {
+ }
+
+ ///
+ /// Inspector描画
+ ///
+ public override void OnInspectorGUI()
+ {
+ bool is_dirty = false;
+
+ is_dirty = OnInspectorGUIforOutlineWidth() || is_dirty;
+ is_dirty = OnInspectorGUIforUseRigidbody() || is_dirty;
+ is_dirty = OnInspectorGUIforIkList() || is_dirty;
+ is_dirty = OnInspectorGUIforShaderList() || is_dirty;
+ is_dirty = OnInspectorGUIforRenderQueue() || is_dirty;
+
+ if (is_dirty) {
+ //更新が有ったなら
+ //Inspector更新
+ EditorUtility.SetDirty(target);
+ }
+ }
+
+ ///
+ /// エッジ幅の為のInspector描画
+ ///
+ /// 更新が有ったか(true:更新有り, false:未更新)
+ private bool OnInspectorGUIforOutlineWidth()
+ {
+ MMDEngine self = (MMDEngine)target;
+ bool is_update = false;
+
+#if !MFU_DISABLE_LEGACY_DATA_SUPPORT
+ if (0 == self.material_outline_widths.Length) {
+ //material_outline_widthsが設定されていないなら(昔の変換データ)
+ Material[] materials = GetMaterials(self);
+ if (0 < materials.Length) {
+ //マテリアルが有り、今のエッジ幅が0.0fで無いなら
+ //データ生成を試みる
+ self.material_outline_widths = materials.Select(x=>x.GetFloat("_OutlineWidth")).ToArray();
+ }
+ }
+#endif
+
+ float outline_width = self.outline_width;
+ outline_width = EditorGUILayout.Slider("Outline Width", outline_width, 0.0f, 2.0f);
+ if (self.outline_width != outline_width) {
+ //変更が掛かったなら
+ Material[] materials = GetMaterials(self);
+ //Undo登録
+ var record_objects = materials.Select(x=>(UnityEngine.Object)x) //マテリアル全てと
+ .Concat(new UnityEngine.Object[]{self}) //UnityEngine
+ .ToArray();
+#if !UNITY_4_2 //4.3以降
+ Undo.RecordObjects(record_objects, "Outline Width Change");
+#else
+ Undo.RegisterUndo(record_objects, "Outline Width Change");
+#endif
+ //更新
+ const float c_default_scale = 0.085f; //0.085fの時にMMDと一致する様にしているので、それ以外なら補正
+ self.outline_width = outline_width;
+ foreach (var i in Enumerable.Range(0, materials.Length)
+ .Select(x=>new {material = materials[x], edge_size = self.material_outline_widths[x]})) {
+ i.material.SetFloat("_OutlineWidth", i.edge_size * outline_width * self.scale / c_default_scale);
+ }
+
+ is_update = true;
+ }
+
+ return is_update;
+ }
+
+ ///
+ /// リジッドボティ使用の為のInspector描画
+ ///
+ /// 更新が有ったか(true:更新有り, false:未更新)
+ private bool OnInspectorGUIforUseRigidbody()
+ {
+ MMDEngine self = (MMDEngine)target;
+ bool is_update = false;
+
+ bool use_rigidbody = self.useRigidbody;
+ use_rigidbody = EditorGUILayout.Toggle("Use Rigidbody", use_rigidbody);
+ if (self.useRigidbody != use_rigidbody) {
+ //変更が掛かったなら
+ //Undo登録
+#if !UNITY_4_2 //4.3以降
+ Undo.RecordObject(self, "Use Rigidbody Change");
+#else
+ Undo.RegisterUndo(self, "Use Rigidbody Change");
+#endif
+ //更新
+ self.useRigidbody = use_rigidbody;
+
+ is_update = true;
+ }
+ return is_update;
+ }
+
+ ///
+ /// IKリストの為のInspector描画
+ ///
+ /// 更新が有ったか(true:更新有り, false:未更新)
+ private bool OnInspectorGUIforIkList()
+ {
+ MMDEngine self = (MMDEngine)target;
+ bool is_update = false;
+
+ //IKリストツリータイトル
+ ik_list_display_ = EditorGUILayout.Foldout(ik_list_display_, "IK List");
+ //IKリストツリー内部
+ if (ik_list_display_) {
+ //IKリストを表示するなら
+ GUIStyle style = new GUIStyle();
+ style.margin.left = 10;
+ EditorGUILayout.BeginVertical(style);
+ {
+ foreach (CCDIKSolver ik in self.ik_list) {
+ bool enabled = ik.enabled;
+ enabled = EditorGUILayout.Toggle(ik.name, enabled);
+ if (ik.enabled != enabled) {
+ //変更が掛かったなら
+ //Undo登録
+#if !UNITY_4_2 //4.3以降
+ Undo.RecordObject(ik, "Enabled Change");
+#else
+ Undo.RegisterUndo(ik, "Enabled Change");
+#endif
+ //更新
+ ik.enabled = enabled;
+ //改変したIKのInspector更新
+ EditorUtility.SetDirty(ik);
+
+ is_update = true;
+ }
+ }
+ }
+ EditorGUILayout.EndVertical();
+ }
+ return is_update;
+ }
+
+ ///
+ /// シェーダーリストの為のInspector描画
+ ///
+ /// 更新が有ったか(true:更新有り, false:未更新)
+ private bool OnInspectorGUIforShaderList()
+ {
+ MMDEngine self = (MMDEngine)target;
+ bool is_update = false;
+
+ //シェーダーリストタイトル
+ shader_display_ = EditorGUILayout.Foldout(shader_display_, "Shader List");
+ //シェーダーリスト内部
+ if (shader_display_) {
+ //シェーダーリストを表示するなら
+ Material[] materials = GetMaterials(self);
+ GUIStyle style = new GUIStyle();
+ style.margin.left = 10;
+ EditorGUILayout.BeginVertical(style);
+ {
+ //タイトル
+ EditorGUILayout.BeginHorizontal();
+ {
+ //ラベル
+ EditorGUILayout.LabelField("Material", GUILayout.Width(64));
+ //シェーダー
+ EditorGUILayout.LabelField(new GUIContent("Tr", "Transparent"), GUILayout.Width(20));
+ EditorGUILayout.LabelField(new GUIContent("Eg", "Edge"), GUILayout.Width(20));
+ EditorGUILayout.LabelField(new GUIContent("Rv", "Reversible"), GUILayout.Width(20));
+ EditorGUILayout.LabelField(new GUIContent("Cs", "CastShadow"), GUILayout.Width(20));
+#if MFU_ENABLE_NO_RECEIVE_SHADOW_SHADER //影受け無しのシェーダはまだ無いので無効化
+ EditorGUILayout.LabelField(new GUIContent("Rs", "ReceiveShadow"), GUILayout.Width(20));
+#endif //MFU_ENABLE_NO_RECEIVE_SHADOW_SHADER
+ EditorGUILayout.LabelField("", GUILayout.Width(20));
+ EditorGUILayout.LabelField(new GUIContent("Hi", "Highlight"), GUILayout.Width(20));
+ EditorGUILayout.LabelField(new GUIContent("Hd", "Hidden"), GUILayout.Width(20));
+ }
+ EditorGUILayout.EndHorizontal();
+
+ //描画用配列
+ var parameter_table = new[]{new {flag=ShaderFlag.Transparent, reverse=false}
+ , new {flag=ShaderFlag.Outline, reverse=false}
+ , new {flag=ShaderFlag.CullBack, reverse=true} //背景カリングON/OFFはわかり辛いので、MMDの様に両面描画ON/OFFで扱う
+ , new {flag=ShaderFlag.NoCastShadow, reverse=true} //影放たないON/OFFの2重否定を止めて影放つON/OFFで扱う
+#if MFU_ENABLE_NO_RECEIVE_SHADOW_SHADER //影受け無しのシェーダはまだ無いので無効化
+ , new {flag=ShaderFlag.NoReceiveShadow, reverse=true} //影受けないON/OFFの2重否定を止めて影受けるON/OFFで扱う
+#endif //MFU_ENABLE_NO_RECEIVE_SHADOW_SHADER
+ , new {flag=(ShaderFlag)0, reverse=false}
+ , new {flag=ShaderFlag.Highlight, reverse=false}
+ , new {flag=ShaderFlag.Hidden, reverse=false}
+ };
+ //マテリアル
+ for (int i = 0, i_max = materials.Length; i < i_max; ++i) {
+ Material material = materials[i];
+
+ EditorGUILayout.BeginHorizontal();
+ {
+ //ラベル
+ EditorGUILayout.LabelField(new GUIContent(material.name, material.name), GUILayout.Width(64));
+ //シェーダー
+ if (IsMmdShader(material)) {
+ //MMDシェーダーなら
+ bool is_change_shader = false;
+ ShaderFlag flag = AnalyzeShaderFlag(material);
+ foreach (var param in parameter_table) {
+ if (0 != param.flag) {
+ //描画用
+ bool enable_old = 0 != ((int)flag & (int)param.flag);
+ if (param.reverse) {
+ enable_old = !enable_old;
+ }
+ bool enable = EditorGUILayout.Toggle(enable_old, GUILayout.Width(20));
+ if (enable_old != enable) {
+ //更新
+ if (param.reverse) {
+ enable = !enable;
+ }
+ flag = (ShaderFlag)((int)flag ^ (int)param.flag);
+
+ is_change_shader = true;
+ }
+ } else {
+ //スペース用
+ EditorGUILayout.LabelField("", GUILayout.Width(20));
+ }
+ }
+ if (is_change_shader) {
+ //変更が掛かったなら
+ //Undo登録
+#if !UNITY_4_2 //4.3以降
+ Undo.RecordObject(material, "Shader Change");
+#else
+ Undo.RegisterUndo(material, "Shader Change");
+#endif
+
+ int render_queue = ((self.enable_render_queue)? self.render_queue_value + i: -1);
+ SetShader(material, flag, render_queue);
+ is_update = true;
+ }
+ }
+ }
+ EditorGUILayout.EndHorizontal();
+ }
+ }
+ EditorGUILayout.EndVertical();
+ }
+ return is_update;
+ }
+
+ ///
+ /// カスタムレンダーキューの為のInspector描画
+ ///
+ /// 更新が有ったか(true:更新有り, false:未更新)
+ private bool OnInspectorGUIforRenderQueue()
+ {
+ MMDEngine self = (MMDEngine)target;
+ bool is_update = false;
+
+#if !MFU_DISABLE_LEGACY_DATA_SUPPORT
+ if ((false == self.enable_render_queue) && (0 == self.render_queue_value)) {
+ //カスタムレンダーキュー関連が設定されていないなら(昔の変換データ)
+ //無効状態で初期化
+ self.enable_render_queue = false;
+ const int c_render_queue_transparent = 3000;
+ self.render_queue_value = c_render_queue_transparent;
+ }
+#endif
+
+ bool enable_render_queue = self.enable_render_queue;
+ enable_render_queue = EditorGUILayout.Toggle("Render Queue", enable_render_queue);
+ if (self.enable_render_queue != enable_render_queue) {
+ //変更が掛かったなら
+ is_update = true;
+ }
+ int render_queue_value = -1;
+ if (enable_render_queue) {
+ //有効なら
+ render_queue_value = self.render_queue_value;
+ render_queue_value = EditorGUILayout.IntField("Render Queue Value", render_queue_value);
+ if (self.render_queue_value != render_queue_value) {
+ //変更が掛かったなら
+ is_update = true;
+ }
+ }
+
+ if (is_update) {
+ //変更が掛かったなら
+ Material[] materials = GetMaterials(self);
+ //Undo登録
+ var record_objects = materials.Select(x=>(UnityEngine.Object)x) //マテリアル全てと
+ .Concat(new UnityEngine.Object[]{self}) //UnityEngine
+ .ToArray();
+#if !UNITY_4_2 //4.3以降
+ Undo.RecordObjects(record_objects, "Render Queue Change");
+#else
+ Undo.RegisterUndo(record_objects, "Render Queue Change");
+#endif
+ //更新
+ self.enable_render_queue = enable_render_queue;
+ if (enable_render_queue) {
+ //有効化
+ self.render_queue_value = render_queue_value;
+ for (int i = 0, i_max = materials.Length; i < i_max; ++i) {
+ var material = materials[i];
+ ShaderFlag flag = AnalyzeShaderFlag(material);
+ if (0 != (flag & ShaderFlag.MmdShader)) {
+ //Mmdシェーダーなら
+ //カスタムレンダーキュー
+ if (0 != (flag & ShaderFlag.Transparent)) {
+ //透過なら
+ //マテリアル順にカスタムレンダーキューを設定
+ material.renderQueue = render_queue_value + i;
+ } else {
+ //不透明なら
+ //カスタムレンダーキューを解除
+ material.renderQueue = -1;
+ }
+ }
+ }
+ } else {
+ //無効化
+ foreach (var material in materials) {
+ ShaderFlag flag = AnalyzeShaderFlag(material);
+ if (0 != (flag & ShaderFlag.MmdShader)) {
+ //Mmdシェーダーなら
+ //カスタムレンダーキューを解除
+ material.renderQueue = -1;
+ }
+ }
+ }
+ }
+
+ return is_update;
+ }
+
+ ///
+ /// MMDシェーダー確認
+ ///
+ /// MMDシェーダーか
+ /// マテリアル
+ static bool IsMmdShader(Material material) {
+ bool result = false;
+ if (null != material.shader) {
+ //シェーダーを持っているなら
+ if (0 == material.shader.name.IndexOf("MMD/")) {
+ //Mfuシェーダーなら
+ if (-1 == material.shader.name.IndexOf("MMD/HalfLambertOutline")) {
+ //エッジ付きハーフランバートシェーダーで無いなら
+ result = true;
+ }
+ }
+ }
+ return result;
+ }
+
+ ///
+ /// シェーダーフラグの解析
+ ///
+ /// シェーダーフラグ
+ /// マテリアル
+ static ShaderFlag AnalyzeShaderFlag(Material material) {
+ ShaderFlag result = ShaderFlag.MmdShader;
+ string name = material.shader.name;
+ if (0 == name.IndexOf("MMD/Dummy")) {
+ //デバッグ(ハイライト・非表示)シェーダーなら
+ //_DummyOriginalShaderTypeパラメータに埋め込んでいるのでそれを使用
+ float original_shader_type = 0.0f;
+ if (material.HasProperty("_DummyOriginalShaderType")) {
+ original_shader_type = material.GetFloat("_DummyOriginalShaderType");
+ }
+ result = (ShaderFlag)(int)original_shader_type;
+ //デバッグカラーからデバッグ内のシェーダ判別
+ Color color;
+ if (material.HasProperty("_DummyColor")) {
+ color = material.GetColor("_DummyColor");
+ } else {
+ color = new Color(1.0f, 1.0f, 1.0f, 0.0f);
+ }
+ if (0.0f < color.a) {
+ //透過で無いなら
+ //ハイライト
+ result = result | ShaderFlag.Highlight;
+ } else {
+ //透過なら
+ //非表示
+ result = result | ShaderFlag.Hidden;
+ }
+ } else if (0 == name.IndexOf("MMD/")) {
+ //通常シェーダーなら
+ if (-1 != name.IndexOf("Transparent/")) {
+ //透過なら
+ result = (result | ShaderFlag.Transparent);
+ }
+ if (-1 != name.IndexOf("-Outline")) {
+ //エッジ有りなら
+ result = (result | ShaderFlag.Outline);
+ }
+ if (-1 != name.IndexOf("-CullBack")) {
+ //背面カリングなら
+ result = (result | ShaderFlag.CullBack);
+ }
+ if (-1 != name.IndexOf("-NoCastShadow")) {
+ //影を放たないなら
+ result = (result | ShaderFlag.NoCastShadow);
+ }
+#if MFU_ENABLE_NO_RECEIVE_SHADOW_SHADER //影受け無しのシェーダはまだ無いので無効化
+ if (-1 != name.IndexOf("-NoReceiveShadow")) {
+ //影受け無しなら
+ result = (result | ShaderFlag.NoReceiveShadow);
+ }
+#endif //MFU_ENABLE_NO_RECEIVE_SHADOW_SHADER
+ } else {
+ //MMDシェーダー以外なら
+ result = (ShaderFlag)0;
+ }
+ return result;
+ }
+
+ ///
+ /// シェーダーフラグからのシェーダー設定
+ ///
+ /// マテリアル
+ /// シェーダーフラグ
+ /// 透過の場合に設定するレンダーキュー
+ static void SetShader(Material material, ShaderFlag flag, int render_queue) {
+ if (0 != (flag & ShaderFlag.MmdShader)) {
+ //Mmdシェーダーなら
+ material.shader = CreateShaderFromShaderFlag(flag);
+ if (0 != (flag & ShaderFlag.Hidden)) {
+ //非表示なら
+ float original_shader_type = (float)(int)flag;
+ material.SetFloat("_DummyOriginalShaderType", original_shader_type);
+ material.SetColor("_DummyColor", new Color(1.0f, 1.0f, 1.0f, 0.0f));
+ } else if (0 != (flag & ShaderFlag.Highlight)) {
+ //ハイライトなら
+ float original_shader_type = (float)(int)flag;
+ material.SetFloat("_DummyOriginalShaderType", original_shader_type);
+ material.SetColor("_DummyColor", new Color(1.0f, 0.0f, 1.0f, 1.0f));
+ }
+ //カスタムレンダーキュー
+ if (0 != (flag & ShaderFlag.Transparent)) {
+ //透過なら
+ //マテリアル順にカスタムレンダーキューを設定
+ material.renderQueue = render_queue;
+ } else {
+ //不透明なら
+ //カスタムレンダーキューを解除
+ material.renderQueue = -1;
+ }
+ }
+ }
+
+ ///
+ /// シェーダーフラグからのシェーダー作成
+ ///
+ /// シェーダー
+ /// シェーダーフラグ
+ static Shader CreateShaderFromShaderFlag(ShaderFlag flag) {
+ Shader result;
+ string path = "MMD/";
+ if (0 != (flag & ShaderFlag.Transparent)) {
+ path += "Transparent/";
+ }
+ path += "PMDMaterial";
+ if (0 != (flag & ShaderFlag.Outline)) {
+ path += "-with-Outline";
+ }
+ if (0 != (flag & ShaderFlag.CullBack)) {
+ path += "-CullBack";
+ }
+ if (0 != (flag & ShaderFlag.NoCastShadow)) {
+ path += "-NoCastShadow";
+ }
+#if MFU_ENABLE_NO_RECEIVE_SHADOW_SHADER //影受け無しのシェーダはまだ無いので無効化
+ if (0 != (flag & ShaderFlag.NoReceiveShadow)) {
+ path += "-NoReceiveShadow";
+ }
+#endif //MFU_ENABLE_NO_RECEIVE_SHADOW_SHADER
+ result = Shader.Find(path);
+
+ //デバッグ系
+ if (0 != (flag & ShaderFlag.Highlight)) {
+ //ハイライト
+ string original_shader_name = result.name;
+ result = Shader.Find("MMD/Dummy");
+ result.name = original_shader_name + "+Highlight";
+ } else if (0 != (flag & ShaderFlag.Hidden)) {
+ //非表示
+ string original_shader_name = result.name;
+ result = Shader.Find("MMD/Dummy");
+ result.name = original_shader_name + "+Hidden";
+ }
+
+ return result;
+ }
+
+ ///
+ /// 本来の順序で材質一覧の取得
+ ///
+ /// 材質一覧
+ /// 材質を取得するMMDEngine
+ static Material[] GetMaterials(MMDEngine engine)
+ {
+ SkinnedMeshRenderer[] renderers = engine.GetComponentsInChildren();
+ Material[] result = renderers.SelectMany(x=>x.sharedMaterials).Distinct().ToArray();
+ if (1 < renderers.Length) {
+ //rendererが複数有る(≒PMX)なら
+ //PMXでは名前の先頭にはマテリアルインデックスが有るのでそれを参考にソート
+ //PMDではrendererが1つしか無く、かつソート済みの為不要
+ System.Array.Sort(result, (x,y)=>{
+ string x_name = x.name.Substring(0, x.name.IndexOf('_'));
+ string y_name = y.name.Substring(0, y.name.IndexOf('_'));
+ int x_int, y_int;
+ Int32.TryParse(x_name, out x_int);
+ Int32.TryParse(y_name, out y_int);
+ return x_int - y_int;
+ });
+ }
+ return result;
+ }
+
+ [Flags]
+ private enum ShaderFlag {
+ MmdShader = 1<< 0, //MMDシェーダー
+ Transparent = 1<< 1, //透過
+ Outline = 1<< 2, //エッジ有り
+ CullBack = 1<< 3, //背面カリング
+ NoCastShadow = 1<< 4, //影放ち無し
+ NoReceiveShadow = 1<< 5, //影受け無し
+ Highlight = 1<< 6, //ハイライト
+ Hidden = 1<< 7, //非表示
+ }
+
+ private static bool ik_list_display_; //IKリストの表示
+ private static bool shader_display_; //シェーダーリストの表示
+}
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/Editor/MMDLoader/LoadedWindow.cs b/Assets/Scripts/3rd/mmd-for-unity-master/Editor/MMDLoader/LoadedWindow.cs
new file mode 100644
index 000000000..3046d6073
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/Editor/MMDLoader/LoadedWindow.cs
@@ -0,0 +1,37 @@
+using UnityEngine;
+using UnityEditor;
+using System.Collections;
+
+public class LoadedWindow : EditorWindow
+{
+ ///
+ /// メッセージ用テキスト
+ ///
+ public string Text { get; set; }
+
+ const int width = 400;
+
+ const int height = 300;
+
+ ///
+ /// 初期化
+ ///
+ /// ウィンドウ
+ public static LoadedWindow Init()
+ {
+ var window = EditorWindow.GetWindow("PMD file loaded!") as LoadedWindow;
+ var pos = window.position;
+ pos.height = LoadedWindow.height;
+ pos.width = LoadedWindow.width;
+ window.position = pos;
+ return window;
+ }
+
+ void OnGUI()
+ {
+ EditorGUI.TextArea(new Rect(0, 0, LoadedWindow.width, LoadedWindow.height - 30), this.Text);
+
+ if (GUI.Button(new Rect(0, height - 30, LoadedWindow.width, 30), "OK"))
+ Close();
+ }
+}
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/Editor/MMDLoader/PMDLoaderWindow.cs b/Assets/Scripts/3rd/mmd-for-unity-master/Editor/MMDLoader/PMDLoaderWindow.cs
new file mode 100644
index 000000000..cc13aa727
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/Editor/MMDLoader/PMDLoaderWindow.cs
@@ -0,0 +1,61 @@
+using UnityEngine;
+using System.Collections;
+using UnityEditor;
+
+public class PMDLoaderWindow : EditorWindow {
+ Object pmdFile;
+ MMD.PMDImportConfig pmd_config;
+
+ [MenuItem("MMD for Unity/PMD Loader")]
+ static void Init() {
+ var window = (PMDLoaderWindow)EditorWindow.GetWindow(true, "PMDLoader");
+ window.Show();
+ }
+
+ void OnEnable()
+ {
+ // デフォルトコンフィグ
+ pmdFile = null;
+ pmd_config = MMD.Config.LoadAndCreate().pmd_config.Clone();
+ }
+
+ void OnGUI() {
+ // GUIの有効化
+ GUI.enabled = !EditorApplication.isPlaying;
+
+ // GUI描画
+ pmdFile = EditorGUILayout.ObjectField("PMD File" , pmdFile, typeof(Object), false);
+ pmd_config.OnGUIFunction();
+
+ {
+ bool gui_enabled_old = GUI.enabled;
+ GUI.enabled = !EditorApplication.isPlaying && (pmdFile != null);
+ if (GUILayout.Button("Convert")) {
+ LoadModel();
+ pmdFile = null; // 読み終わったので空にする
+ }
+ GUI.enabled = gui_enabled_old;
+ }
+ }
+
+ void LoadModel() {
+ string file_path = AssetDatabase.GetAssetPath(pmdFile);
+ MMD.ModelAgent model_agent = new MMD.ModelAgent(file_path);
+ model_agent.CreatePrefab(pmd_config.shader_type
+ , pmd_config.rigidFlag
+ , pmd_config.animation_type
+ , pmd_config.use_ik
+ , pmd_config.scale
+ , pmd_config.is_pmx_base_import
+ );
+
+ // 読み込み完了メッセージ
+ var window = LoadedWindow.Init();
+ window.Text = string.Format(
+ "----- model name -----\n{0}\n\n----- comment -----\n{1}",
+ model_agent.name,
+ model_agent.comment
+ );
+ window.Show();
+ }
+}
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/Editor/MMDLoader/Private/AlphaReadableTexture.cs b/Assets/Scripts/3rd/mmd-for-unity-master/Editor/MMDLoader/Private/AlphaReadableTexture.cs
new file mode 100644
index 000000000..ca5e0a543
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/Editor/MMDLoader/Private/AlphaReadableTexture.cs
@@ -0,0 +1,123 @@
+using UnityEngine;
+using UnityEditor;
+using System.Collections.Generic;
+using System.Linq;
+
+public class AlphaReadableTexture : System.IDisposable {
+
+ ///
+ /// コンストラクタ
+ ///
+ /// テクスチャ相対パスリスト
+ /// カレントディレクトリ("/"終わり、テクスチャの相対パス基点)
+ /// 解析作業用ディレクトリ("/"終わり、このディレクトリの下に解析作業用ディレクトリを作ります)
+ public AlphaReadableTexture(string[] texture_path_list, string current_directory, string temporary_directory)
+ {
+ texture_path_list_ = texture_path_list;
+ current_directory_ = current_directory;
+ temporary_directory_ = temporary_directory + directory_name + "/";
+
+ //テクスチャ作成
+ foreach (string texture_path in texture_path_list_.Where(x=>!string.IsNullOrEmpty(x)).Distinct()) {
+ CreateReadableTexture(texture_path);
+ }
+ AssetDatabase.Refresh();
+ //テクスチャ取得
+ textures_ = texture_path_list_.Select(x=>GetReadableTexture(x)).ToArray();
+ }
+
+ ///
+ /// 読み込み可能テクスチャの取得
+ ///
+ /// 読み込み可能テクスチャ
+ public Texture2D[] textures {get{return textures_;}}
+
+ ///
+ /// Disposeインターフェース
+ ///
+ public void Dispose()
+ {
+ //テクスチャ破棄
+ foreach (string texture_path in texture_path_list_.Where(x=>!string.IsNullOrEmpty(x)).Distinct()) {
+ DeleteReadableTexture(texture_path);
+ }
+ //ディレクトリの破棄
+ string path = Application.dataPath + "/../" + temporary_directory_; //"Asset/"が被るので1階層上がる
+ if (System.IO.Directory.Exists(path)) {
+ System.IO.Directory.Delete(path, true);
+ }
+ }
+
+ ///
+ /// 解析対象ディレクトリ名の取得
+ ///
+ /// The directory_name.
+ public static string directory_name {get{return "AlphaReadableTextureDirectory.MmdForUnity";}}
+
+ ///
+ /// 読み込み可能テクスチャの作成
+ ///
+ /// テクスチャパス
+ private void CreateReadableTexture(string texture_path)
+ {
+ if (!string.IsNullOrEmpty(texture_path)) {
+ string base_texture_path = current_directory_ + texture_path;
+ string readable_texture_path = temporary_directory_ + texture_path;
+ CreateDirectoryPath(System.IO.Path.GetDirectoryName(readable_texture_path));
+ bool is_copy_success = AssetDatabase.CopyAsset(base_texture_path, readable_texture_path);
+ if (!is_copy_success) {
+ throw new System.InvalidOperationException();
+ }
+ }
+ }
+
+ ///
+ /// 読み込み可能テクスチャの取得
+ ///
+ /// 読み込み可能テクスチャ
+ /// テクスチャパス
+ private Texture2D GetReadableTexture(string texture_path)
+ {
+ Texture2D result = null;
+ if (!string.IsNullOrEmpty(texture_path)) {
+ string readable_texture_path = temporary_directory_ + texture_path;
+ result = (Texture2D)AssetDatabase.LoadAssetAtPath(readable_texture_path, typeof(Texture2D));
+ }
+ return result;
+ }
+
+ ///
+ /// 読み込み可能テクスチャの削除
+ ///
+ /// テクスチャパス
+ private void DeleteReadableTexture(string texture_path)
+ {
+ if (!string.IsNullOrEmpty(texture_path)) {
+ string readable_texture_path = temporary_directory_ + texture_path;
+ AssetDatabase.DeleteAsset(readable_texture_path);
+ }
+ }
+
+ ///
+ /// ディレクトリの作成(親ディレクトリが無ければ再帰的に作成)
+ ///
+ /// ディレクトリパス
+ private static void CreateDirectoryPath(string path)
+ {
+ //親ディレクトリ作成
+ string parent_path = System.IO.Path.GetDirectoryName(path);
+ if (!string.IsNullOrEmpty(parent_path) && !System.IO.Directory.Exists(parent_path)) {
+ CreateDirectoryPath(parent_path);
+ }
+ //カレントディレクトリ作成
+ if (!System.IO.Directory.Exists(path)) {
+ string name = System.IO.Path.GetFileName(path);
+ AssetDatabase.CreateFolder(parent_path, name);
+ }
+ }
+
+ private Texture2D[] textures_; //読み込み可能テクスチャ
+ private string[] texture_path_list_; //解析するテクスチャリスト
+ private string current_directory_; //カレントディレクトリ
+ private string temporary_directory_; //解析作業用ディレクトリ
+}
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/Editor/MMDLoader/Private/AlphaReadableTextureDirectoryImporter.cs b/Assets/Scripts/3rd/mmd-for-unity-master/Editor/MMDLoader/Private/AlphaReadableTextureDirectoryImporter.cs
new file mode 100644
index 000000000..a092297a1
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/Editor/MMDLoader/Private/AlphaReadableTextureDirectoryImporter.cs
@@ -0,0 +1,28 @@
+using UnityEngine;
+using UnityEditor;
+using System.Collections.Generic;
+
+public class AlphaReadableTextureDirectoryImporter : AssetPostprocessor {
+
+ ///
+ /// テクスチャプリプロセッサ
+ ///
+ void OnPreprocessTexture() {
+ if (-1 != assetPath.IndexOf(AlphaReadableTexture.directory_name)) {
+ //MmdForUnityの解析用ディレクトリなら
+ TextureImporter importer = (TextureImporter)assetImporter;
+ importer.isReadable = true; //読み込み可能とする
+ //importer.textureFormat = TextureImporterFormat.Alpha8; //アルファのみ
+ importer.mipmapEnabled = false; //mipmapを作成しない
+ if (importer.DoesSourceTextureHaveAlpha()) {
+ //アルファが有れば
+ //透過フラグを立てる
+ importer.alphaIsTransparency = true;
+ } else {
+ //アルファが無ければ
+ //解像度を最小化
+ importer.maxTextureSize = 1;
+ }
+ }
+ }
+}
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/Editor/MMDLoader/Private/AvatarSettingScript.cs b/Assets/Scripts/3rd/mmd-for-unity-master/Editor/MMDLoader/Private/AvatarSettingScript.cs
new file mode 100644
index 000000000..b390e094b
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/Editor/MMDLoader/Private/AvatarSettingScript.cs
@@ -0,0 +1,359 @@
+using UnityEngine;
+using UnityEditor;
+using System.Collections.Generic;
+using System.Linq;
+
+// アバターの設定を行うスクリプト
+public class AvatarSettingScript
+{
+ ///
+ /// デフォルトコンストラクタ
+ ///
+ ///
+ /// ユーザーに依るインスタンス作成を禁止する
+ ///
+ public AvatarSettingScript(GameObject root_game_object, GameObject[] bones) {
+ root_game_object_ = root_game_object;
+ bones_ = bones;
+ }
+
+ ///
+ /// 汎用アバダーを設定する
+ ///
+ /// アニメーター
+ public Animator SettingGenericAvatar() {
+ //アバタールートトランスフォームの取得
+ Transform avatar_root_transform = root_game_object_.transform.Find("Model");
+ if (null == avatar_root_transform) {
+ //ルートゲームオブジェクト直下にモデルルートオブジェクトが無い(PMDConverter)なら
+ //ルートゲームオブジェクトをアバタールートオブジェクトとする
+ avatar_root_transform = root_game_object_.transform;
+ }
+
+ //ジェネリックアバター作成
+ string root_name = ((HasBone("全ての親"))? "全ての親": "");
+ avatar_ = AvatarBuilder.BuildGenericAvatar(avatar_root_transform.gameObject, root_name);
+
+ //アバターをアニメーターに設定
+ animator_ = root_game_object_.AddComponent();
+ animator_.avatar = avatar_;
+
+ return animator_;
+ }
+
+ ///
+ /// 人型アバダーを設定する
+ ///
+ /// アニメーター
+ ///
+ /// モデルに依ってボーン構成に差が有るが、MMD標準モデルとの一致を優先する
+ ///
+ public Animator SettingHumanAvatar() {
+ //生成済みのボーンをUnity推奨ポーズに設定
+ SetRequirePose();
+
+ //アバタールートトランスフォームの取得
+ Transform avatar_root_transform = root_game_object_.transform.Find("Model");
+ if (null == avatar_root_transform) {
+ //ルートゲームオブジェクト直下にモデルルートオブジェクトが無い(PMDConverter)なら
+ //ルートゲームオブジェクトをアバタールートオブジェクトとする
+ avatar_root_transform = root_game_object_.transform;
+ }
+
+ //ヒューマノイドアバター作成
+ HumanDescription description = new HumanDescription();
+ description.human = CreateHumanBone();
+ description.skeleton = CreateSkeletonBone();
+ description.lowerArmTwist = 0.0f;
+ description.upperArmTwist = 0.0f;
+ description.upperLegTwist = 0.0f;
+ description.lowerLegTwist = 0.0f;
+ description.armStretch = 0.0f;
+ description.legStretch = 0.0f;
+ description.feetSpacing = 0.0f;
+ avatar_ = AvatarBuilder.BuildHumanAvatar(avatar_root_transform.gameObject, description);
+
+ //アバターをアニメーターに設定
+ animator_ = root_game_object_.AddComponent();
+ animator_.avatar = avatar_;
+
+ //IKの無効化
+ DisableIk();
+
+ return animator_;
+ }
+
+ /// アバターをProjectに登録する
+ ///
+ /// ファイルパス
+ public void CreateAsset(string file_path)
+ {
+ if (avatar_) {
+ AssetDatabase.CreateAsset(avatar_, file_path);
+ } else {
+ throw new System.InvalidOperationException();
+ }
+ }
+
+ ///
+ /// 生成済みのボーンをUnity推奨ポーズに設定
+ ///
+ void SetRequirePose()
+ {
+ foreach (Transform transform in bones_.Select(x=>x.transform)) {
+ SetRequirePose(transform);
+ }
+ }
+
+ ///
+ /// 特定の名前を持つボーンを先代から選び出す
+ ///
+ /// 基点のボーン
+ /// 対象のボーン名
+ /// 対象の先代ボーン
+ ///
+ /// 基点ボーンが探索名なら基点ボーンを返す。
+ ///
+ static Transform FindTransformUpwards(Transform transform, string name)
+ {
+ while ((null != transform) && (transform.name != name)) {
+ transform = transform.parent;
+ }
+ return transform;
+ }
+
+ ///
+ /// 親子関係を見てボーンを水平にする
+ ///
+ /// 対象のボーン
+ /// Z軸のみを回転させるQuaternion
+ static Quaternion ResetHorizontalPose(Transform transform, Transform child_transform)
+ {
+ // ボーンの向きを取得
+ var bone_vector = child_transform.position - transform.position;
+ bone_vector.z = 0f; // 平面化
+ bone_vector.Normalize();
+
+ // 平面化した正規化ベクトルと単位ベクトルを比較して,角度を取得する
+ Vector3 normalized_vector = bone_vector.x >= 0 ? Vector3.right : Vector3.left;
+ float cos_value = Vector3.Dot(bone_vector, normalized_vector);
+ float theta = Mathf.Acos(cos_value) * Mathf.Rad2Deg;
+
+ theta = bone_vector.x >= 0 ? -theta : theta; // ボーンの向きによって回転方向が違う
+
+ return Quaternion.Euler(0f, 0f, theta);
+ }
+
+ ///
+ /// 腕全体を水平にする処理
+ ///
+ /// 手首ボーン
+ /// ひじボーン名
+ /// 腕ボーン名
+ /// 肩ボーン名
+ static void StartResettingHorizontal(Transform wrist, string hinge_name, string arm_name, string shoulder_name)
+ {
+ var hinge = FindTransformUpwards(wrist, hinge_name);
+ var arm = FindTransformUpwards(hinge, arm_name);
+ var shoulder = FindTransformUpwards(arm, shoulder_name);
+ shoulder.transform.localRotation = ResetHorizontalPose(shoulder, arm);
+ arm.transform.localRotation = ResetHorizontalPose(arm, hinge);
+ hinge.transform.localRotation = ResetHorizontalPose(hinge, wrist);
+ }
+
+ ///
+ /// 生成済みのボーンをUnity推奨ポーズに設定
+ ///
+ /// ボーンのトランスフォーム
+ void SetRequirePose(Transform transform)
+ {
+ switch (transform.name) {
+ case "左手首": //Tポーズにする為に腕を持ち上げる
+ StartResettingHorizontal(transform, "左ひじ", "左腕", "左肩");
+ break;
+ case "右手首": //Tポーズにする為に腕を持ち上げる
+ StartResettingHorizontal(transform, "右ひじ", "右腕", "右肩");
+ break;
+ case "腰": goto case "センター";
+ case "センター":
+ if (HasBone("腰") ^ ("センター" == transform.name)) {
+ //腰ボーンを持っていて、現在の入力が腰ボーンなら もしくは 腰ボーンを持っておらず、現在の入力がセンターボーンなら
+ //後ろを向いているので向き直す
+ transform.localRotation = Quaternion.Euler(0.0f, 180.0f, 0.0f);
+ transform.localPosition = new Vector3(-transform.localPosition.x, transform.localPosition.y, -transform.localPosition.z);
+ }
+ break;
+ default:
+ if (root_game_object_.transform.Find("Physics") == transform.parent) {
+ //物理演算ルートなら
+ //後ろを向いているので向き直す
+ transform.localRotation = Quaternion.Euler(0.0f, 180.0f, 0.0f);
+ transform.localPosition = new Vector3(-transform.localPosition.x, transform.localPosition.y, -transform.localPosition.z);
+ }
+ break;
+ }
+ }
+
+ ///
+ /// ボーン存在確認
+ ///
+ /// true:ボーンが存在する, false:ボーンが存在しない
+ /// ボーン名
+ bool HasBone(string name) {
+ return bones_.Any(x=>x.name == name);
+ }
+
+ ///
+ /// MMD用ヒューマノイドボーン作成
+ ///
+ /// ヒューマノイドボーン
+ HumanBone[] CreateHumanBone()
+ {
+ System.Func CreateHint = (key, value)=>{
+ HumanBone human_bone = new HumanBone();
+ human_bone.humanName = key;
+ human_bone.boneName = value;
+ human_bone.limit.useDefaultValues = true;
+ return human_bone;
+ };
+
+ List bone_name = new List();
+
+ //◆必須
+ //△標準逸脱モデル対策
+
+ //顔系
+ //ヒューマノイドボーンは"ヒップ→背骨"のボーンを要求するが、MMDは"上半身→下半身"と接続方向が逆なのでこれらを割り当てる事は出来ない
+ if (HasBone("腰")) {
+ bone_name.Add(CreateHint("Hips", "腰" )); //ヒップ◆△
+ } else {
+ bone_name.Add(CreateHint("Hips", "センター" )); //ヒップ◆
+ }
+ bone_name.Add(CreateHint("Spine", "上半身" )); //背骨◆
+ if (HasBone("胸")) {
+ bone_name.Add(CreateHint("Chest", "胸" )); //胸△
+ } else {
+ bone_name.Add(CreateHint("Chest", "上半身2" )); //胸
+ }
+ bone_name.Add(CreateHint("Neck", "首" )); //首
+ bone_name.Add(CreateHint("Head", "頭" )); //頭◆
+ bone_name.Add(CreateHint("LeftEye", "左目" )); //左目
+ bone_name.Add(CreateHint("RightEye", "右目" )); //右目
+ if (HasBone("あご")) {
+ bone_name.Add(CreateHint("Jaw", "あご" )); //あご△
+ } else if (HasBone("顎")) {
+ bone_name.Add(CreateHint("Jaw", "顎" )); //あご△
+ }
+
+ //足系
+ bone_name.Add(CreateHint("LeftUpperLeg", "左足" )); //左脚上部◆
+ bone_name.Add(CreateHint("RightUpperLeg", "右足" )); //右脚上部◆
+ bone_name.Add(CreateHint("LeftLowerLeg", "左ひざ" )); //左脚◆
+ bone_name.Add(CreateHint("RightLowerLeg", "右ひざ" )); //右脚◆
+ bone_name.Add(CreateHint("LeftFoot", "左足首" )); //左足◆
+ bone_name.Add(CreateHint("RightFoot", "右足首" )); //右足◆
+ bone_name.Add(CreateHint("LeftToes", "左つま先" )); //左足指
+ bone_name.Add(CreateHint("RightToes", "右つま先" )); //右足指
+
+ //手系
+ bone_name.Add(CreateHint("LeftShoulder", "左肩" )); //左肩
+ bone_name.Add(CreateHint("RightShoulder", "右肩" )); //右肩
+ bone_name.Add(CreateHint("LeftUpperArm", "左腕" )); //左腕上部◆
+ bone_name.Add(CreateHint("RightUpperArm", "右腕" )); //右腕上部◆
+ bone_name.Add(CreateHint("LeftLowerArm", "左ひじ" )); //左腕◆
+ bone_name.Add(CreateHint("RightLowerArm", "右ひじ" )); //右腕◆
+ bone_name.Add(CreateHint("LeftHand", "左手首" )); //左手◆
+ bone_name.Add(CreateHint("RightHand", "右手首" )); //右手◆
+
+ //指系
+ bone_name.Add(CreateHint("Left Thumb Proximal", "左親指1" )); //左親指(付根)
+ bone_name.Add(CreateHint("Left Thumb Intermediate", "左親指2" )); //左親指(間接)
+ bone_name.Add(CreateHint("Left Thumb Distal", "左親指先" )); //左親指(先)
+ bone_name.Add(CreateHint("Left Index Proximal", "左人指1" )); //左人差し指(付根)
+ bone_name.Add(CreateHint("Left Index Intermediate", "左人指2" )); //左人差し指(間接)
+ if (HasBone("左人指先")) {
+ bone_name.Add(CreateHint("Left Index Distal", "左人指先" )); //左人差し指(先)△
+ } else {
+ bone_name.Add(CreateHint("Left Index Distal", "左人差指先" )); //左人差し指(先)
+ }
+ bone_name.Add(CreateHint("Left Middle Proximal", "左中指1" )); //左中指(付根)
+ bone_name.Add(CreateHint("Left Middle Intermediate", "左中指2" )); //左中指(間接)
+ bone_name.Add(CreateHint("Left Middle Distal", "左中指先" )); //左中指(先)
+ bone_name.Add(CreateHint("Left Ring Proximal", "左薬指1" )); //左薬指(付根)
+ bone_name.Add(CreateHint("Left Ring Intermediate", "左薬指2" )); //左薬指(間接)
+ bone_name.Add(CreateHint("Left Ring Distal", "左薬指先" )); //左薬指(先)
+ bone_name.Add(CreateHint("Left Little Proximal", "左小指1" )); //左小指(付根)
+ bone_name.Add(CreateHint("Left Little Intermediate", "左小指2" )); //左小指(間接)
+ bone_name.Add(CreateHint("Left Little Distal", "左小指先" )); //左小指(先)
+ bone_name.Add(CreateHint("Right Thumb Proximal", "右親指1" )); //右親指(付根)
+ bone_name.Add(CreateHint("Right Thumb Intermediate", "右親指2" )); //右親指(間接)
+ bone_name.Add(CreateHint("Right Thumb Distal", "右親指先" )); //右親指(先)
+ bone_name.Add(CreateHint("Right Index Proximal", "右人指1" )); //右人差し指(付根)
+ bone_name.Add(CreateHint("Right Index Intermediate", "右人指2" )); //右人差し指(間接)
+ if (HasBone("右人指先")) {
+ bone_name.Add(CreateHint("Right Index Distal", "右人指先" )); //右人差し指(先)△
+ } else {
+ bone_name.Add(CreateHint("Right Index Distal", "右人差指先" )); //右人差し指(先)
+ }
+ bone_name.Add(CreateHint("Right Middle Proximal", "右中指1" )); //右中指(付根)
+ bone_name.Add(CreateHint("Right Middle Intermediate", "右中指2" )); //右中指(間接)
+ bone_name.Add(CreateHint("Right Middle Distal", "右中指先" )); //右中指(先)
+ bone_name.Add(CreateHint("Right Ring Proximal", "右薬指1" )); //右薬指(付根)
+ bone_name.Add(CreateHint("Right Ring Intermediate", "右薬指2" )); //右薬指(間接)
+ bone_name.Add(CreateHint("Right Ring Distal", "右薬指先" )); //右薬指(先)
+ bone_name.Add(CreateHint("Right Little Proximal", "右小指1" )); //右小指(付根)
+ bone_name.Add(CreateHint("Right Little Intermediate", "右小指2" )); //右小指(間接)
+ bone_name.Add(CreateHint("Right Little Distal", "右小指先" )); //右小指(先)
+
+ return bone_name.Where(x=>!string.IsNullOrEmpty(x.boneName)).ToArray();
+ }
+
+ ///
+ /// MMD用スケルトンボーン作成
+ ///
+ /// スケルトンボーン
+ SkeletonBone[] CreateSkeletonBone()
+ {
+ IEnumerable bones_enumerator = bones_;
+
+ //Hipsボーンの親ボーン迄SkeletonBoneに入れる必要が有るので、確認と追加
+ string hips_bone_name = ((HasBone("腰"))? "腰": "センター");
+ Transform hips_parent_bone = bones_.Where(x=>x.name == hips_bone_name).Select(x=>x.transform.parent).FirstOrDefault();
+ if (null != hips_parent_bone) {
+ //Hipsボーンの親ボーンが有るなら
+ //Hipsボーンの親ボーンがbones_に含まれているか確認する
+ if (!HasBone(hips_parent_bone.name)) {
+ //Hipsボーンの親ボーンがbones_に無いなら
+ //追加(Hipsボーン依りも前に追加しないといけないので注意)
+ bones_enumerator = Enumerable.Repeat(hips_parent_bone.gameObject, 1)
+ .Concat(bones_enumerator);
+ }
+ }
+
+ var result = bones_enumerator.Select(x=>{
+ SkeletonBone skeleton_bone = new SkeletonBone();
+ skeleton_bone.name = x.name;
+ Transform transform = x.transform;
+ skeleton_bone.position = transform.localPosition;
+ skeleton_bone.rotation = transform.localRotation;
+ skeleton_bone.scale = transform.localScale;
+ return skeleton_bone;
+ });
+ return result.ToArray();
+ }
+
+ ///
+ /// IKの無効化
+ ///
+ void DisableIk()
+ {
+ foreach(CCDIKSolver ik_solver in root_game_object_.GetComponent().ik_list) {
+ ik_solver.enabled = false;
+ }
+ }
+
+ GameObject root_game_object_ = null;
+ GameObject[] bones_ = null;
+ Avatar avatar_ = null;
+ Animator animator_ = null;
+}
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/Editor/MMDLoader/Private/ComputeSkin.cs b/Assets/Scripts/3rd/mmd-for-unity-master/Editor/MMDLoader/Private/ComputeSkin.cs
new file mode 100644
index 000000000..ee072b28f
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/Editor/MMDLoader/Private/ComputeSkin.cs
@@ -0,0 +1,31 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using UnityEngine;
+//using Mono.Simd;
+
+namespace MMD
+{
+ namespace Skin
+ {
+ ///
+ /// スキンの計算を行う
+ ///
+ public class ComputeMorph
+ {
+ ///
+ /// モーフベクトルをweight値から計算する
+ ///
+ /// モーフベクトル
+ /// ウェイト
+ /// 表情の移動ベクトル
+ public static void Compute(ref Vector3[] resultVector, Vector3[] morphVector, float weight)
+ {
+ // モーフベクトルを伸び縮みさせたものを結果として返す
+ for (int i = 0; i < morphVector.Length; i++)
+ resultVector[i] = morphVector[i] * weight;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/Editor/MMDLoader/Private/MMDFormat.cs b/Assets/Scripts/3rd/mmd-for-unity-master/Editor/MMDLoader/Private/MMDFormat.cs
new file mode 100644
index 000000000..9a50446c0
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/Editor/MMDLoader/Private/MMDFormat.cs
@@ -0,0 +1,841 @@
+using System.Collections;
+using System.Collections.Generic;
+using System;
+using System.IO;
+using UnityEngine;
+using System.Text;
+
+// Reference URL:
+// http://blog.goo.ne.jp/torisu_tetosuki/e/209ad341d3ece2b1b4df24abf619d6e4
+// http://mikudan.blog120.fc2.com/blog-entry-280.html
+
+namespace MMD
+{
+ namespace PMX
+ {
+ // PMXフォーマットクラス
+ public class PMXFormat
+ {
+ public MetaHeader meta_header;
+ public Header header;
+ public VertexList vertex_list;
+ public FaceVertexList face_vertex_list;
+ public TextureList texture_list;
+ public MaterialList material_list;
+ public BoneList bone_list;
+ public MorphList morph_list;
+ public DisplayFrameList display_frame_list;
+ public RigidbodyList rigidbody_list;
+ public RigidbodyJointList rigidbody_joint_list;
+
+ public class MetaHeader
+ {
+ public string path; // フルパス
+ public string name; // 拡張子とパス抜きのファイルの名前
+ public string folder; // ファイル名抜きのパス
+ }
+
+ public class Header
+ {
+ public enum StringCode {
+ Utf16le,
+ Utf8,
+ }
+ public enum IndexSize {
+ Byte1 = 1,
+ Byte2 = 2,
+ Byte4 = 4,
+ }
+ public byte[] magic; // "PMX "
+ public float version; // 00 00 80 3F == 1.00
+
+ public byte dataSize;
+ public StringCode encodeMethod;
+ public byte additionalUV;
+ public IndexSize vertexIndexSize;
+ public IndexSize textureIndexSize;
+ public IndexSize materialIndexSize;
+ public IndexSize boneIndexSize;
+ public IndexSize morphIndexSize;
+ public IndexSize rigidbodyIndexSize;
+
+ public string model_name;
+ public string model_english_name;
+ public string comment;
+ public string english_comment;
+ }
+
+ public class VertexList
+ {
+ public Vertex[] vertex; // 頂点データ(38bytes/頂点)
+ }
+
+ public class Vertex
+ {
+ public enum WeightMethod {
+ BDEF1,
+ BDEF2,
+ BDEF4,
+ SDEF,
+ QDEF,
+ }
+ public Vector3 pos; // x, y, z // 座標
+ public Vector3 normal_vec; // nx, ny, nz // 法線ベクトル
+ public Vector2 uv; // u, v // UV座標 // MMDは頂点UV
+ public Vector4[] add_uv; // x,y,z,w
+ public BoneWeight bone_weight;
+ public float edge_magnification;
+
+ }
+
+ public interface BoneWeight
+ {
+ Vertex.WeightMethod method {get;}
+ uint bone1_ref {get;}
+ uint bone2_ref {get;}
+ uint bone3_ref {get;}
+ uint bone4_ref {get;}
+ float bone1_weight {get;}
+ float bone2_weight {get;}
+ float bone3_weight {get;}
+ float bone4_weight {get;}
+ Vector3 c_value {get;}
+ Vector3 r0_value {get;}
+ Vector3 r1_value {get;}
+ }
+
+ public class BDEF1 : BoneWeight
+ {
+ public Vertex.WeightMethod method {get{return Vertex.WeightMethod.BDEF1;}}
+ public uint bone1_ref {get; set;}
+ public uint bone2_ref {get{return 0;}}
+ public uint bone3_ref {get{return 0;}}
+ public uint bone4_ref {get{return 0;}}
+ public float bone1_weight {get{return 1.0f;}}
+ public float bone2_weight {get{return 0.0f;}}
+ public float bone3_weight {get{return 0.0f;}}
+ public float bone4_weight {get{return 0.0f;}}
+ public Vector3 c_value {get{return Vector3.zero;}}
+ public Vector3 r0_value {get{return Vector3.zero;}}
+ public Vector3 r1_value {get{return Vector3.zero;}}
+ }
+ public class BDEF2 : BoneWeight
+ {
+ public Vertex.WeightMethod method {get{return Vertex.WeightMethod.BDEF2;}}
+ public uint bone1_ref {get; set;}
+ public uint bone2_ref {get; set;}
+ public float bone1_weight {get; set;}
+ public uint bone3_ref {get{return 0;}}
+ public uint bone4_ref {get{return 0;}}
+ public float bone2_weight {get{return 1.0f - bone1_weight;}}
+ public float bone3_weight {get{return 0.0f;}}
+ public float bone4_weight {get{return 0.0f;}}
+ public Vector3 c_value {get{return Vector3.zero;}}
+ public Vector3 r0_value {get{return Vector3.zero;}}
+ public Vector3 r1_value {get{return Vector3.zero;}}
+ }
+ public class BDEF4 : BoneWeight
+ {
+ public Vertex.WeightMethod method {get{return Vertex.WeightMethod.BDEF4;}}
+ public uint bone1_ref {get; set;}
+ public uint bone2_ref {get; set;}
+ public uint bone3_ref {get; set;}
+ public uint bone4_ref {get; set;}
+ public float bone1_weight {get; set;}
+ public float bone2_weight {get; set;}
+ public float bone3_weight {get; set;}
+ public float bone4_weight {get; set;}
+ public Vector3 c_value {get{return Vector3.zero;}}
+ public Vector3 r0_value {get{return Vector3.zero;}}
+ public Vector3 r1_value {get{return Vector3.zero;}}
+ }
+ public class SDEF : BoneWeight
+ {
+ public Vertex.WeightMethod method {get{return Vertex.WeightMethod.SDEF;}}
+ public uint bone1_ref {get; set;}
+ public uint bone2_ref {get; set;}
+ public float bone1_weight {get; set;}
+ public Vector3 c_value {get; set;}
+ public Vector3 r0_value {get; set;}
+ public Vector3 r1_value {get; set;}
+ public uint bone3_ref {get{return 0;}}
+ public uint bone4_ref {get{return 0;}}
+ public float bone2_weight {get{return 1.0f - bone1_weight;}}
+ public float bone3_weight {get{return 0.0f;}}
+ public float bone4_weight {get{return 0.0f;}}
+ }
+ public class QDEF : BoneWeight
+ {
+ public Vertex.WeightMethod method {get{return Vertex.WeightMethod.QDEF;}}
+ public uint bone1_ref {get; set;}
+ public uint bone2_ref {get; set;}
+ public uint bone3_ref {get; set;}
+ public uint bone4_ref {get; set;}
+ public float bone1_weight {get; set;}
+ public float bone2_weight {get; set;}
+ public float bone3_weight {get; set;}
+ public float bone4_weight {get; set;}
+ public Vector3 c_value {get{return Vector3.zero;}}
+ public Vector3 r0_value {get{return Vector3.zero;}}
+ public Vector3 r1_value {get{return Vector3.zero;}}
+ }
+
+ // 面頂点リスト
+ public class FaceVertexList
+ {
+ public uint[] face_vert_index; // 頂点番号(3個/面)
+ }
+
+ public class TextureList
+ {
+ public string[] texture_file; // 100byte * 10個固定
+ }
+
+ public class MaterialList
+ {
+ public Material[] material; // 材質データ(70bytes/material)
+ }
+
+ public class Material
+ {
+ [Flags]
+ public enum Flag {
+ Reversible = 1<< 0, //両面描画
+ CastShadow = 1<< 1, //地面影
+ CastSelfShadow = 1<< 2, //セルフシャドウマップへの描画
+ ReceiveSelfShadow = 1<< 3, //セルフシャドウの描画
+ Edge = 1<< 4, //エッジ描画
+ }
+ public enum SphereMode {
+ Null, //無し
+ MulSphere, //乗算スフィア
+ AddSphere, //加算スフィア
+ SubTexture, //サブテクスチャ
+ }
+ public string name;
+ public string english_name;
+
+ public Color diffuse_color; // dr, dg, db, da // 減衰色
+ public Color specular_color; // sr, sg, sb // 光沢色
+ public float specularity;
+ public Color ambient_color; // mr, mg, mb // 環境色(ambient)
+ public Flag flag;
+ public Color edge_color; // r, g, b, a
+ public float edge_size;
+ public uint usually_texture_index;
+ public uint sphere_texture_index;
+ public SphereMode sphere_mode;
+ public byte common_toon;
+ public uint toon_texture_index;
+ public string memo;
+ public uint face_vert_count; // 面頂点数 // インデックスに変換する場合は、材質0から順に加算
+ }
+
+ public class BoneList
+ {
+ public Bone[] bone; // ボーンデータ(39bytes/bone)
+ }
+
+ public class Bone
+ {
+ [Flags]
+ public enum Flag {
+ Connection = 1<< 0, //接続先(PMD子ボーン指定)表示方法(ON:ボーンで指定、OFF:座標オフセットで指定)
+ Rotatable = 1<< 1, //回転可能
+ Movable = 1<< 2, //移動可能
+ DisplayFlag = 1<< 3, //表示
+ CanOperate = 1<< 4, //操作可
+ IkFlag = 1<< 5, //IK
+ AddLocal = 1<< 7, //ローカル付与 | 付与対象(ON:親のローカル変形量、OFF:ユーザー変形値/IKリンク/多重付与)
+ AddRotation = 1<< 8, //回転付与
+ AddMove = 1<< 9, //移動付与
+ FixedAxis = 1<<10, //軸固定
+ LocalAxis = 1<<11, //ローカル軸
+ PhysicsTransform = 1<<12, //物理後変形
+ ExternalParentTransform = 1<<13, //外部親変形
+ }
+ public string bone_name; // ボーン名
+ public string bone_english_name;
+ public Vector3 bone_position;
+ public uint parent_bone_index; // 親ボーン番号(ない場合はuint.MaxValue)
+ public int transform_level;
+ public Flag bone_flag;
+ public Vector3 position_offset;
+ public uint connection_index;
+ public uint additional_parent_index;
+ public float additional_rate;
+ public Vector3 axis_vector;
+ public Vector3 x_axis_vector;
+ public Vector3 z_axis_vector;
+ public uint key_value;
+ public IK_Data ik_data;
+ }
+
+ public class IK_Data
+ {
+ public uint ik_bone_index; // IKボーン番号
+ public uint iterations; // 再帰演算回数 // IK値1
+ public float limit_angle;
+ public IK_Link[] ik_link;
+ }
+
+ public class IK_Link
+ {
+ public uint target_bone_index;
+ public byte angle_limit;
+ public Vector3 lower_limit;
+ public Vector3 upper_limit;
+ }
+
+ public class MorphList
+ {
+ public MorphData[] morph_data; // 表情データ((25+16*skin_vert_count)/skin)
+ }
+
+ public class MorphData
+ {
+ public enum Panel {
+ Base,
+ EyeBrow,
+ Eye,
+ Lip,
+ Other,
+ }
+ public enum MorphType {
+ Group,
+ Vertex,
+ Bone,
+ Uv,
+ Adduv1,
+ Adduv2,
+ Adduv3,
+ Adduv4,
+ Material,
+
+ Flip,
+ Impulse,
+ }
+ public string morph_name; // 表情名
+ public string morph_english_name; // 表情英名
+ public Panel handle_panel;
+ public MorphType morph_type;
+ public MorphOffset[] morph_offset;
+ }
+
+ public interface MorphOffset {};
+
+ public class VertexMorphOffset : MorphOffset
+ {
+ public uint vertex_index;
+ public Vector3 position_offset;
+ }
+ public class UVMorphOffset : MorphOffset
+ {
+ public uint vertex_index;
+ public Vector4 uv_offset;
+ }
+ public class BoneMorphOffset : MorphOffset
+ {
+ public uint bone_index;
+ public Vector3 move_value;
+ public Quaternion rotate_value;
+ }
+ public class MaterialMorphOffset : MorphOffset
+ {
+ public enum OffsetMethod {
+ Mul,
+ Add,
+ }
+ public uint material_index;
+ public OffsetMethod offset_method;
+ public Color diffuse;
+ public Color specular;
+ public float specularity;
+ public Color ambient;
+ public Color edge_color;
+ public float edge_size;
+ public Color texture_coefficient;
+ public Color sphere_texture_coefficient;
+ public Color toon_texture_coefficient;
+ }
+ public class GroupMorphOffset : MorphOffset
+ {
+ public uint morph_index;
+ public float morph_rate;
+ }
+
+ public class ImpulseMorphOffset : MorphOffset
+ {
+ public uint rigidbody_index;
+ public byte local_flag;
+ public Vector3 move_velocity;
+ public Vector3 rotation_torque;
+ }
+
+ public class DisplayFrameList
+ {
+ public DisplayFrame[] display_frame;
+ }
+
+ public class DisplayFrame
+ {
+ public string display_name;
+ public string display_english_name;
+ public byte special_frame_flag;
+ public DisplayElement[] display_element;
+ }
+
+ public class DisplayElement
+ {
+ public byte element_target;
+ public uint element_target_index;
+ }
+
+ public class RigidbodyList
+ {
+ public PMX.PMXFormat.Rigidbody[] rigidbody;
+ }
+
+ ///
+ /// 剛体
+ ///
+ public class Rigidbody
+ {
+ public enum ShapeType {
+ Sphere, //球
+ Box, //箱
+ Capsule, //カプセル
+ }
+ public enum OperationType {
+ Static, //ボーン追従
+ Dynamic, //物理演算
+ DynamicAndPosAdjust, //物理演算(Bone位置合せ)
+ }
+ public string name; // 諸データ:名称 ,20byte
+ public string english_name; // 諸データ:名称 ,20byte
+ public uint rel_bone_index;// 諸データ:関連ボーン番号
+ public byte group_index; // 諸データ:グループ
+ public ushort ignore_collision_group;
+ public ShapeType shape_type; // 形状:タイプ(0:球、1:箱、2:カプセル)
+ public Vector3 shape_size;
+ public Vector3 collider_position; // 位置:位置(x, y, z)
+ public Vector3 collider_rotation; // 位置:回転(rad(x), rad(y), rad(z))
+ public float weight; // 諸データ:質量 // 00 00 80 3F // 1.0
+ public float position_dim; // 諸データ:移動減 // 00 00 00 00
+ public float rotation_dim; // 諸データ:回転減 // 00 00 00 00
+ public float recoil; // 諸データ:反発力 // 00 00 00 00
+ public float friction; // 諸データ:摩擦力 // 00 00 00 00
+ public OperationType operation_type; // 諸データ:タイプ(0:Bone追従、1:物理演算、2:物理演算(Bone位置合せ)) // 00 // Bone追従
+ }
+
+ public class RigidbodyJointList
+ {
+ public MMD.PMX.PMXFormat.Joint[] joint;
+ }
+
+ public class Joint
+ {
+ public enum OperationType {
+ Spring6DOF, //スプリング6DOF
+ }
+ public string name; // 20byte
+ public string english_name;
+ public OperationType operation_type;
+ public uint rigidbody_a; // 諸データ:剛体A
+ public uint rigidbody_b; // 諸データ:剛体B
+ public Vector3 position; // 諸データ:位置(x, y, z) // 諸データ:位置合せでも設定可
+ public Vector3 rotation; // 諸データ:回転(rad(x), rad(y), rad(z))
+ public Vector3 constrain_pos_lower; // 制限:移動1(x, y, z)
+ public Vector3 constrain_pos_upper; // 制限:移動2(x, y, z)
+ public Vector3 constrain_rot_lower; // 制限:回転1(rad(x), rad(y), rad(z))
+ public Vector3 constrain_rot_upper; // 制限:回転2(rad(x), rad(y), rad(z))
+ public Vector3 spring_position; // ばね:移動(x, y, z)
+ public Vector3 spring_rotation; // ばね:回転(rad(x), rad(y), rad(z))
+ }
+ }
+ }
+
+ namespace PMD
+ {
+ // PMDのフォーマットクラス
+ public class PMDFormat
+ {
+ public string path; // フルパス
+ public string name; // 拡張子とパス抜きのファイルの名前
+ public string folder; // ファイル名抜きのパス
+
+ public Header head;
+ public VertexList vertex_list;
+ public FaceVertexList face_vertex_list;
+ public MaterialList material_list;
+ public BoneList bone_list;
+ public IKList ik_list;
+ public SkinList skin_list;
+ public SkinNameList skin_name_list;
+ public BoneNameList bone_name_list;
+ public BoneDisplayList bone_display_list;
+ public EnglishHeader eg_head;
+ public EnglishBoneNameList eg_bone_name_list;
+ public EnglishSkinNameList eg_skin_name_list;
+ public EnglishBoneDisplayList eg_bone_display_list;
+ public ToonTextureList toon_texture_list;
+ public RigidbodyList rigidbody_list;
+ public RigidbodyJointList rigidbody_joint_list;
+
+ public class Header
+ {
+ public byte[] magic; // "Pmd"
+ public float version; // 00 00 80 3F == 1.00
+ public string model_name;
+ public string comment;
+ }
+
+ public class VertexList
+ {
+ public uint vert_count; // 頂点数
+ public Vertex[] vertex; // 頂点データ(38bytes/頂点)
+ }
+
+ public class Vertex
+ {
+ public Vector3 pos; // x, y, z // 座標
+ public Vector3 normal_vec; // nx, ny, nz // 法線ベクトル
+ public Vector2 uv; // u, v // UV座標 // MMDは頂点UV
+ public ushort[] bone_num; // ボーン番号1、番号2 // モデル変形(頂点移動)時に影響
+ public byte bone_weight; // ボーン1に与える影響度 // min:0 max:100 // ボーン2への影響度は、(100 - bone_weight)
+ public byte edge_flag; // 0:通常、1:エッジ無効 // エッジ(輪郭)が有効の場合
+ }
+
+ // 面頂点リスト
+ public class FaceVertexList
+ {
+ public uint face_vert_count; // 頂点数
+ public ushort[] face_vert_index; // 頂点番号(3個/面)
+ }
+
+ public class MaterialList
+ {
+ public uint material_count; // 材質数
+ public Material[] material; // 材質データ(70bytes/material)
+ }
+
+ public class Material
+ {
+ public Color diffuse_color; // dr, dg, db // 減衰色
+ public float alpha;
+ public float specularity;
+ public Color specular_color; // sr, sg, sb // 光沢色
+ public Color mirror_color; // mr, mg, mb // 環境色(ambient)
+ public byte toon_index; // toon??.bmp // 0.bmp:0xFF, 1(01).bmp:0x00 ・・・ 10.bmp:0x09
+ public byte edge_flag; // 輪郭、影
+ public uint face_vert_count; // 面頂点数 // インデックスに変換する場合は、材質0から順に加算
+ public string texture_file_name; // テクスチャファイル名またはスフィアファイル名 // 20バイトぎりぎりまで使える(終端の0x00は無くても動く)
+ public string sphere_map_name; // スフィアマップ用
+
+ /*
+ テクスチャファイル名またはスフィアファイル名の補足:
+
+ テクスチャファイルにスフィアファイルを乗算または加算する場合
+ (MMD 5.12以降)
+ "テクスチャ名.bmp*スフィア名.sph" で乗算
+ "テクスチャ名.bmp*スフィア名.spa" で加算
+
+ (MMD 5.11)
+ "テクスチャ名.bmp/スフィア名.sph" で乗算
+
+ (MMD 5.09あたり-)
+ "テクスチャ名.bmp" または "スフィア名.sph"
+ */
+ }
+
+ public class BoneList
+ {
+ public ushort bone_count; // ボーン数
+ public Bone[] bone; // ボーンデータ(39bytes/bone)
+ }
+
+ public class Bone
+ {
+ public string bone_name; // ボーン名
+ public ushort parent_bone_index; // 親ボーン番号(ない場合は0xFFFF)
+ public ushort tail_pos_bone_index; // tail位置のボーン番号(チェーン末端の場合は0xFFFF) // 親:子は1:多なので、主に位置決め用
+ public byte bone_type; // ボーンの種類
+ public ushort ik_parent_bone_index; // IKボーン番号(影響IKボーン。ない場合は0)
+ public Vector3 bone_head_pos; // x, y, z // ボーンのヘッドの位置
+
+ /*
+ ・ボーンの種類
+ 0:回転 1:回転と移動 2:IK 3:不明 4:IK影響下 5:回転影響下 6:IK接続先 7:非表示 8:捻り 9:回転運動
+ */
+ }
+
+ public class IKList
+ {
+ public ushort ik_data_count; // IKデータ数
+ public IK[] ik_data; // IKデータ((11+2*ik_chain_length)/IK)
+ }
+
+ public class IK
+ {
+ public ushort ik_bone_index; // IKボーン番号
+ public ushort ik_target_bone_index; // IKターゲットボーン番号 // IKボーンが最初に接続するボーン
+ public byte ik_chain_length; // IKチェーンの長さ(子の数)
+ public ushort iterations; // 再帰演算回数 // IK値1
+ public float control_weight; // IKの影響度 // IK値2
+ public ushort[] ik_child_bone_index; // IK影響下のボーン番号
+ }
+
+ public class SkinList
+ {
+ public ushort skin_count; // 表情数
+ public SkinData[] skin_data; // 表情データ((25+16*skin_vert_count)/skin)
+ }
+
+ public class SkinData
+ {
+ public string skin_name; // 表情名
+ public uint skin_vert_count; // 表情用の頂点数
+ public byte skin_type; // 表情の種類 // 0:base、1:まゆ、2:目、3:リップ、4:その他
+ public SkinVertexData[] skin_vert_data; // 表情用の頂点のデータ(16bytes/vert)
+ }
+
+ public class SkinVertexData
+ {
+ // 実際の頂点を参照するには
+ // int num = vertex_count - skin_vert_count;
+ // skin_vert[num]みたいな形で参照しないと無理
+ public uint skin_vert_index; // 表情用の頂点の番号(頂点リストにある番号)
+ public Vector3 skin_vert_pos; // x, y, z // 表情用の頂点の座標(頂点自体の座標)
+ }
+
+ // 表情用枠名
+ public class SkinNameList
+ {
+ public byte skin_disp_count;
+ public ushort[] skin_index; // 表情番号
+ }
+
+ // ボーン用枠名
+ public class BoneNameList
+ {
+ public byte bone_disp_name_count;
+ public string[] disp_name; // 50byte
+ }
+
+ // ボーン枠用表示リスト
+ public class BoneDisplayList
+ {
+ public uint bone_disp_count;
+ public BoneDisplay[] bone_disp;
+ }
+
+ public class BoneDisplay
+ {
+ public ushort bone_index; // 枠用ボーン番号
+ public byte bone_disp_frame_index; // 表示枠番号
+ }
+
+ ///
+ /// 英語表記用ヘッダ
+ ///
+ public class EnglishHeader
+ {
+ public byte english_name_compatibility; // 01で英名対応
+ public string model_name_eg; // 20byte
+ public string comment_eg; // 256byte
+ }
+
+ ///
+ /// 英語表記用ボーンの英語名
+ ///
+ public class EnglishBoneNameList
+ {
+ public string[] bone_name_eg; // 20byte * bone_count
+ }
+
+ public class EnglishSkinNameList
+ {
+ // baseは英名が登録されない
+ public string[] skin_name_eg; // 20byte * skin_count-1
+ }
+
+ public class EnglishBoneDisplayList
+ {
+ public string[] disp_name_eg; // 50byte * bone_disp_name_count
+ }
+
+ public class ToonTextureList
+ {
+ public string[] toon_texture_file; // 100byte * 10個固定
+ }
+
+ public class RigidbodyList
+ {
+ public uint rigidbody_count;
+ public PMD.PMDFormat.Rigidbody[] rigidbody;
+ }
+
+ ///
+ /// 剛体
+ ///
+ public class Rigidbody
+ {
+ public string rigidbody_name; // 諸データ:名称 ,20byte
+ public int rigidbody_rel_bone_index;// 諸データ:関連ボーン番号
+ public byte rigidbody_group_index; // 諸データ:グループ
+ public ushort rigidbody_group_target; // 諸データ:グループ:対象 // 0xFFFFとの差
+ public byte shape_type; // 形状:タイプ(0:球、1:箱、2:カプセル)
+ public float shape_w; // 形状:半径(幅)
+ public float shape_h; // 形状:高さ
+ public float shape_d; // 形状:奥行
+ public Vector3 pos_pos; // 位置:位置(x, y, z)
+ public Vector3 pos_rot; // 位置:回転(rad(x), rad(y), rad(z))
+ public float rigidbody_weight; // 諸データ:質量 // 00 00 80 3F // 1.0
+ public float rigidbody_pos_dim; // 諸データ:移動減 // 00 00 00 00
+ public float rigidbody_rot_dim; // 諸データ:回転減 // 00 00 00 00
+ public float rigidbody_recoil; // 諸データ:反発力 // 00 00 00 00
+ public float rigidbody_friction; // 諸データ:摩擦力 // 00 00 00 00
+ public byte rigidbody_type; // 諸データ:タイプ(0:Bone追従、1:物理演算、2:物理演算(Bone位置合せ)) // 00 // Bone追従
+ }
+
+ public class RigidbodyJointList
+ {
+ public uint joint_count;
+ public Joint[] joint;
+ }
+
+ public class Joint
+ {
+ public string joint_name; // 20byte
+ public uint joint_rigidbody_a; // 諸データ:剛体A
+ public uint joint_rigidbody_b; // 諸データ:剛体B
+ public Vector3 joint_pos; // 諸データ:位置(x, y, z) // 諸データ:位置合せでも設定可
+ public Vector3 joint_rot; // 諸データ:回転(rad(x), rad(y), rad(z))
+ public Vector3 constrain_pos_1; // 制限:移動1(x, y, z)
+ public Vector3 constrain_pos_2; // 制限:移動2(x, y, z)
+ public Vector3 constrain_rot_1; // 制限:回転1(rad(x), rad(y), rad(z))
+ public Vector3 constrain_rot_2; // 制限:回転2(rad(x), rad(y), rad(z))
+ public Vector3 spring_pos; // ばね:移動(x, y, z)
+ public Vector3 spring_rot; // ばね:回転(rad(x), rad(y), rad(z))
+ }
+ }
+ }
+ namespace VMD
+ {
+ // VMDのフォーマットクラス
+ public class VMDFormat
+ {
+ public string name;
+ public string path;
+ public string folder;
+
+ public Header header;
+ public MotionList motion_list;
+ public SkinList skin_list;
+ public LightList light_list;
+ public CameraList camera_list;
+ public SelfShadowList self_shadow_list;
+
+ public class Header
+ {
+ public string vmd_header; // 30byte, "Vocaloid Motion Data 0002"
+ public string vmd_model_name; // 20byte
+ }
+
+ public class MotionList
+ {
+ public uint motion_count;
+ public Dictionary> motion;
+ }
+
+ public class Motion
+ {
+ public string bone_name; // 15byte
+ public uint frame_no;
+ public Vector3 location;
+ public Quaternion rotation;
+ public byte[] interpolation; // [4][4][4], 64byte
+
+ // なんか不便になりそうな気がして
+ public byte GetInterpolation(int i, int j, int k)
+ {
+ return this.interpolation[i*16+j*4+k];
+ }
+
+ public void SetInterpolation(byte val, int i, int j, int k)
+ {
+ this.interpolation[i*16+j*4+k] = val;
+ }
+ }
+
+ ///
+ /// 表情リスト
+ ///
+ public class SkinList
+ {
+ public uint skin_count;
+ public Dictionary> skin;
+ }
+
+ public class SkinData
+ {
+ public string skin_name; // 15byte
+ public uint frame_no;
+ public float weight;
+ }
+
+ public class CameraList
+ {
+ public uint camera_count;
+ public CameraData[] camera;
+ }
+
+ public class CameraData
+ {
+ public uint frame_no;
+ public float length;
+ public Vector3 location;
+ public Vector3 rotation; // オイラー角, X軸は符号が反転している
+ public byte[] interpolation; // [6][4], 24byte(未検証)
+ public uint viewing_angle;
+ public byte perspective; // 0:on 1:off
+
+ public byte GetInterpolation(int i, int j)
+ {
+ return this.interpolation[i*6+j];
+ }
+
+ public void SetInterpolation(byte val, int i, int j)
+ {
+ this.interpolation[i*6+j] = val;
+ }
+ }
+
+ public class LightList
+ {
+ public uint light_count;
+ public LightData[] light;
+ }
+
+ public class LightData
+ {
+ public uint frame_no;
+ public Color rgb; // αなし, 256
+ public Vector3 location;
+ }
+
+ public class SelfShadowList
+ {
+ public uint self_shadow_count;
+ public SelfShadowData[] self_shadow;
+ }
+
+ public class SelfShadowData
+ {
+ public uint frame_no;
+ public byte mode; //00-02
+ public float distance; // 0.1 - (dist * 0.00001)
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/Editor/MMDLoader/Private/MMDMathf.cs b/Assets/Scripts/3rd/mmd-for-unity-master/Editor/MMDLoader/Private/MMDMathf.cs
new file mode 100644
index 000000000..7314518a7
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/Editor/MMDLoader/Private/MMDMathf.cs
@@ -0,0 +1,108 @@
+using UnityEngine;
+using System.Collections;
+
+public class MMDMathf
+{
+ public static Matrix4x4 CreateRotationXMatrix(float rad)
+ {
+ Matrix4x4 m = Matrix4x4.identity;
+ float cos = Mathf.Cos(rad), sin = Mathf.Sin(rad);
+ m.m11 = cos; m.m12 = -sin;
+ m.m21 = sin; m.m22 = cos;
+ return m;
+ }
+
+ public static Matrix4x4 CreateRotationYMatrix(float rad)
+ {
+ Matrix4x4 m = Matrix4x4.identity;
+ float cos = Mathf.Cos(rad), sin = Mathf.Sin(rad);
+ m.m00 = cos; m.m02 = sin;
+ m.m20 = -sin; m.m22 = cos;
+ return m;
+ }
+
+ public static Matrix4x4 CreateRotationZMatrix(float rad)
+ {
+ Matrix4x4 m = Matrix4x4.identity;
+ float cos = Mathf.Cos(rad), sin = Mathf.Sin(rad);
+ m.m01 = cos; m.m02 = -sin;
+ m.m11 = sin; m.m12 = cos;
+ return m;
+ }
+
+ public static Matrix4x4 CreateRotationMatrixFromRollPitchYaw(float r, float p, float y)
+ {
+ Matrix4x4 m = Matrix4x4.identity;
+ float rc = Mathf.Cos(r), rs = Mathf.Sin(r); // Z
+ float pc = Mathf.Cos(p), ps = Mathf.Sin(p); // Y
+ float yc = Mathf.Cos(y), ys = Mathf.Sin(y);; // X
+ m.m00 = rc*pc; m.m01 = rc*ps*ys-rs*yc; m.m02 = rc*ps*yc+rs*ys;
+ m.m10 = rs*pc; m.m11 = rs*ps*ys+rc*yc; m.m12 = rs*ps*yc-rc*ys;
+ m.m20 = -ps; m.m21 = pc*ys; m.m22 = pc*yc;
+ return m;
+ }
+
+ public static Vector3 CreatePositionFromMatrix(Matrix4x4 m)
+ {
+ return new Vector3(m.m30, m.m31, m.m33);
+ }
+
+ public static Quaternion CreateQuaternionFromRotationMatrix(Matrix4x4 m)
+ {
+ Quaternion q;
+ const float quad = 1.0f / 4.0f;
+ q.x = ( m.m00 + m.m11 + m.m22 + 1.0f) * quad;
+ q.y = ( m.m00 - m.m11 - m.m22 + 1.0f) * quad;
+ q.z = (-m.m00 + m.m11 - m.m22 + 1.0f) * quad;
+ q.w = (-m.m00 - m.m11 + m.m22 + 1.0f) * quad;
+ if (q.x < 0.0f) q.x = 0.0f;
+ if (q.y < 0.0f) q.y = 0.0f;
+ if (q.z < 0.0f) q.z = 0.0f;
+ if (q.w < 0.0f) q.w = 0.0f;
+ q.x = Mathf.Sqrt(q.x);
+ q.y = Mathf.Sqrt(q.y);
+ q.z = Mathf.Sqrt(q.z);
+ q.w = Mathf.Sqrt(q.w);
+ if (q.x >= q.y && q.x >= q.z && q.x >= q.w)
+ {
+ q.x *= 1.0f;
+ q.y *= Sign(m.m22 - m.m13);
+ q.z *= Sign(m.m03 - m.m21);
+ q.w *= Sign(m.m11 - m.m02);
+ }
+ else if (q.y >= q.x && q.y >= q.z && q.y >= q.w)
+ {
+ q.x *= Sign(m.m22 - m.m13);
+ q.y *= 1.0f;
+ q.z *= Sign(m.m11 + m.m02);
+ q.w *= Sign(m.m03 + m.m21);
+ }
+ else if(q.z >= q.x && q.z >= q.y && q.z >= q.w) {
+ q.x *= Sign(m.m03 - m.m21);
+ q.y *= Sign(m.m11 + m.m02);
+ q.z *= +1.0f;
+ q.w *= Sign(m.m22 + m.m13);
+ } else if(q.w >= q.x && q.w >= q.y && q.w >= q.z) {
+ q.x *= Sign(m.m11 - m.m02);
+ q.y *= Sign(m.m21 + m.m03);
+ q.z *= Sign(m.m22 + m.m13);
+ q.w *= +1.0f;
+ }
+ float r = 1.0f / Norm(q.x, q.y, q.z, q.w);
+ q.x *= r;
+ q.y *= r;
+ q.z *= r;
+ q.w *= r;
+ return q;
+ }
+
+ private static float Sign(float x)
+ {
+ return (x >= 0.0f) ? 1.0f : -1.0f;
+ }
+
+ private static float Norm(float a, float b, float c, float d)
+ {
+ return Mathf.Sqrt(a*a+b*b+c*c+d*d);
+ }
+}
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/Editor/MMDLoader/Private/ModelAgent.cs b/Assets/Scripts/3rd/mmd-for-unity-master/Editor/MMDLoader/Private/ModelAgent.cs
new file mode 100644
index 000000000..cd721b429
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/Editor/MMDLoader/Private/ModelAgent.cs
@@ -0,0 +1,141 @@
+using UnityEngine;
+using UnityEditor;
+using System.Collections.Generic;
+
+namespace MMD {
+
+ public class ModelAgent {
+
+ ///
+ /// コンストラクタ
+ ///
+ /// 読み込むファイルパス
+ public ModelAgent(string file_path) {
+ if (string.IsNullOrEmpty(file_path)) {
+ throw new System.ArgumentException();
+ }
+ file_path_ = file_path;
+ header_ = null;
+ try {
+ //PMX読み込みを試みる
+ header_ = PMXLoaderScript.GetHeader(file_path_);
+ } catch (System.FormatException) {
+ //PMXとして読み込めなかったら
+ //PMDとして読み込む
+ PMD.PMDFormat.Header pmd_header = PMDLoaderScript.GetHeader(file_path_);
+ header_ = PMXLoaderScript.PMD2PMX(pmd_header);
+ }
+ }
+
+ ///
+ /// プレファブを作成する
+ ///
+ /// シェーダーの種類
+ /// 剛体を使用するか
+ /// アニメーションタイプ
+ /// IKを使用するか
+ /// スケール
+ /// PMX Baseでインポートするか
+ public void CreatePrefab(PMDConverter.ShaderType shader_type, bool use_rigidbody, PMXConverter.AnimationType animation_type, bool use_ik, float scale, bool is_pmx_base_import) {
+ GameObject game_object;
+ string prefab_path;
+ if (is_pmx_base_import) {
+ //PMX Baseでインポートする
+ //PMXファイルのインポート
+ PMX.PMXFormat pmx_format = null;
+ try {
+ //PMX読み込みを試みる
+ pmx_format = PMXLoaderScript.Import(file_path_);
+ } catch (System.FormatException) {
+ //PMXとして読み込めなかったら
+ //PMDとして読み込む
+ PMD.PMDFormat pmd_format = PMDLoaderScript.Import(file_path_);
+ pmx_format = PMXLoaderScript.PMD2PMX(pmd_format);
+ }
+ header_ = pmx_format.header;
+ //ゲームオブジェクトの作成
+ game_object = PMXConverter.CreateGameObject(pmx_format, use_rigidbody, animation_type, use_ik, scale);
+
+ // プレファブパスの設定
+ prefab_path = pmx_format.meta_header.folder + "/" + pmx_format.meta_header.name + ".prefab";
+ } else {
+ //PMXエクスポーターを使用しない
+ //PMDファイルのインポート
+ PMD.PMDFormat pmd_format = null;
+ try {
+ //PMX読み込みを試みる
+ PMX.PMXFormat pmx_format = PMXLoaderScript.Import(file_path_);
+ pmd_format = PMXLoaderScript.PMX2PMD(pmx_format);
+ } catch (System.FormatException) {
+ //PMXとして読み込めなかったら
+ //PMDとして読み込む
+ pmd_format = PMDLoaderScript.Import(file_path_);
+ }
+ header_ = PMXLoaderScript.PMD2PMX(pmd_format.head);
+
+ //ゲームオブジェクトの作成
+ bool use_mecanim = PMXConverter.AnimationType.LegacyAnimation == animation_type;
+ game_object = PMDConverter.CreateGameObject(pmd_format, shader_type, use_rigidbody, use_mecanim, use_ik, scale);
+
+ // プレファブパスの設定
+ prefab_path = pmd_format.folder + "/" + pmd_format.name + ".prefab";
+ }
+ // プレファブ化
+ PrefabUtility.CreatePrefab(prefab_path, game_object, ReplacePrefabOptions.ConnectToPrefab);
+
+ // アセットリストの更新
+ AssetDatabase.Refresh();
+ }
+
+ ///
+ /// モデル名取得
+ ///
+ /// モデル名
+ public string name {get{
+ string result = null;
+ if (null != header_) {
+ result = header_.model_name;
+ }
+ return result;
+ }}
+
+ ///
+ /// 英語表記モデル名取得
+ ///
+ /// 英語表記モデル名
+ public string english_name {get{
+ string result = null;
+ if (null != header_) {
+ result = header_.model_english_name;
+ }
+ return result;
+ }}
+
+ ///
+ /// モデル製作者からのコメント取得
+ ///
+ /// モデル製作者からのコメント
+ public string comment {get{
+ string result = null;
+ if (null != header_) {
+ result = header_.comment;
+ }
+ return result;
+ }}
+
+ ///
+ /// モデル製作者からの英語コメント取得
+ ///
+ /// モデル製作者からの英語コメント
+ public string english_comment {get{
+ string result = null;
+ if (null != header_) {
+ result = header_.english_comment;
+ }
+ return result;
+ }}
+
+ string file_path_;
+ PMX.PMXFormat.Header header_;
+ }
+}
\ No newline at end of file
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/Editor/MMDLoader/Private/MotionAgent.cs b/Assets/Scripts/3rd/mmd-for-unity-master/Editor/MMDLoader/Private/MotionAgent.cs
new file mode 100644
index 000000000..146488e44
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/Editor/MMDLoader/Private/MotionAgent.cs
@@ -0,0 +1,93 @@
+using UnityEngine;
+using UnityEditor;
+using System.Collections.Generic;
+using System.IO;
+
+namespace MMD {
+
+ public class MotionAgent {
+
+ ///
+ /// コンストラクタ
+ ///
+ /// 読み込むファイルパス
+ public MotionAgent(string file_path) {
+ if (string.IsNullOrEmpty(file_path)) {
+ throw new System.ArgumentException();
+ }
+ file_path_ = file_path;
+ header_ = VMDLoaderScript.GetHeader(file_path_); //VMD読み込み
+ format_ = null;
+ }
+
+ ///
+ /// アニメーションクリップを作成する
+ ///
+ /// 使用するPMDのGameObject
+ /// Prefab外に作成するか(true:Prefab外に作成, false:Prefab内蔵)
+ /// 補完曲線品質
+ public void CreateAnimationClip(GameObject assign_pmd, bool create_asset, int interpolationQuality) {
+ //VMDファイルのインポート
+ if (null == format_) {
+ //まだ読み込んでいないなら読むこむ
+ format_ = VMDLoaderScript.Import(file_path_); //VMD読み込み
+ header_ = format_.header;
+ }
+
+ //アニメーションクリップの作成
+ AnimationClip animation_clip = VMDConverter.CreateAnimationClip(format_, assign_pmd, interpolationQuality);
+ if (animation_clip == null)
+ {
+ throw new System.Exception("Cannot create AnimationClip");
+ }
+
+ // ここで登録
+ //anim.AddClip(animation_clip, animation_clip.name);
+
+ if (create_asset) {
+ // フォルダを生成してアニメーションのファイルを書き出す
+ string prefab_folder = AssetDatabase.GetAssetPath(assign_pmd);
+ prefab_folder = Path.GetDirectoryName(prefab_folder);
+
+ if (!Directory.Exists(prefab_folder + "/Animation"))
+ AssetDatabase.CreateFolder(prefab_folder, "Animation");
+
+ AssetDatabase.CreateAsset(animation_clip, prefab_folder + "/Animation/" + animation_clip.name + ".anim");
+ }
+ else
+ {
+ // こちらはPrefabの中に入れるタイプ
+ AssetDatabase.AddObjectToAsset(animation_clip, AssetDatabase.GetAssetPath(assign_pmd));
+ }
+
+ AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(animation_clip));
+ }
+
+ ///
+ /// アニメーション名取得
+ ///
+ /// アニメーション名
+ public string name {get{
+ string result = null;
+ if (null != format_) {
+ result = format_.name;
+ }
+ return result;
+ }}
+
+ ///
+ /// アニメーション名取得
+ ///
+ /// アニメーション名
+ public string model_name {get{
+ string result = null;
+ if (null != header_) {
+ result = header_.vmd_model_name;
+ }
+ return result;
+ }}
+ string file_path_;
+ VMD.VMDFormat.Header header_;
+ VMD.VMDFormat format_;
+ }
+}
\ No newline at end of file
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/Editor/MMDLoader/Private/PMDConverter.cs b/Assets/Scripts/3rd/mmd-for-unity-master/Editor/MMDLoader/Private/PMDConverter.cs
new file mode 100644
index 000000000..fb22bef9c
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/Editor/MMDLoader/Private/PMDConverter.cs
@@ -0,0 +1,1015 @@
+using UnityEngine;
+using UnityEditor;
+using System.Collections.Generic;
+using System.Linq;
+using MMD.PMD;
+
+namespace MMD
+{
+ public class PMDConverter
+ {
+ ///
+ /// シェーダの種類
+ ///
+ public enum ShaderType
+ {
+ Default, /// Unityのデフォルトシェーダ
+ HalfLambert, /// もやっとしたLambertっぽくなる
+ MMDShader /// MMDっぽいシェーダ
+ }
+
+ ///
+ /// GameObjectを作成する
+ ///
+ /// 内部形式データ
+ /// シェーダーの種類
+ /// 剛体を使用するか
+ /// Mecanimを使用するか
+ /// IKを使用するか
+ /// スケール
+ public static GameObject CreateGameObject(PMDFormat format, ShaderType shader_type, bool use_rigidbody, bool use_mecanim, bool use_ik, float scale) {
+ PMDConverter converter = new PMDConverter();
+ return converter.CreateGameObject_(format, shader_type, use_rigidbody, use_mecanim, use_ik, scale);
+ }
+
+ ///
+ /// デフォルトコンストラクタ
+ ///
+ ///
+ /// ユーザーに依るインスタンス作成を禁止する
+ ///
+ private PMDConverter() {}
+
+ private GameObject CreateGameObject_(PMDFormat format, ShaderType shader_type, bool use_rigidbody, bool use_mecanim, bool use_ik, float scale) {
+ format_ = format;
+ shader_type_ = shader_type;
+ use_rigidbody_ = use_rigidbody;
+ use_mecanim_ = use_mecanim;
+ use_ik_ = use_ik;
+ scale_ = scale;
+ root_game_object_ = new GameObject(format_.name);
+
+ Mesh mesh = CreateMesh(); // メッシュの生成・設定
+ Material[] materials = CreateMaterials(); // マテリアルの生成・設定
+ GameObject[] bones = CreateBones(); // ボーンの生成・設定
+
+ // バインドポーズの作成
+ BuildingBindpose(mesh, materials, bones);
+
+ MMDEngine engine = root_game_object_.AddComponent();
+ //スケール・エッジ幅
+ engine.scale = scale_;
+ engine.outline_width = default_outline_width;
+ engine.material_outline_widths = Enumerable.Repeat(1.0f, materials.Length).ToArray();
+
+ // IKの登録
+ if (use_ik_)
+ engine.ik_list = EntryIKSolver(bones);
+
+ // 剛体関連
+ if (use_rigidbody_)
+ {
+ try
+ {
+ var rigids = CreateRigids(bones);
+ AssignRigidbodyToBone(bones, rigids);
+ SetRigidsSettings(bones, rigids);
+ GameObject[] joints = SettingJointComponent(bones, rigids);
+ GlobalizeRigidbody(joints);
+
+ // 非衝突グループ
+ List[] ignoreGroups = SettingIgnoreRigidGroups(rigids);
+ int[] groupTarget = GetRigidbodyGroupTargets(rigids);
+
+ MMDEngine.Initialize(engine, groupTarget, ignoreGroups, rigids);
+ }
+ catch { }
+ }
+
+ // Mecanim設定
+ if (use_mecanim_) {
+ AvatarSettingScript avatar_setting = new AvatarSettingScript(root_game_object_, bones);
+ avatar_setting.SettingHumanAvatar();
+
+ string path = format_.folder + "/";
+ string name = GetFilePathString(format_.name);
+ string file_name = path + name + ".avatar.asset";
+ avatar_setting.CreateAsset(file_name);
+ } else {
+ root_game_object_.AddComponent(); // アニメーション追加
+ }
+
+ return root_game_object_;
+ }
+
+ Vector3[] EntryVertices()
+ {
+ int vcount = (int)format_.vertex_list.vert_count;
+ Vector3[] vpos = new Vector3[vcount];
+ for (int i = 0; i < vcount; i++)
+ vpos[i] = format_.vertex_list.vertex[i].pos * scale_;
+ return vpos;
+ }
+
+ Vector3[] EntryNormals()
+ {
+ int vcount = (int)format_.vertex_list.vert_count;
+ Vector3[] normals = new Vector3[vcount];
+ for (int i = 0; i < vcount; i++)
+ normals[i] = format_.vertex_list.vertex[i].normal_vec;
+ return normals;
+ }
+
+ Vector2[] EntryUVs()
+ {
+ int vcount = (int)format_.vertex_list.vert_count;
+ Vector2[] uvs = new Vector2[vcount];
+ for (int i = 0; i < vcount; i++)
+ uvs[i] = format_.vertex_list.vertex[i].uv;
+ return uvs;
+ }
+
+ BoneWeight[] EntryBoneWeights()
+ {
+ int vcount = (int)format_.vertex_list.vert_count;
+ BoneWeight[] weights = new BoneWeight[vcount];
+ for (int i = 0; i < vcount; i++)
+ {
+ weights[i].boneIndex0 = (int)format_.vertex_list.vertex[i].bone_num[0];
+ weights[i].boneIndex1 = (int)format_.vertex_list.vertex[i].bone_num[1];
+ weights[i].weight0 = (float)format_.vertex_list.vertex[i].bone_weight / 100.0f;
+ weights[i].weight1 = 1.0f - weights[i].weight0;
+ }
+ return weights;
+ }
+
+ // 頂点座標やUVなどの登録だけ
+ void EntryAttributesForMesh(Mesh mesh)
+ {
+ //mesh.vertexCount = (int)format_.vertex_list.vert_count;
+ mesh.vertices = EntryVertices();
+ mesh.normals = EntryNormals();
+ mesh.uv = EntryUVs();
+ mesh.boneWeights = EntryBoneWeights();
+ }
+
+ void SetSubMesh(Mesh mesh)
+ {
+ // マテリアル対サブメッシュ
+ // サブメッシュとはマテリアルに適用したい面頂点データのこと
+ // 面ごとに設定するマテリアルはここ
+ mesh.subMeshCount = (int)format_.material_list.material_count;
+
+ int sum = 0;
+ for (int i = 0; i < mesh.subMeshCount; i++)
+ {
+ int count = (int)format_.material_list.material[i].face_vert_count;
+ int[] indices = new int[count];
+
+ // 面頂点は材質0から順番に加算されている
+ for (int j = 0; j < count; j++)
+ indices[j] = format_.face_vertex_list.face_vert_index[j+sum];
+ mesh.SetTriangles(indices, i);
+ sum += (int)format_.material_list.material[i].face_vert_count;
+ }
+ }
+
+ // メッシュをProjectに登録
+ void CreateAssetForMesh(Mesh mesh)
+ {
+ AssetDatabase.CreateAsset(mesh, format_.folder + "/" + format_.name + ".asset");
+ }
+
+ Mesh CreateMesh()
+ {
+ Mesh mesh = new Mesh();
+ EntryAttributesForMesh(mesh);
+ SetSubMesh(mesh);
+ CreateAssetForMesh(mesh);
+ return mesh;
+ }
+
+ //透過マテリアル確認(true:透過, false:不透明)
+ bool IsTransparentMaterial(PMD.PMDFormat.Material model_material, Texture2D texture) {
+ bool result = false;
+ result = result || (model_material.alpha < 0.98f); //0.98f以上は不透明と見做す(0.98fに影生成情報を埋め込んでいる為)
+ if (null != texture) {
+ result = result || texture.alphaIsTransparency;
+ }
+ return result;
+ }
+
+ //エッジマテリアル確認(true:エッジ有り, false:無エッジ)
+ bool IsEdgeMaterial(PMD.PMDFormat.Material model_material) {
+ bool result;
+ if (0 == model_material.edge_flag) {
+ //エッジ無し
+ result = false;
+ } else {
+ //エッジ有りなら
+ result = true;
+ }
+ return result;
+ }
+
+ //背面カリングマテリアル確認(true:背面カリングする, false:背面カリングしない)
+ bool IsCullBackMaterial(PMD.PMDFormat.Material model_material) {
+ bool result;
+ if (1.0f <= model_material.alpha) {
+ //不透明なら
+ //背面カリングする
+ result = true;
+ } else if (0.99f <= model_material.alpha) {
+ //不透明の両面描画なら
+ //背面カリングしない
+ result = false;
+ } else {
+ //透過なら
+ //背面カリングしない
+ result = false;
+ }
+ return result;
+ }
+
+ //無影マテリアル確認(true:無影, false:影放ち)
+ bool IsNoCastShadowMaterial(PMD.PMDFormat.Material model_material) {
+ bool result;
+ if (0 == model_material.edge_flag) {
+ //エッジ無し
+ //無影
+ result = true;
+ } else {
+ //エッジ有りなら
+ //影放ち
+ result = false;
+ }
+ return result;
+ }
+
+ //影受け無しマテリアル確認(true:影受け無し, false:影受け)
+ bool IsNoReceiveShadowMaterial(PMD.PMDFormat.Material model_material) {
+ bool result;
+ if (0.98f == model_material.alpha) { //浮動小数点の比較だけど、0.98fとの同値確認でPMXエディタの0.98と一致したので一旦これで。
+ //影受け無し(不透明度が0.98fは特別扱いで影受け無し)なら
+ result = true;
+ } else {
+ //影受け有りなら
+ result = false;
+ }
+ return result;
+ }
+
+ string GetMMDShaderPath(PMD.PMDFormat.Material model_material, Texture2D texture) {
+ string result = "MMD/";
+ if (IsTransparentMaterial(model_material, texture)) {
+ result += "Transparent/";
+ }
+ result += "PMDMaterial";
+ if (IsEdgeMaterial(model_material)) {
+ result += "-with-Outline";
+ }
+ if (IsCullBackMaterial(model_material)) {
+ result += "-CullBack";
+ }
+ if (IsNoCastShadowMaterial(model_material)) {
+ result += "-NoCastShadow";
+ }
+#if MFU_ENABLE_NO_RECEIVE_SHADOW_SHADER //影受け無しのシェーダはまだ無いので無効化
+ if (IsNoReceiveShadowMaterial(model_material)) {
+ result += "-NoReceiveShadow";
+ }
+#endif //MFU_ENABLE_NO_RECEIVE_SHADOW_SHADER
+ return result;
+ }
+
+ // 色の生成
+ void EntryColors(Material[] mats)
+ {
+ // マテリアルの生成
+ for (int i = 0; i < mats.Length; i++)
+ {
+ // PMDフォーマットのマテリアルを取得
+ PMD.PMDFormat.Material pmdMat = format_.material_list.material[i];
+
+ //先にテクスチャ情報を検索
+ Texture2D main_texture = null;
+ if (pmdMat.texture_file_name != "") {
+ string path = format_.folder + "/" + pmdMat.texture_file_name;
+ main_texture = AssetDatabase.LoadAssetAtPath(path, typeof(Texture2D)) as Texture2D;
+ }
+
+ //マテリアルに設定
+ switch (shader_type_)
+ {
+ case ShaderType.Default: // デフォルト
+ mats[i] = new Material(Shader.Find("Transparent/Diffuse"));
+ mats[i].color = pmdMat.diffuse_color;
+ Color cbuf = mats[i].color;
+ cbuf.a = pmdMat.alpha; // これでいいのか?
+ mats[i].color = cbuf;
+ break;
+
+ case ShaderType.HalfLambert: // ハーフランバート
+ mats[i] = new Material(Shader.Find("Custom/CharModel"));
+ mats[i].SetFloat("_Cutoff", 1 - pmdMat.alpha);
+ mats[i].color = pmdMat.diffuse_color;
+ break;
+
+ case ShaderType.MMDShader:
+ mats[i] = new Material(Shader.Find(GetMMDShaderPath(pmdMat, main_texture)));
+
+ // シェーダに依って値が有ったり無かったりするが、設定してもエラーに為らない様なので全部設定
+ mats[i].SetColor("_Color", pmdMat.diffuse_color);
+ mats[i].SetColor("_AmbColor", pmdMat.mirror_color);
+ mats[i].SetFloat("_Opacity", pmdMat.alpha);
+ mats[i].SetColor("_SpecularColor", pmdMat.specular_color);
+ mats[i].SetFloat("_Shininess", pmdMat.specularity);
+ // エッジ
+ const float c_default_scale = 0.085f; //0.085fの時にMMDと一致する様にしているので、それ以外なら補正
+ mats[i].SetFloat("_OutlineWidth", default_outline_width * scale_ / c_default_scale);
+ mats[i].SetColor("_OutlineColor", default_outline_color);
+
+ // ここでスフィアマップ
+ string path = format_.folder + "/" + pmdMat.sphere_map_name;
+ Texture sphere_map;
+
+ if (System.IO.File.Exists(path))
+ { // ファイルの存在を確認
+ sphere_map = UnityEditor.AssetDatabase.LoadAssetAtPath(path, typeof(Texture)) as Texture;
+
+ // 乗算と加算判定
+ string ext = System.IO.Path.GetExtension(pmdMat.sphere_map_name);
+ switch (ext) {
+ case ".spa": // 加算
+ mats[i].SetTexture("_SphereAddTex", sphere_map);
+ mats[i].SetTextureScale("_SphereAddTex", new Vector2(1, -1));
+ break;
+ case ".sph": // 乗算
+ mats[i].SetTexture("_SphereMulTex", sphere_map);
+ mats[i].SetTextureScale("_SphereMulTex", new Vector2(1, -1));
+ break;
+ default:
+ // 加算扱い
+ goto case ".spa";
+ }
+ }
+
+ // トゥーンの位置を取得
+ string toon_name = pmdMat.toon_index != 0xFF ?
+ format_.toon_texture_list.toon_texture_file[pmdMat.toon_index] : "toon00.bmp";
+ string resource_path = UnityEditor.AssetDatabase.GetAssetPath(Shader.Find("MMD/HalfLambertOutline"));
+ resource_path = System.IO.Path.GetDirectoryName(resource_path); // resourceディレクトリを取得
+ resource_path += "/toon/" + toon_name;
+
+ // トゥーンが存在するか確認
+ if (!System.IO.File.Exists(resource_path))
+ {
+ // 自前トゥーンの可能性がある
+ resource_path = format_.folder + "/" + format_.toon_texture_list.toon_texture_file[pmdMat.toon_index];
+ if (!System.IO.File.Exists(resource_path))
+ {
+ Debug.LogError("Do not exists toon texture: " + format_.toon_texture_list.toon_texture_file[pmdMat.toon_index]);
+ break;
+ }
+ }
+
+ // テクスチャの割り当て
+ Texture toon_tex = UnityEditor.AssetDatabase.LoadAssetAtPath(resource_path, typeof(Texture)) as Texture;
+ mats[i].SetTexture("_ToonTex", toon_tex);
+ mats[i].SetTextureScale("_ToonTex", new Vector2(1, -1));
+ break;
+ }
+
+ // テクスチャが空でなければ登録
+ if (null != main_texture) {
+ mats[i].mainTexture = main_texture;
+ mats[i].mainTextureScale = new Vector2(1, -1);
+ }
+ }
+ }
+
+ // マテリアルに必要な色などを登録
+ Material[] EntryAttributesForMaterials()
+ {
+ int count = (int)format_.material_list.material_count;
+ Material[] mats = new Material[count];
+ EntryColors(mats);
+ return mats;
+ }
+
+ // マテリアルの登録
+ void CreateAssetForMaterials(Material[] mats)
+ {
+ // 適当なフォルダに投げる
+ string path = format_.folder + "/Materials/";
+ if (!System.IO.Directory.Exists(path)) {
+ AssetDatabase.CreateFolder(format_.folder, "Materials");
+ }
+
+ for (int i = 0; i < mats.Length; i++)
+ {
+ string fname = path + format_.name + "_material" + i + ".asset";
+ AssetDatabase.CreateAsset(mats[i], fname);
+ }
+ }
+
+ // マテリアルの生成
+ Material[] CreateMaterials()
+ {
+ Material[] materials;
+ materials = EntryAttributesForMaterials();
+ CreateAssetForMaterials(materials);
+ return materials;
+ }
+
+ // 親子関係の構築
+ void AttachParentsForBone(GameObject[] bones)
+ {
+ for (int i = 0; i < bones.Length; i++)
+ {
+ int index = format_.bone_list.bone[i].parent_bone_index;
+ if (index != 0xFFFF)
+ bones[i].transform.parent = bones[index].transform;
+ else
+ bones[i].transform.parent = root_game_object_.transform;
+ }
+ }
+
+ // ボーンの位置決めや親子関係の整備など
+ GameObject[] EntryAttributeForBones()
+ {
+ int count = format_.bone_list.bone_count;
+ GameObject[] bones = new GameObject[count];
+
+ for (int i = 0; i < count; i++) {
+ bones[i] = new GameObject(format_.bone_list.bone[i].bone_name);
+ bones[i].transform.name = bones[i].name;
+ bones[i].transform.position = format_.bone_list.bone[i].bone_head_pos * scale_;
+ }
+ return bones;
+ }
+
+ // ボーンの生成
+ GameObject[] CreateBones()
+ {
+ GameObject[] bones;
+ bones = EntryAttributeForBones();
+ AttachParentsForBone(bones);
+ CreateSkinBone(bones);
+ return bones;
+ }
+
+ // 表情ボーンの生成を行う
+ void CreateSkinBone(GameObject[] bones)
+ {
+ // 表情ルートを生成してルートの子供に付ける
+ GameObject skin_root = new GameObject("Expression");
+ if (skin_root.GetComponent() == null)
+ skin_root.AddComponent();
+ skin_root.transform.parent = root_game_object_.transform;
+
+ for (int i = 0; i < format_.skin_list.skin_count; i++)
+ {
+ // 表情を親ボーンに付ける
+ GameObject skin = new GameObject(format_.skin_list.skin_data[i].skin_name);
+ skin.transform.parent = skin_root.transform;
+ var script = skin.AddComponent();
+
+ // モーフの情報を入れる
+ AssignMorphVectorsForSkin(format_.skin_list.skin_data[i], format_.vertex_list, script);
+ }
+ }
+
+ // モーフ情報(頂点インデックス、モーフ先頂点など)を記録する
+ void AssignMorphVectorsForSkin(PMD.PMDFormat.SkinData data, PMD.PMDFormat.VertexList vtxs, MMDSkinsScript script)
+ {
+ uint count = data.skin_vert_count;
+ int[] indices = new int[count];
+ Vector3[] morph_target = new Vector3[count];
+
+ for (int i = 0; i < count; i++)
+ {
+ // ここで設定する
+ indices[i] = (int)data.skin_vert_data[i].skin_vert_index;
+
+ // モーフ先 - 元頂点
+ //morph_target[i] = (data.skin_vert_data[i].skin_vert_pos - vtxs.vertex[indices[i]].pos).normalized;
+ //morph_target[i] = data.skin_vert_data[i].skin_vert_pos - vtxs.vertex[indices[i]].pos;
+ morph_target[i] = data.skin_vert_data[i].skin_vert_pos * scale_;
+ }
+
+ // スクリプトに記憶させる
+ script.morphTarget = morph_target;
+ script.targetIndices = indices;
+
+ switch (data.skin_type)
+ {
+ case 0:
+ script.skinType = MMDSkinsScript.SkinType.Base;
+ script.gameObject.name = "base";
+ break;
+
+ case 1:
+ script.skinType = MMDSkinsScript.SkinType.EyeBrow;
+ break;
+
+ case 2:
+ script.skinType = MMDSkinsScript.SkinType.Eye;
+ break;
+
+ case 3:
+ script.skinType = MMDSkinsScript.SkinType.Lip;
+ break;
+
+ case 4:
+ script.skinType = MMDSkinsScript.SkinType.Other;
+ break;
+ }
+ }
+
+ // バインドポーズの作成
+ void BuildingBindpose(Mesh mesh, Material[] materials, GameObject[] bones)
+ {
+ // 行列とかトランスフォームとか
+ Matrix4x4[] bindpose = new Matrix4x4[bones.Length];
+ Transform[] trans = new Transform[bones.Length];
+ for (int i = 0; i < bones.Length; i++) {
+ trans[i] = bones[i].transform;
+ bindpose[i] = bones[i].transform.worldToLocalMatrix;
+ }
+
+ // ここで本格的な適用
+ SkinnedMeshRenderer smr = root_game_object_.AddComponent() as SkinnedMeshRenderer;
+ mesh.bindposes = bindpose;
+ smr.sharedMesh = mesh;
+ smr.bones = trans;
+ smr.materials = materials;
+ smr.receiveShadows = false; //影を受けない
+ ExpressionManagerScript ems = root_game_object_.GetComponentInChildren();
+ ems.mesh = mesh;
+ }
+
+ // IKの登録
+ // IKは基本的にスクリプトを利用
+ CCDIKSolver[] EntryIKSolver(GameObject[] bones)
+ {
+ PMD.PMDFormat.IKList ik_list = format_.ik_list;
+
+ CCDIKSolver[] iksolvers = new CCDIKSolver[ik_list.ik_data_count];
+ for (int i = 0; i < ik_list.ik_data_count; i++)
+ {
+ PMD.PMDFormat.IK ik = ik_list.ik_data[i];
+
+ bones[ik.ik_bone_index].AddComponent();
+ CCDIKSolver solver = bones[ik.ik_bone_index].GetComponent();
+ solver.target = bones[ik.ik_target_bone_index].transform;
+ solver.controll_weight = ik.control_weight * 4; // PMDファイルは4倍らしい
+ solver.iterations = ik.iterations;
+ solver.chains = new Transform[ik.ik_chain_length];
+ for (int j = 0; j < ik.ik_chain_length; j++)
+ solver.chains[j] = bones[ik.ik_child_bone_index[j]].transform;
+
+ if (!(bones[ik.ik_bone_index].name.Contains("足") || bones[ik.ik_bone_index].name.Contains("つま先")))
+ {
+ solver.enabled = false;
+ }
+ iksolvers[i] = solver;
+ }
+
+ return iksolvers;
+ }
+
+ // Sphere Colliderの設定
+ Collider EntrySphereCollider(PMDFormat.Rigidbody rigid, GameObject obj)
+ {
+ SphereCollider collider = obj.AddComponent();
+ collider.radius = rigid.shape_w * scale_;
+ return collider;
+ }
+
+ // Box Colliderの設定
+ Collider EntryBoxCollider(PMDFormat.Rigidbody rigid, GameObject obj)
+ {
+ BoxCollider collider = obj.AddComponent();
+ collider.size = new Vector3(
+ rigid.shape_w * 2f * scale_,
+ rigid.shape_h * 2f * scale_,
+ rigid.shape_d * 2f * scale_);
+ return collider;
+ }
+
+ // Capsule Colliderの設定
+ Collider EntryCapsuleCollider(PMDFormat.Rigidbody rigid, GameObject obj)
+ {
+ CapsuleCollider collider = obj.AddComponent();
+ collider.radius = rigid.shape_w * scale_;
+ collider.height = (rigid.shape_h + rigid.shape_w * 2) * scale_;
+ return collider;
+ }
+
+ // 物理素材の定義
+ PhysicsMaterial CreatePhysicMaterial(PMDFormat.Rigidbody rigid)
+ {
+ PhysicsMaterial material = new PhysicsMaterial(format_.name + "_r" + rigid.rigidbody_name);
+ material.bounciness = rigid.rigidbody_recoil;
+ material.staticFriction = rigid.rigidbody_friction;
+ material.dynamicFriction = rigid.rigidbody_friction;
+
+ AssetDatabase.CreateAsset(material, format_.folder + "/Physics/" + GetFilePathString(material.name) + ".asset");
+ return material;
+ }
+
+ // Unity側のRigidbodyの設定を行う
+ void UnityRigidbodySetting(PMDFormat.Rigidbody rigidbody, GameObject targetBone, bool setted=false)
+ {
+ // rigidbodyの調整
+ if (!setted)
+ {
+ targetBone.GetComponent().isKinematic = (0 == rigidbody.rigidbody_type);
+ targetBone.GetComponent().mass = Mathf.Max(float.Epsilon, rigidbody.rigidbody_weight);
+ targetBone.GetComponent().linearDamping = rigidbody.rigidbody_pos_dim;
+ targetBone.GetComponent().angularDamping = rigidbody.rigidbody_rot_dim;
+ }
+ else
+ {
+ // Rigidbodyはボーンに対して適用されるので複数ある場合は平均を取る
+ targetBone.GetComponent().mass += rigidbody.rigidbody_weight;
+ targetBone.GetComponent().linearDamping += rigidbody.rigidbody_pos_dim;
+ targetBone.GetComponent().angularDamping += rigidbody.rigidbody_rot_dim;
+ targetBone.GetComponent().mass *= 0.5f;
+ targetBone.GetComponent().linearDamping *= 0.5f;
+ targetBone.GetComponent().angularDamping *= 0.5f;
+ }
+ }
+
+ // 剛体の値を代入する
+ void SetRigidsSettings(GameObject[] bones, GameObject[] rigid)
+ {
+ PMDFormat.RigidbodyList list = format_.rigidbody_list;
+ for (int i = 0; i < list.rigidbody_count; i++) // iは剛体番号
+ {
+ // 剛体の関連ボーンのインデックス
+ int rigidRefIndex = list.rigidbody[i].rigidbody_rel_bone_index;
+
+ // ローカル座標の確定
+ Vector3 localPos = list.rigidbody[i].pos_pos * scale_;// - rigid[i].transform.position;
+
+ // ここで位置の決定
+ if (rigidRefIndex >= ushort.MaxValue)
+ {
+ // 関連ボーン無し
+ if (rigid[i].GetComponent() == null)
+ rigid[i].AddComponent();
+ UnityRigidbodySetting(list.rigidbody[i], rigid[i]);
+ rigid[i].transform.localPosition = localPos;
+
+ // 関連ボーンなしの剛体はセンターボーンに接続している
+ rigid[i].transform.position = localPos + format_.bone_list.bone[0].bone_head_pos * scale_;
+ // 回転の値を決める
+ Vector3 rot = list.rigidbody[i].pos_rot * Mathf.Rad2Deg;
+ rigid[i].transform.rotation = Quaternion.Euler(rot);
+ }
+ else
+ // 関連ボーン有り
+ { // とりあえずここで剛体を追加・設定
+ if (bones[rigidRefIndex].GetComponent() == null)
+ bones[rigidRefIndex].AddComponent();
+ UnityRigidbodySetting(list.rigidbody[i], bones[rigidRefIndex]);
+ rigid[i].transform.localPosition = localPos;
+ // 回転の値を決める
+ Vector3 rot = list.rigidbody[i].pos_rot * Mathf.Rad2Deg;
+ rigid[i].transform.rotation = Quaternion.Euler(rot);
+ }
+
+ }
+ }
+
+ // 剛体の生成
+ GameObject[] CreateRigids(GameObject[] bones)
+ {
+ PMDFormat.RigidbodyList list = format_.rigidbody_list;
+ if (!System.IO.Directory.Exists(System.IO.Path.Combine(format_.folder, "Physics")))
+ {
+ AssetDatabase.CreateFolder(format_.folder, "Physics");
+ }
+
+ // 剛体の登録
+ GameObject[] rigid = new GameObject[list.rigidbody_count];
+ for (int i = 0; i < list.rigidbody_count; i++)
+ {
+ rigid[i] = new GameObject("r_" + list.rigidbody[i].rigidbody_name);
+ //rigid[i].AddComponent(); // 剛体本体にはrigidbodyは適用しない
+
+ // 各種Colliderの設定
+ Collider collider = null;
+ switch (list.rigidbody[i].shape_type)
+ {
+ case 0:
+ collider = EntrySphereCollider(list.rigidbody[i], rigid[i]);
+ break;
+
+ case 1:
+ collider = EntryBoxCollider(list.rigidbody[i], rigid[i]);
+ break;
+
+ case 2:
+ collider = EntryCapsuleCollider(list.rigidbody[i], rigid[i]);
+ break;
+ }
+
+ // マテリアルの設定
+ collider.material = CreatePhysicMaterial(list.rigidbody[i]);
+ }
+ return rigid;
+ }
+
+ // ジョインに依って接続している(されている)剛体番号を検索する
+ int SearchConnectRigidByJoint(int rigidIndex)
+ {
+ for (int i = 0; i < format_.rigidbody_joint_list.joint_count; i++)
+ {
+ int joint_rigidbody_a = (int)format_.rigidbody_joint_list.joint[i].joint_rigidbody_a;
+ int joint_rigidbody_b = (int)format_.rigidbody_joint_list.joint[i].joint_rigidbody_b;
+ if (joint_rigidbody_b == rigidIndex)
+ {
+ return joint_rigidbody_a;
+ }
+ else if (joint_rigidbody_a == rigidIndex)
+ {
+ return joint_rigidbody_b;
+ }
+ }
+ // 接続剛体は発見出来ず
+ return -1;
+ }
+
+ // 関連ボーンなしの剛体から親のボーンを探してくる
+ // rigidIndexは剛体番号
+ int GetTargetRigidBone(int rigidIndex)
+ {
+ // 接続剛体Aを探す
+ int targetRigid = SearchConnectRigidByJoint(rigidIndex);
+
+ // 接続剛体Aの関連ボーンを探す
+ int ind = format_.rigidbody_list.rigidbody[targetRigid].rigidbody_rel_bone_index;
+
+ // MaxValueを引けば接続剛体Aの関連ボーンに接続されるようになっている
+ if (ind >= ushort.MaxValue)
+ format_.rigidbody_list.rigidbody[rigidIndex].rigidbody_rel_bone_index = ushort.MaxValue + (ushort)ind;
+
+ return (int)ind;
+ }
+
+ // 剛体ボーンを
+ void AssignRigidbodyToBone(GameObject[] bones, GameObject[] rigids)
+ {
+ // 剛体の数だけ回す
+ for (int i = 0; i < rigids.Length; i++)
+ {
+ // 剛体を親ボーンに格納
+ int refIndex = format_.rigidbody_list.rigidbody[i].rigidbody_rel_bone_index;
+ if (refIndex != ushort.MaxValue)
+ { // 65535が最大値
+ rigids[i].transform.parent = bones[refIndex].transform;
+ }
+ else
+ {
+ // ジョイントから接続剛体B=現在の剛体名で探し出す
+ int boneIndex = GetTargetRigidBone(i);
+
+ // 接続剛体Aの関連ボーンに剛体を接続
+ rigids[i].transform.parent = bones[boneIndex].transform;
+ }
+ }
+ }
+
+ // 移動や回転制限
+ void SetMotionAngularLock(PMDFormat.Joint joint, ConfigurableJoint conf)
+ {
+ SoftJointLimit jlim;
+
+ // Motionの固定
+ if (joint.constrain_pos_1.x == 0f && joint.constrain_pos_2.x == 0f)
+ conf.xMotion = ConfigurableJointMotion.Locked;
+ else
+ conf.xMotion = ConfigurableJointMotion.Limited;
+
+ if (joint.constrain_pos_1.y == 0f && joint.constrain_pos_2.y == 0f)
+ conf.yMotion = ConfigurableJointMotion.Locked;
+ else
+ conf.yMotion = ConfigurableJointMotion.Limited;
+
+ if (joint.constrain_pos_1.z == 0f && joint.constrain_pos_2.z == 0f)
+ conf.zMotion = ConfigurableJointMotion.Locked;
+ else
+ conf.zMotion = ConfigurableJointMotion.Limited;
+
+ // 角度の固定
+ if (joint.constrain_rot_1.x == 0f && joint.constrain_rot_2.x == 0f)
+ conf.angularXMotion = ConfigurableJointMotion.Locked;
+ else
+ {
+ conf.angularXMotion = ConfigurableJointMotion.Limited;
+ float hlim = Mathf.Max(-joint.constrain_rot_1.x, -joint.constrain_rot_2.x); //回転方向が逆なので負数
+ float llim = Mathf.Min(-joint.constrain_rot_1.x, -joint.constrain_rot_2.x);
+ SoftJointLimit jhlim = new SoftJointLimit();
+ jhlim.limit = Mathf.Clamp(hlim * Mathf.Rad2Deg, -180.0f, 180.0f);
+ conf.highAngularXLimit = jhlim;
+
+ SoftJointLimit jllim = new SoftJointLimit();
+ jllim.limit = Mathf.Clamp(llim * Mathf.Rad2Deg, -180.0f, 180.0f);
+ conf.lowAngularXLimit = jllim;
+ }
+
+ if (joint.constrain_rot_1.y == 0f && joint.constrain_rot_2.y == 0f)
+ conf.angularYMotion = ConfigurableJointMotion.Locked;
+ else
+ {
+ // 値がマイナスだとエラーが出るので注意
+ conf.angularYMotion = ConfigurableJointMotion.Limited;
+ float lim = Mathf.Min(Mathf.Abs(joint.constrain_rot_1.y), Mathf.Abs(joint.constrain_rot_2.y));//絶対値の小さい方
+ jlim = new SoftJointLimit();
+ jlim.limit = lim * Mathf.Clamp(Mathf.Rad2Deg, 0.0f, 180.0f);
+ conf.angularYLimit = jlim;
+ }
+
+ if (joint.constrain_rot_1.z == 0f && joint.constrain_rot_2.z == 0f)
+ conf.angularZMotion = ConfigurableJointMotion.Locked;
+ else
+ {
+ conf.angularZMotion = ConfigurableJointMotion.Limited;
+ float lim = Mathf.Min(Mathf.Abs(-joint.constrain_rot_1.z), Mathf.Abs(-joint.constrain_rot_2.z));//絶対値の小さい方//回転方向が逆なので負数
+ jlim = new SoftJointLimit();
+ jlim.limit = Mathf.Clamp(lim * Mathf.Rad2Deg, 0.0f, 180.0f);
+ conf.angularZLimit = jlim;
+ }
+ }
+
+ // ばねの設定など
+ void SetDrive(PMDFormat.Joint joint, ConfigurableJoint conf)
+ {
+ JointDrive drive;
+
+ // Position
+ if (joint.spring_pos.x != 0f)
+ {
+ drive = new JointDrive();
+ drive.positionSpring = joint.spring_pos.x * scale_;
+ conf.xDrive = drive;
+ }
+ if (joint.spring_pos.y != 0f)
+ {
+ drive = new JointDrive();
+ drive.positionSpring = joint.spring_pos.y * scale_;
+ conf.yDrive = drive;
+ }
+ if (joint.spring_pos.z != 0f)
+ {
+ drive = new JointDrive();
+ drive.positionSpring = joint.spring_pos.z * scale_;
+ conf.zDrive = drive;
+ }
+
+ // Angular
+ if (joint.spring_rot.x != 0f)
+ {
+ drive = new JointDrive();
+ drive.positionSpring = joint.spring_rot.x;
+ conf.angularXDrive = drive;
+ }
+ if (joint.spring_rot.y != 0f || joint.spring_rot.z != 0f)
+ {
+ drive = new JointDrive();
+ drive.positionSpring = (joint.spring_rot.y + joint.spring_rot.z) * 0.5f;
+ conf.angularYZDrive = drive;
+ }
+ }
+
+ // ConfigurableJointの値を設定する
+ void SetAttributeConfigurableJoint(PMDFormat.Joint joint, ConfigurableJoint conf)
+ {
+ SetMotionAngularLock(joint, conf);
+ SetDrive(joint, conf);
+ }
+
+ // ConfigurableJointの設定
+ // 先に設定してからFixedJointを設定する
+ GameObject[] SetupConfigurableJoint(GameObject[] rigids)
+ {
+ List result_list = new List();
+ foreach (PMDFormat.Joint joint in format_.rigidbody_joint_list.joint) {
+ //相互接続する剛体の取得
+ Transform transform_a = rigids[joint.joint_rigidbody_a].transform;
+ Transform transform_b = rigids[joint.joint_rigidbody_b].transform;
+ Rigidbody rigidbody_a = transform_a.GetComponent();
+ if (null == rigidbody_a) {
+ rigidbody_a = transform_a.parent.GetComponent();
+ }
+ Rigidbody rigidbody_b = transform_b.GetComponent();
+ if (null == rigidbody_b) {
+ rigidbody_b = transform_b.parent.GetComponent();
+ }
+ if (rigidbody_a != rigidbody_b) {
+ //接続する剛体が同じ剛体を指さないなら
+ //(本来ならPMDの設定が間違っていない限り同一を指す事は無いが、MFUでは関連ボーンを持たない剛体はセンターボーンに纏められる為に依り起こり得る)
+ //ジョイント設定
+ ConfigurableJoint config_joint = rigidbody_b.gameObject.AddComponent();
+ config_joint.connectedBody = rigidbody_a;
+ SetAttributeConfigurableJoint(joint, config_joint);
+
+ result_list.Add(config_joint.gameObject);
+ }
+ }
+ return result_list.ToArray();
+ }
+
+ // ジョイントの設定
+ // ジョイントはボーンに対して適用される
+ GameObject[] SettingJointComponent(GameObject[] bones, GameObject[] rigids)
+ {
+ // ConfigurableJointの設定
+ GameObject[] joints = SetupConfigurableJoint(rigids);
+ return joints;
+ }
+
+ // 剛体のグローバル座標化
+ void GlobalizeRigidbody(GameObject[] joints)
+ {
+ if ((null != joints) && (0 < joints.Length)) {
+ // 物理演算ルートを生成してルートの子供に付ける
+ GameObject physics_root = new GameObject("Physics");
+ PhysicsManager physics_manager = physics_root.AddComponent();
+ physics_root.transform.parent = root_game_object_.transform;
+ Transform physics_root_transform = physics_root.transform;
+
+ // PhysicsManagerに移動前の状態を覚えさせる(幾つか重複しているので重複は削除)
+ physics_manager.connect_bone_list = joints.Select(x=>x.gameObject)
+ .Distinct()
+ .Select(x=>new PhysicsManager.ConnectBone(x, x.transform.parent.gameObject))
+ .ToArray();
+
+ //isKinematicで無くConfigurableJointを持つ場合はグローバル座標化
+ foreach (ConfigurableJoint joint in joints.Where(x=>!x.GetComponent().isKinematic)
+ .Select(x=>x.GetComponent())) {
+ joint.transform.parent = physics_root_transform;
+ }
+ }
+ }
+
+ // 非衝突剛体の設定
+ List[] SettingIgnoreRigidGroups(GameObject[] rigids)
+ {
+ // 非衝突グループ用リストの初期化
+ const int MaxGroup = 16; // グループの最大数
+ List[] ignoreRigid = new List[MaxGroup];
+ for (int i = 0; i < 16; i++) ignoreRigid[i] = new List();
+
+ // それぞれの剛体が所属している非衝突グループを追加していく
+ PMDFormat.RigidbodyList list = format_.rigidbody_list;
+ for (int i = 0; i < list.rigidbody_count; i++)
+ ignoreRigid[list.rigidbody[i].rigidbody_group_index].Add(i);
+ return ignoreRigid;
+ }
+
+ // グループターゲット
+ int[] GetRigidbodyGroupTargets(GameObject[] rigids)
+ {
+ int[] result = new int[rigids.Length];
+ for (int i = 0; i < rigids.Length; i++)
+ {
+ result[i] = format_.rigidbody_list.rigidbody[i].rigidbody_group_target;
+ }
+ return result;
+ }
+
+ ///
+ /// ファイルパス文字列の取得
+ ///
+ /// ファイルパスに使用可能な文字列
+ /// ファイルパスに使用したい文字列
+ private static string GetFilePathString(string src) {
+ return src.Replace('\\', '\')
+ .Replace('/', '/')
+ .Replace(':', ':')
+ .Replace('*', '*')
+ .Replace('?', '?')
+ .Replace('"', '”')
+ .Replace('<', '<')
+ .Replace('>', '>')
+ .Replace('|', '|')
+ .Replace("\n", string.Empty)
+ .Replace("\r", string.Empty);
+ }
+
+ static float default_outline_width = 0.2f; //標準エッジ幅
+ static Color default_outline_color = Color.black; //標準エッジ色
+
+ GameObject root_game_object_;
+ PMDFormat format_;
+ ShaderType shader_type_;
+ bool use_rigidbody_;
+ bool use_mecanim_;
+ bool use_ik_;
+ float scale_;
+ }
+}
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/Editor/MMDLoader/Private/PMDLoaderScript.cs b/Assets/Scripts/3rd/mmd-for-unity-master/Editor/MMDLoader/Private/PMDLoaderScript.cs
new file mode 100644
index 000000000..407ca260e
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/Editor/MMDLoader/Private/PMDLoaderScript.cs
@@ -0,0 +1,499 @@
+using UnityEngine;
+using UnityEditor;
+using System.Collections;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+using MMD.PMD;
+
+public class PMDLoaderScript {
+
+ ///
+ /// PMDファイルのヘッダー取得
+ ///
+ /// PMDファイルのパス
+ /// ヘッダー
+ public static PMDFormat.Header GetHeader(string file_path) {
+ PMDLoaderScript loader = new PMDLoaderScript();
+ return loader.GetHeader_(file_path);
+ }
+
+ ///
+ /// PMDファイルのインポート
+ ///
+ /// PMDファイルのパス
+ /// 内部形式データ
+ public static PMDFormat Import(string file_path) {
+ PMDLoaderScript loader = new PMDLoaderScript();
+ return loader.Import_(file_path);
+ }
+
+ ///
+ /// デフォルトコンストラクタ
+ ///
+ ///
+ /// ユーザーに依るインスタンス作成を禁止する
+ ///
+ private PMDLoaderScript() {}
+
+ private PMDFormat.Header GetHeader_(string file_path) {
+ PMDFormat.Header result;
+ using (FileStream stream = new FileStream(file_path, FileMode.Open, FileAccess.Read))
+ using (BinaryReader bin = new BinaryReader(stream)) {
+ file_path_ = null;
+ binary_reader_ = bin;
+ result = ReadHeader();
+ }
+ return result;
+ }
+
+ private PMDFormat Import_(string file_path) {
+ using (FileStream stream = new FileStream(file_path, FileMode.Open, FileAccess.Read))
+ using (BinaryReader bin = new BinaryReader(stream)) {
+ file_path_ = file_path;
+ binary_reader_ = bin;
+ Read();
+ }
+ return format_;
+ }
+
+ private PMDFormat Read() {
+ format_ = new PMDFormat();
+ EntryPathes();
+
+ try {
+ format_.head = ReadHeader();
+ format_.vertex_list = ReadVertexList();
+ format_.face_vertex_list = ReadFaceVertexList();
+ format_.material_list = ReadMaterialList();
+ format_.bone_list = ReadBoneList();
+ format_.ik_list = ReadIKList();
+ format_.skin_list = ReadSkinList();
+ format_.skin_name_list = ReadSkinNameList();
+ format_.bone_name_list = ReadBoneNameList();
+ format_.bone_display_list = ReadBoneDisplayList();
+ format_.eg_head = ReadEnglishHeader();
+ if (format_.eg_head.english_name_compatibility != 0) {
+ format_.eg_bone_name_list = ReadEnglishBoneNameList(format_.bone_list.bone_count);
+ format_.eg_skin_name_list = ReadEnglishSkinNameList(format_.skin_list.skin_count);
+ format_.eg_bone_display_list = ReadEnglishBoneDisplayList(format_.bone_name_list.bone_disp_name_count);
+ }
+ format_.toon_texture_list = ReadToonTextureList();
+ format_.rigidbody_list = ReadRigidbodyList();
+ format_.rigidbody_joint_list = ReadRigidbodyJointList();
+ } catch {
+ Debug.Log("Don't read full format");
+ }
+ return format_;
+ }
+
+ private void EntryPathes() {
+ format_.path = file_path_;
+ format_.name = Path.GetFileNameWithoutExtension(file_path_); // .pmdを抜かす
+ format_.folder = Path.GetDirectoryName(file_path_); // PMDが格納されているフォルダ
+ }
+
+ private PMDFormat.Header ReadHeader() {
+ PMDFormat.Header result = new PMDFormat.Header();
+ result.magic = binary_reader_.ReadBytes(3);
+ result.version = binary_reader_.ReadSingle();
+ result.model_name = ConvertByteToString(binary_reader_.ReadBytes(20), "");
+ result.comment = ConvertByteToString(binary_reader_.ReadBytes(256), System.Environment.NewLine);
+ return result;
+ }
+
+ private PMDFormat.VertexList ReadVertexList() {
+ PMDFormat.VertexList result = new PMDFormat.VertexList();
+ result.vert_count = binary_reader_.ReadUInt32();
+ result.vertex = new PMDFormat.Vertex[result.vert_count];
+ for (int i = 0; i < result.vert_count; i++) {
+ result.vertex[i] = ReadVertex();
+ }
+ return result;
+ }
+
+ private PMDFormat.Vertex ReadVertex() {
+ PMDFormat.Vertex result = new PMDFormat.Vertex();
+ result.pos = ReadSinglesToVector3(binary_reader_);
+ result.normal_vec = ReadSinglesToVector3(binary_reader_);
+ result.uv = ReadSinglesToVector2(binary_reader_);
+ result.bone_num = ReadUInt16s(binary_reader_, 2);
+ result.bone_weight = binary_reader_.ReadByte();
+ result.edge_flag = binary_reader_.ReadByte();
+ return result;
+ }
+
+ private PMDFormat.FaceVertexList ReadFaceVertexList() {
+ PMDFormat.FaceVertexList result = new PMDFormat.FaceVertexList();
+ result.face_vert_count = binary_reader_.ReadUInt32();
+ result.face_vert_index = ReadUInt16s(binary_reader_, result.face_vert_count);
+ return result;
+ }
+
+ private PMDFormat.MaterialList ReadMaterialList() {
+ PMDFormat.MaterialList result = new PMDFormat.MaterialList();
+ result.material_count = binary_reader_.ReadUInt32();
+ result.material = new PMDFormat.Material[result.material_count];
+ for (int i = 0; i < result.material_count; i++) {
+ result.material[i] = ReadMaterial();
+ }
+ return result;
+ }
+
+ private PMDFormat.Material ReadMaterial() {
+ PMDFormat.Material result = new PMDFormat.Material();
+ result.diffuse_color = ReadSinglesToColor(binary_reader_, 1);
+ result.alpha = binary_reader_.ReadSingle();
+ result.specularity = binary_reader_.ReadSingle();
+ result.specular_color = ReadSinglesToColor(binary_reader_, 1);
+ result.mirror_color = ReadSinglesToColor(binary_reader_, 1);
+ result.toon_index = binary_reader_.ReadByte();
+ result.edge_flag = binary_reader_.ReadByte();
+ result.face_vert_count = binary_reader_.ReadUInt32();
+
+ // テクスチャ名の抜き出し
+ // スフィアマップも行う
+ string buf = ConvertByteToString(binary_reader_.ReadBytes(20), "");
+
+ //Debug by Wilfrem: テクスチャが無い場合を考慮していない
+ //Debug by Wilfrem: テクスチャはfoo.bmp*bar.sphのパターンだけなのか? bar.sph*foo.bmpのパターンがあり得るのでは? 対策をしておくべき
+ //Debug by GRGSIBERIA: スフィアマップとテクスチャが逆になる現象が発生したので修正
+ //Debug by GRGSIBERIA: "./テクスチャ名"で始まるモデルで異常発生したので修正
+ if (!string.IsNullOrEmpty(buf.Trim())) {
+ string[] textures = buf.Trim().Split('*');
+ foreach (var tex in textures) {
+ string texNameEndAssignVar = "";
+ string ext = Path.GetExtension(tex);
+ if (ext == ".sph" || ext == ".spa") {
+ result.sphere_map_name = tex;
+ /*} else if (string.IsNullOrEmpty(tex)) {
+ result.texture_file_name=""; */
+ } else {
+ if (tex.Split('/')[0] == ".") {
+ // テクスチャ名の後端に"./"があった場合の回避処理
+ string[] texNameBuf = tex.Split('/');
+ for (int i = 1; i < texNameBuf.Length-1; i++) {
+ texNameEndAssignVar += texNameBuf[i] + "/";
+ }
+ texNameEndAssignVar += texNameBuf[texNameBuf.Length-1];
+ } else {
+ // 特に異常がない場合はそのまま代入
+ texNameEndAssignVar = tex;
+ }
+#if UNITY_STANDALONE_OSX
+ // MACの場合,濁点のあるひらがなを使うと動かないらしいので対策
+ // http://sourceforge.jp/ticket/browse.php?group_id=6158&tid=31929
+ texNameEndAssignVar = texNameEndAssignVar.Normalize(NormalizationForm.FormKD);
+#endif
+ result.texture_file_name = texNameEndAssignVar;
+ }
+ }
+ } else {
+ result.sphere_map_name="";
+ result.texture_file_name="";
+ }
+ if (string.IsNullOrEmpty(result.texture_file_name)) {
+ result.texture_file_name = "";
+ }
+ return result;
+ }
+
+ private PMDFormat.BoneList ReadBoneList() {
+ PMDFormat.BoneList result = new PMDFormat.BoneList();
+ result.bone_count = binary_reader_.ReadUInt16();
+ //Debug.Log("BoneCount:"+bone_count);
+ result.bone = new PMDFormat.Bone[result.bone_count];
+ for (int i = 0; i < result.bone_count; i++) {
+ result.bone[i] = ReadBone();
+ }
+ return result;
+ }
+
+ private PMDFormat.Bone ReadBone() {
+ PMDFormat.Bone result = new PMDFormat.Bone();
+ result.bone_name = ConvertByteToString(binary_reader_.ReadBytes(20), "");
+ result.parent_bone_index = binary_reader_.ReadUInt16();
+ result.tail_pos_bone_index = binary_reader_.ReadUInt16();
+ result.bone_type = binary_reader_.ReadByte();
+ result.ik_parent_bone_index = binary_reader_.ReadUInt16();
+ result.bone_head_pos = ReadSinglesToVector3(binary_reader_);
+ return result;
+ }
+
+ private PMDFormat.IKList ReadIKList() {
+ PMDFormat.IKList result = new PMDFormat.IKList();
+ result.ik_data_count = binary_reader_.ReadUInt16();
+ //Debug.Log("IKDataCount:"+ik_data_count);
+ result.ik_data = new PMDFormat.IK[result.ik_data_count];
+ for (int i = 0; i < result.ik_data_count; i++) {
+ result.ik_data[i] = ReadIK();
+ }
+ return result;
+ }
+
+ private PMDFormat.IK ReadIK() {
+ PMDFormat.IK result = new PMDFormat.IK();
+ result.ik_bone_index = binary_reader_.ReadUInt16();
+ result.ik_target_bone_index = binary_reader_.ReadUInt16();
+ result.ik_chain_length = binary_reader_.ReadByte();
+ result.iterations = binary_reader_.ReadUInt16();
+ result.control_weight = binary_reader_.ReadSingle();
+ result.ik_child_bone_index = ReadUInt16s(binary_reader_, result.ik_chain_length);
+ return result;
+ }
+
+ private PMDFormat.SkinList ReadSkinList() {
+ PMDFormat.SkinList result = new PMDFormat.SkinList();
+ result.skin_count = binary_reader_.ReadUInt16();
+ //Debug.Log("SkinCount:"+skin_count);
+ result.skin_data = new PMDFormat.SkinData[result.skin_count];
+ for (int i = 0; i < result.skin_count; i++) {
+ result.skin_data[i] = ReadSkinData();
+ }
+ return result;
+ }
+
+ private PMDFormat.SkinData ReadSkinData() {
+ PMDFormat.SkinData result = new PMDFormat.SkinData();
+ result.skin_name = ConvertByteToString(binary_reader_.ReadBytes(20), "");
+ result.skin_vert_count = binary_reader_.ReadUInt32();
+ result.skin_type = binary_reader_.ReadByte();
+ result.skin_vert_data = new PMDFormat.SkinVertexData[result.skin_vert_count];
+ for (int i = 0; i < result.skin_vert_count; i++) {
+ result.skin_vert_data[i] = ReadSkinVertexData();
+ }
+ return result;
+ }
+
+ private PMDFormat.SkinVertexData ReadSkinVertexData() {
+ PMDFormat.SkinVertexData result = new PMDFormat.SkinVertexData();
+ result.skin_vert_index = binary_reader_.ReadUInt32();
+ result.skin_vert_pos = ReadSinglesToVector3(binary_reader_);
+ return result;
+ }
+
+
+ private PMDFormat.SkinNameList ReadSkinNameList() {
+ PMDFormat.SkinNameList result = new PMDFormat.SkinNameList();
+ result.skin_disp_count = binary_reader_.ReadByte();
+ result.skin_index = ReadUInt16s(binary_reader_, result.skin_disp_count);
+ return result;
+ }
+
+ private PMDFormat.BoneNameList ReadBoneNameList() {
+ PMDFormat.BoneNameList result = new PMDFormat.BoneNameList();
+ result.bone_disp_name_count = binary_reader_.ReadByte();
+ result.disp_name = new string[result.bone_disp_name_count];
+ for (int i = 0; i < result.bone_disp_name_count; i++) {
+ result.disp_name[i] = ConvertByteToString(binary_reader_.ReadBytes(50), "");
+ }
+ return result;
+ }
+
+ private PMDFormat.BoneDisplayList ReadBoneDisplayList() {
+ PMDFormat.BoneDisplayList result = new PMDFormat.BoneDisplayList();
+ result.bone_disp_count = binary_reader_.ReadUInt32();
+ result.bone_disp = new PMDFormat.BoneDisplay[result.bone_disp_count];
+ for (int i = 0; i < result.bone_disp_count; i++) {
+ result.bone_disp[i] = ReadBoneDisplay();
+ }
+ return result;
+ }
+
+ private PMDFormat.BoneDisplay ReadBoneDisplay() {
+ PMDFormat.BoneDisplay result = new PMDFormat.BoneDisplay();
+ result.bone_index = binary_reader_.ReadUInt16();
+ result.bone_disp_frame_index = binary_reader_.ReadByte();
+ return result;
+ }
+
+ private PMDFormat.EnglishHeader ReadEnglishHeader() {
+ PMDFormat.EnglishHeader result = new PMDFormat.EnglishHeader();
+ result.english_name_compatibility = binary_reader_.ReadByte();
+
+ if (result.english_name_compatibility != 0) {
+ // 英語名対応あり
+ result.model_name_eg = ConvertByteToString(binary_reader_.ReadBytes(20), "");
+ result.comment_eg = ConvertByteToString(binary_reader_.ReadBytes(256), System.Environment.NewLine);
+ }
+ return result;
+ }
+
+ private PMDFormat.EnglishBoneNameList ReadEnglishBoneNameList(int boneCount) {
+ PMDFormat.EnglishBoneNameList result = new PMDFormat.EnglishBoneNameList();
+ result.bone_name_eg = new string[boneCount];
+ for (int i = 0; i < boneCount; i++) {
+ result.bone_name_eg[i] = ConvertByteToString(binary_reader_.ReadBytes(20), "");
+ }
+ return result;
+ }
+
+ private PMDFormat.EnglishSkinNameList ReadEnglishSkinNameList(int skinCount) {
+ PMDFormat.EnglishSkinNameList result = new PMDFormat.EnglishSkinNameList();
+ result.skin_name_eg = new string[skinCount];
+ for (int i = 0; i < skinCount - 1; i++) {
+ result.skin_name_eg[i] = ConvertByteToString(binary_reader_.ReadBytes(20), "");
+ }
+ return result;
+ }
+
+ private PMDFormat.EnglishBoneDisplayList ReadEnglishBoneDisplayList(int boneDispNameCount) {
+ PMDFormat.EnglishBoneDisplayList result = new PMDFormat.EnglishBoneDisplayList();
+ result.disp_name_eg = new string[boneDispNameCount];
+ for (int i = 0; i < boneDispNameCount; i++) {
+ result.disp_name_eg[i] = ConvertByteToString(binary_reader_.ReadBytes(50), "");
+ }
+ return result;
+ }
+
+ private PMDFormat.ToonTextureList ReadToonTextureList() {
+ PMDFormat.ToonTextureList result = new PMDFormat.ToonTextureList();
+ result.toon_texture_file = new string[10];
+ for (int i = 0; i < result.toon_texture_file.Length; i++) {
+ result.toon_texture_file[i] = ConvertByteToString(binary_reader_.ReadBytes(100), "");
+ }
+ return result;
+ }
+
+ private PMDFormat.RigidbodyList ReadRigidbodyList() {
+ PMDFormat.RigidbodyList result = new PMDFormat.RigidbodyList();
+ result.rigidbody_count = binary_reader_.ReadUInt32();
+ result.rigidbody = new PMDFormat.Rigidbody[result.rigidbody_count];
+ for (int i = 0; i < result.rigidbody_count; i++) {
+ result.rigidbody[i] = ReadRigidbody();
+ }
+ return result;
+ }
+
+ private PMDFormat.Rigidbody ReadRigidbody() {
+ PMDFormat.Rigidbody result = new PMDFormat.Rigidbody();
+ result.rigidbody_name = ConvertByteToString(binary_reader_.ReadBytes(20), "");
+ result.rigidbody_rel_bone_index = binary_reader_.ReadUInt16();
+ result.rigidbody_group_index = binary_reader_.ReadByte();
+ result.rigidbody_group_target = binary_reader_.ReadUInt16();
+ result.shape_type = binary_reader_.ReadByte();
+ result.shape_w = binary_reader_.ReadSingle();
+ result.shape_h = binary_reader_.ReadSingle();
+ result.shape_d = binary_reader_.ReadSingle();
+ result.pos_pos = ReadSinglesToVector3(binary_reader_);
+ result.pos_rot = ReadSinglesToVector3(binary_reader_);
+ result.rigidbody_weight = binary_reader_.ReadSingle();
+ result.rigidbody_pos_dim = binary_reader_.ReadSingle();
+ result.rigidbody_rot_dim = binary_reader_.ReadSingle();
+ result.rigidbody_recoil = binary_reader_.ReadSingle();
+ result.rigidbody_friction = binary_reader_.ReadSingle();
+ result.rigidbody_type = binary_reader_.ReadByte();
+ return result;
+ }
+
+ private PMDFormat.RigidbodyJointList ReadRigidbodyJointList() {
+ PMDFormat.RigidbodyJointList result = new PMDFormat.RigidbodyJointList();
+ result.joint_count = binary_reader_.ReadUInt32();
+ result.joint = new PMDFormat.Joint[result.joint_count];
+ for (int i = 0; i < result.joint_count; i++) {
+ result.joint[i] = ReadJoint();
+ }
+ return result;
+ }
+
+ private PMDFormat.Joint ReadJoint() {
+ PMDFormat.Joint result = new PMDFormat.Joint();
+ result.joint_name = ConvertByteToString(binary_reader_.ReadBytes(20), "");
+ result.joint_rigidbody_a = binary_reader_.ReadUInt32();
+ result.joint_rigidbody_b = binary_reader_.ReadUInt32();
+ result.joint_pos = ReadSinglesToVector3(binary_reader_);
+ result.joint_rot = ReadSinglesToVector3(binary_reader_);
+ result.constrain_pos_1 = ReadSinglesToVector3(binary_reader_);
+ result.constrain_pos_2 = ReadSinglesToVector3(binary_reader_);
+ result.constrain_rot_1 = ReadSinglesToVector3(binary_reader_);
+ result.constrain_rot_2 = ReadSinglesToVector3(binary_reader_);
+ result.spring_pos = ReadSinglesToVector3(binary_reader_);
+ result.spring_rot = ReadSinglesToVector3(binary_reader_);
+ return result;
+ }
+
+ // ShiftJISからUTF-8に変換してstringで返す
+ private static string ConvertByteToString(byte[] bytes, string line_feed_code = null)
+ {
+ // パディングの消去, 文字を詰める
+ if (bytes[0] == 0) return "";
+ int count;
+ for (count = 0; count < bytes.Length; count++) if (bytes[count] == 0) break;
+ byte[] buf = new byte[count]; // NULL文字を含めるとうまく行かない
+ for (int i = 0; i < count; i++) {
+ buf[i] = bytes[i];
+ }
+
+#if UNITY_STANDALONE_OSX
+ buf = Encoding.Convert(Encoding.GetEncoding(932), Encoding.UTF8, buf);
+#else
+ buf = Encoding.Convert(Encoding.GetEncoding(0), Encoding.UTF8, buf);
+#endif
+ string result = Encoding.UTF8.GetString(buf);
+ if (null != line_feed_code) {
+ //改行コード統一(もしくは除去)
+ result = result.Replace("\r\n", "\n").Replace('\r', '\n').Replace("\n", line_feed_code);
+ }
+ return result;
+ }
+
+ private static Vector3 ReadSinglesToVector3(BinaryReader bin)
+ {
+ const int count = 3;
+ float[] result = new float[count];
+ for (int i = 0; i < count; i++)
+ {
+ result[i] = bin.ReadSingle();
+ if (float.IsNaN(result[i])) result[i] = 0.0f; //非数値なら回避
+ }
+ return new Vector3(result[0], result[1], result[2]);
+ }
+
+ private static Vector2 ReadSinglesToVector2(BinaryReader bin)
+ {
+ const int count = 2;
+ float[] result = new float[count];
+ for (int i = 0; i < count; i++)
+ {
+ result[i] = bin.ReadSingle();
+ if (float.IsNaN(result[i])) result[i] = 0.0f; //非数値なら回避
+ }
+ return new Vector2(result[0], result[1]);
+ }
+
+ private static Color ReadSinglesToColor(BinaryReader bin)
+ {
+ const int count = 4;
+ float[] result = new float[count];
+ for (int i = 0; i < count; i++)
+ {
+ result[i] = bin.ReadSingle();
+ }
+ return new Color(result[0], result[1], result[2], result[3]);
+ }
+
+ private static Color ReadSinglesToColor(BinaryReader bin, float fix_alpha)
+ {
+ const int count = 3;
+ float[] result = new float[count];
+ for (int i = 0; i < count; i++)
+ {
+ result[i] = bin.ReadSingle();
+ }
+ return new Color(result[0], result[1], result[2], fix_alpha);
+ }
+
+ private static ushort[] ReadUInt16s(BinaryReader bin, uint count)
+ {
+ ushort[] result = new ushort[count];
+ for (uint i = 0; i < count; i++)
+ {
+ result[i] = bin.ReadUInt16();
+ }
+ return result;
+ }
+
+ string file_path_;
+ BinaryReader binary_reader_;
+ PMDFormat format_;
+}
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/Editor/MMDLoader/Private/PMXConverter.cs b/Assets/Scripts/3rd/mmd-for-unity-master/Editor/MMDLoader/Private/PMXConverter.cs
new file mode 100644
index 000000000..69928c9d3
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/Editor/MMDLoader/Private/PMXConverter.cs
@@ -0,0 +1,2033 @@
+using UnityEngine;
+using UnityEditor;
+using System.Collections.Generic;
+using System.Linq;
+using MMD.PMX;
+
+namespace MMD
+{
+ public class PMXConverter : System.IDisposable
+ {
+ ///
+ /// アニメーションタイプ
+ ///
+ public enum AnimationType {
+ GenericMecanim, //汎用アバターでのMecanim
+ HumanMecanim, //人型アバターでのMecanim
+ LegacyAnimation, //旧式アニメーション
+ }
+
+ ///
+ /// GameObjectを作成する
+ ///
+ /// 内部形式データ
+ /// 剛体を使用するか
+ /// アニメーションタイプ
+ /// IKを使用するか
+ /// スケール
+ public static GameObject CreateGameObject(PMXFormat format, bool use_rigidbody, AnimationType animation_type, bool use_ik, float scale) {
+ GameObject result;
+ using (PMXConverter converter = new PMXConverter()) {
+ result = converter.CreateGameObject_(format, use_rigidbody, animation_type, use_ik, scale);
+ }
+ return result;
+ }
+
+ ///
+ /// デフォルトコンストラクタ
+ ///
+ ///
+ /// ユーザーに依るインスタンス作成を禁止する
+ ///
+ private PMXConverter() {}
+
+ ///
+ /// Disposeインターフェース
+ ///
+ public void Dispose()
+ {
+ if (null != alpha_readable_texture_) {
+ alpha_readable_texture_.Dispose();
+ }
+ }
+
+ ///
+ /// GameObjectを作成する
+ ///
+ /// 内部形式データ
+ /// 剛体を使用するか
+ /// アニメーションタイプ
+ /// IKを使用するか
+ /// スケール
+ private GameObject CreateGameObject_(PMXFormat format, bool use_rigidbody, AnimationType animation_type, bool use_ik, float scale) {
+ format_ = format;
+ use_ik_ = use_ik;
+ scale_ = scale;
+ root_game_object_ = new GameObject(format_.meta_header.name);
+ MMDEngine engine = root_game_object_.AddComponent(); //MMDEngine追加
+ //スケール・エッジ幅
+ engine.scale = scale_;
+ engine.outline_width = 1.0f;
+ engine.material_outline_widths = format.material_list.material.Select(x=>x.edge_size).ToArray();
+ engine.enable_render_queue = false; //初期値無効
+ const int c_render_queue_transparent = 3000;
+ engine.render_queue_value = c_render_queue_transparent;
+
+ MeshCreationInfo[] creation_info = CreateMeshCreationInfo(); // メッシュを作成する為の情報を作成
+ Mesh[] mesh = CreateMesh(creation_info); // メッシュの生成・設定
+ Material[][] materials = CreateMaterials(creation_info); // マテリアルの生成・設定
+ GameObject[] bones = CreateBones(); // ボーンの生成・設定
+ SkinnedMeshRenderer[] renderers = BuildingBindpose(mesh, materials, bones); // バインドポーズの作成
+ CreateMorph(mesh, materials, bones, renderers, creation_info); // モーフの生成・設定
+
+
+ // BoneController・IKの登録(use_ik_を使った判定はEntryBoneController()の中で行う)
+ {
+ engine.bone_controllers = EntryBoneController(bones);
+ engine.ik_list = engine.bone_controllers.Where(x=>null != x.ik_solver)
+ .Select(x=>x.ik_solver)
+ .ToArray();
+ }
+
+ // 剛体関連
+ if (use_rigidbody) {
+ GameObject[] rigids = CreateRigids();
+ AssignRigidbodyToBone(bones, rigids);
+ SetRigidsSettings(bones, rigids);
+ GameObject[] joints = CreateJoints(rigids);
+ GlobalizeRigidbody(joints);
+
+ // 非衝突グループ
+ List[] ignoreGroups = SettingIgnoreRigidGroups(rigids);
+ int[] groupTarget = GetRigidbodyGroupTargets(rigids);
+
+ MMDEngine.Initialize(engine, groupTarget, ignoreGroups, rigids);
+ }
+
+ // Mecanim設定
+ if (AnimationType.LegacyAnimation != animation_type) {
+ //アニメーター追加
+ AvatarSettingScript avatar_setting = new AvatarSettingScript(root_game_object_, bones);
+ switch (animation_type) {
+ case AnimationType.GenericMecanim: //汎用アバターでのMecanim
+ avatar_setting.SettingGenericAvatar();
+ break;
+ case AnimationType.HumanMecanim: //人型アバターでのMecanim
+ avatar_setting.SettingHumanAvatar();
+ break;
+ default:
+ throw new System.ArgumentException();
+ }
+
+ string path = format_.meta_header.folder + "/";
+ string name = GetFilePathString(format_.meta_header.name);
+ string file_name = path + name + ".avatar.asset";
+ avatar_setting.CreateAsset(file_name);
+ } else {
+ root_game_object_.AddComponent(); // アニメーション追加
+ }
+
+ return root_game_object_;
+ }
+
+ ///
+ /// メッシュを作成する時に参照するデータの纏め
+ ///
+ class MeshCreationInfo {
+ public class Pack {
+ public uint material_index; //マテリアル
+ public uint[] plane_indices; //面
+ public uint[] vertices; //頂点
+ }
+ public Pack[] value;
+ public uint[] all_vertices; //総頂点
+ public Dictionary reassign_dictionary; //頂点リアサインインデックス用辞書
+ }
+
+ ///
+ /// メッシュを作成する為の情報を作成
+ ///
+ /// メッシュ作成情報
+ MeshCreationInfo[] CreateMeshCreationInfo()
+ {
+ // 1メッシュで収まる場合でも-Multi()を使っても問題は起き無いが、
+ // -Multi()では頂点数計測をマテリアル単位で行う関係上、頂点数が多く見積もられる(概算値)。
+ // (1頂点を複数のマテリアルが参照している場合に参照している分だけ計上してしまう。)
+ // 依って上限付近では本来1メッシュで収まる物が複数メッシュに分割されてしまう事が有るので注意。
+ //
+ // -Multi()を使っても最終的には頂点数を最適化するので、
+ // 1メッシュに収まってしまえば-Single()と同じ頂点数に為る(確定値)。
+ //
+ // 単純に-Single()の方が解析が少ない分早い。
+
+ MeshCreationInfo[] result;
+ if (format_.vertex_list.vertex.Length < c_max_vertex_count_in_mesh) {
+ //1メッシュで収まるなら
+ result = CreateMeshCreationInfoSingle();
+ } else {
+ //1メッシュで収まらず、複数メッシュに分割するなら
+ result = CreateMeshCreationInfoMulti();
+ }
+ return result;
+ }
+
+ ///
+ /// メッシュを作成する為の情報を作成(単体メッシュ版)
+ ///
+ /// メッシュ作成情報
+ MeshCreationInfo[] CreateMeshCreationInfoSingle()
+ {
+ MeshCreationInfo[] result = new[]{new MeshCreationInfo()};
+ //全マテリアルを設定
+ result[0].value = CreateMeshCreationInfoPacks();
+ //全頂点を設定
+ result[0].all_vertices = Enumerable.Range(0, format_.vertex_list.vertex.Length).Select(x=>(uint)x).ToArray();
+ //頂点リアサインインデックス用辞書作成
+ result[0].reassign_dictionary = new Dictionary(result[0].all_vertices.Length);
+ for (uint i = 0, i_max = (uint)result[0].all_vertices.Length; i < i_max; ++i) {
+ result[0].reassign_dictionary[i] = i;
+ }
+ return result;
+ }
+
+ ///
+ /// 全マテリアルをメッシュ作成情報のマテリアルパックとして返す
+ ///
+ /// メッシュ作成情報のマテリアルパック
+ MeshCreationInfo.Pack[] CreateMeshCreationInfoPacks()
+ {
+ uint plane_start = 0;
+ //マテリアル単位のMeshCreationInfo.Packを作成する
+ return Enumerable.Range(0, format_.material_list.material.Length)
+ .Select(x=>{
+ MeshCreationInfo.Pack pack = new MeshCreationInfo.Pack();
+ pack.material_index = (uint)x;
+ uint plane_count = format_.material_list.material[x].face_vert_count;
+ pack.plane_indices = format_.face_vertex_list.face_vert_index.Skip((int)plane_start)
+ .Take((int)plane_count)
+ .ToArray();
+ pack.vertices = pack.plane_indices.Distinct() //重複削除
+ .ToArray();
+ plane_start += plane_count;
+ return pack;
+ })
+ .ToArray();
+ }
+
+ ///
+ /// メッシュを作成する為の情報を作成(複数メッシュ版)
+ ///
+ /// メッシュ作成情報
+ MeshCreationInfo[] CreateMeshCreationInfoMulti()
+ {
+ //マテリアル単位のMeshCreationInfo.Packを作成する
+ MeshCreationInfo.Pack[] packs = CreateMeshCreationInfoPacks();
+ //マテリアル細分化
+ packs = SplitSubMesh(packs);
+ //頂点数の多い順に並べる(メッシュ分割アルゴリズム上、後半に行く程頂点数が少ない方が敷き詰め効率が良い)
+ System.Array.Sort(packs, (x,y)=>y.vertices.Length - x.vertices.Length);
+
+ List result = new List();
+ do {
+ uint vertex_sum = 0;
+ MeshCreationInfo info = new MeshCreationInfo();
+ //マテリアルパック作成
+ info.value = Enumerable.Range(0, packs.Length)
+ .Where(x=>null!=packs[x]) //有効なマテリアルに絞る
+ .Where(x=>{ //採用しても頂点数が限界を超えないなら
+ vertex_sum += (uint)packs[x].vertices.Length;
+ return vertex_sum < c_max_vertex_count_in_mesh;
+ })
+ .Select(x=>{ //マテリアルの採用と無効化
+ var pack = packs[x];
+ packs[x] = null;
+ return pack;
+ })
+ .ToArray();
+ //マテリアルインデックスに並べる(メッシュの選定が終わったので見易い様に並びを戻す)
+ System.Array.Sort(info.value, (x,y)=>((x.material_index>y.material_index)? 1: (x.material_indexx.vertices).Distinct().ToArray();
+ System.Array.Sort(info.all_vertices);
+ //頂点リアサインインデックス用辞書作成
+ info.reassign_dictionary = new Dictionary();
+ uint reassign_index = 0;
+ foreach (var i in info.all_vertices) {
+ info.reassign_dictionary[i] = reassign_index++;
+ }
+ //戻り値に追加
+ result.Add(info);
+ } while (packs.Any(x=>null!=x)); //使用していないマテリアルが為るならループ
+ return result.ToArray();
+ }
+
+ ///
+ /// 1マテリアルの頂点数が1メッシュで表現出来ない場合に分割する
+ ///
+ /// メッシュ作成情報のマテリアルパック
+ /// メッシュ作成情報のマテリアルパック
+ MeshCreationInfo.Pack[] SplitSubMesh(MeshCreationInfo.Pack[] packs)
+ {
+ MeshCreationInfo.Pack[] result = packs;
+ if (packs.Any(x=>c_max_vertex_count_in_mesh<=x.vertices.Length)) {
+ //1メッシュに収まらないマテリアルが有るなら
+ List result_list = new List();
+ foreach (var pack in packs) {
+ if (c_max_vertex_count_in_mesh <= pack.vertices.Length) {
+ //1メッシュに収まらないなら
+ //分離
+ var split_pack = SplitSubMesh(pack);
+ foreach (var i in split_pack) {
+ result_list.Add(i);
+ }
+ } else {
+ //1メッシュに収まるなら
+ //素通し
+ result_list.Add(pack);
+ }
+ }
+ result = result_list.ToArray();
+ }
+ return result;
+ }
+
+ ///
+ /// 1マテリアルの頂点数が1メッシュで表現出来ないので分割する
+ ///
+ /// メッシュ作成情報のマテリアルパック
+ /// メッシュ作成情報のマテリアルパック
+ List SplitSubMesh(MeshCreationInfo.Pack pack)
+ {
+ List result = new List();
+ //1メッシュに収まらないなら
+ uint plane_end = (uint)pack.plane_indices.Length;
+ uint plane_start = 0;
+ while (plane_start < plane_end) {
+ //まだ面が有るなら
+ uint plane_count = 0;
+ uint vertex_count = 0;
+ while (true) {
+ //現在の頂点数から考えると、余裕分の1/3迄の数の面は安定して入る
+ //はみ出て欲しいから更に1面(3頂点)を足す
+ plane_count += (c_max_vertex_count_in_mesh - vertex_count) / 3 * 3 + 3;
+ vertex_count = (uint)pack.plane_indices.Skip((int)plane_start) //面頂点インデックス取り出し(先頭)
+ .Take((int)plane_count) //面頂点インデックス取り出し(末尾)
+ .Distinct() //重複削除
+ .Count(); //個数取得
+ if (c_max_vertex_count_in_mesh <= vertex_count) {
+ //1メッシュを超えているなら
+ //此処でのメッシュ超えは必ずc_max_vertex_count_in_meshぎりぎりで有り、1面(3頂点)を1つ取れば収まる様になっている
+ plane_count -= 3;
+ break;
+ }
+ if (plane_end <= (plane_start + plane_count)) {
+ //面の最後なら
+ break;
+ }
+ }
+ //分離分を戻り値の追加
+ MeshCreationInfo.Pack result_pack = new MeshCreationInfo.Pack();;
+ result_pack.material_index = pack.material_index;
+ result_pack.plane_indices = pack.plane_indices.Skip((int)plane_start) //面頂点インデックス取り出し(先頭)
+ .Take((int)plane_count) //面頂点インデックス取り出し(末尾)
+ .ToArray();
+ result_pack.vertices = result_pack.plane_indices.Distinct() //重複削除
+ .ToArray();
+ result.Add(result_pack);
+ //開始点を後ろに
+ plane_start += plane_count;
+ }
+ return result;
+ }
+
+ ///
+ /// メッシュ作成
+ ///
+ /// メッシュ
+ /// メッシュ作成情報
+ Mesh[] CreateMesh(MeshCreationInfo[] creation_info)
+ {
+ Mesh[] result = new Mesh[creation_info.Length];
+ for (int i = 0, i_max = creation_info.Length; i < i_max; ++i) {
+ Mesh mesh = new Mesh();
+ EntryAttributesForMesh(mesh, creation_info[i]);
+ SetSubMesh(mesh, creation_info[i]);
+ CreateAssetForMesh(mesh, i);
+ result[i] = mesh;
+ }
+ return result;
+ }
+
+ ///
+ /// メッシュに基本情報(頂点座標・法線・UV・ボーンウェイト)を登録する
+ ///
+ /// 対象メッシュ
+ /// メッシュ作成情報
+ void EntryAttributesForMesh(Mesh mesh, MeshCreationInfo creation_info)
+ {
+ mesh.vertices = creation_info.all_vertices.Select(x=>format_.vertex_list.vertex[x].pos * scale_).ToArray();
+ mesh.normals = creation_info.all_vertices.Select(x=>format_.vertex_list.vertex[x].normal_vec).ToArray();
+ mesh.uv = creation_info.all_vertices.Select(x=>format_.vertex_list.vertex[x].uv).ToArray();
+ if (0 < format_.header.additionalUV) {
+ //追加UVが1つ以上有れば
+ //1つ目のみ登録
+ mesh.uv2 = creation_info.all_vertices.Select(x=>new Vector2(format_.vertex_list.vertex[x].add_uv[0].x, format_.vertex_list.vertex[x].add_uv[0].y)).ToArray();
+ }
+ if (1 < format_.header.additionalUV)
+ {
+ //追加UVが1つ以上有れば
+ //2つ目のみ登録
+ mesh.uv3 = creation_info.all_vertices.Select(x => new Vector2(format_.vertex_list.vertex[x].add_uv[1].x, format_.vertex_list.vertex[x].add_uv[1].y)).ToArray();
+ }
+ if (2 < format_.header.additionalUV)
+ {
+ //追加UVが1つ以上有れば
+ //3つ目のみ登録
+ mesh.uv4 = creation_info.all_vertices.Select(x => new Vector2(format_.vertex_list.vertex[x].add_uv[2].x, format_.vertex_list.vertex[x].add_uv[2].y)).ToArray();
+ }
+ mesh.boneWeights = creation_info.all_vertices.Select(x=>ConvertBoneWeight(format_.vertex_list.vertex[x].bone_weight)).ToArray();
+ mesh.colors = creation_info.all_vertices.Select(x=>new Color(0.0f, 0.0f, 0.0f, format_.vertex_list.vertex[x].edge_magnification * 0.25f)).ToArray(); //不透明度にエッジ倍率を0.25倍した情報を仕込む(0~8迄は表せる)
+ }
+
+ ///
+ /// ボーンウェイトをUnity用に変換する
+ ///
+ /// Unity用ボーンウェイト
+ /// PMX用ボーンウェイト
+ BoneWeight ConvertBoneWeight(PMXFormat.BoneWeight bone_weight)
+ {
+ //HACK: 取り敢えずボーンウェイトタイプを考えずにBDEFx系として登録する
+ BoneWeight result = new BoneWeight();
+ switch (bone_weight.method) {
+ case PMXFormat.Vertex.WeightMethod.BDEF1: goto case PMXFormat.Vertex.WeightMethod.BDEF4;
+ case PMXFormat.Vertex.WeightMethod.BDEF2: goto case PMXFormat.Vertex.WeightMethod.BDEF4;
+ case PMXFormat.Vertex.WeightMethod.BDEF4:
+ //BDEF4なら
+ result.boneIndex0 = (int)bone_weight.bone1_ref;
+ result.weight0 = bone_weight.bone1_weight;
+ result.boneIndex1 = (int)bone_weight.bone2_ref;;
+ result.weight1 = bone_weight.bone2_weight;
+ result.boneIndex2 = (int)bone_weight.bone3_ref;
+ result.weight2 = bone_weight.bone3_weight;
+ result.boneIndex3 = (int)bone_weight.bone4_ref;
+ result.weight3 = bone_weight.bone4_weight;
+ break;
+ case PMXFormat.Vertex.WeightMethod.SDEF:
+ //SDEFなら
+ //HACK: BDEF4と同じ対応
+ goto case PMXFormat.Vertex.WeightMethod.BDEF4;
+ case PMXFormat.Vertex.WeightMethod.QDEF:
+ //QDEFなら
+ //HACK: BDEF4と同じ対応
+ goto case PMXFormat.Vertex.WeightMethod.BDEF4;
+ default:
+ throw new System.ArgumentOutOfRangeException();
+ }
+ return result;
+ }
+
+ ///
+ /// メッシュにサブメッシュを登録する
+ ///
+ /// 対象メッシュ
+ /// メッシュ作成情報
+ void SetSubMesh(Mesh mesh, MeshCreationInfo creation_info)
+ {
+ // マテリアル対サブメッシュ
+ // サブメッシュとはマテリアルに適用したい面頂点データのこと
+ // 面ごとに設定するマテリアルはここ
+ mesh.subMeshCount = creation_info.value.Length;
+ for (int i = 0, i_max = creation_info.value.Length; i < i_max; ++i) {
+ //format_.face_vertex_list.face_vert_indexを[start](含む)から[start+count](含まず)迄取り出し
+ int[] indices = creation_info.value[i].plane_indices.Select(x=>(int)creation_info.reassign_dictionary[x]) //頂点リアサインインデックス変換
+ .ToArray();
+ mesh.SetTriangles(indices, i);
+ }
+ }
+
+ ///
+ /// メッシュをProjectに登録する
+ ///
+ /// 対象メッシュ
+ /// メッシュインデックス
+ void CreateAssetForMesh(Mesh mesh, int index)
+ {
+ string path = format_.meta_header.folder + "/Meshes/";
+ if (!System.IO.Directory.Exists(path)) {
+ AssetDatabase.CreateFolder(format_.meta_header.folder, "Meshes");
+ }
+
+ string name = GetFilePathString(format_.meta_header.name);
+ string file_name = path + index.ToString() + "_" + name + ".asset";
+ AssetDatabase.CreateAsset(mesh, file_name);
+ }
+
+ ///
+ /// マテリアル作成
+ ///
+ /// マテリアル
+ /// メッシュ作成情報
+ Material[][] CreateMaterials(MeshCreationInfo[] creation_info)
+ {
+ // 適当なフォルダに投げる
+ string path = format_.meta_header.folder + "/Materials/";
+ if (!System.IO.Directory.Exists(path)) {
+ AssetDatabase.CreateFolder(format_.meta_header.folder, "Materials");
+ }
+
+ //全マテリアルを作成
+ Material[] materials = EntryAttributesForMaterials();
+ CreateAssetForMaterials(materials);
+
+ //メッシュ単位へ振り分け
+ Material[][] result = new Material[creation_info.Length][];
+ for (int i = 0, i_max = creation_info.Length; i < i_max; ++i) {
+ result[i] = creation_info[i].value.Select(x=>materials[x.material_index]).ToArray();
+ }
+
+ return result;
+ }
+
+ ///
+ /// マテリアルに基本情報(シェーダー・カラー・テクスチャ)を登録する
+ ///
+ /// マテリアル
+ Material[] EntryAttributesForMaterials()
+ {
+ //材質モーフが透過を要望するか
+ bool[] is_transparent_by_material = IsTransparentByMaterial(); //材質
+ bool[] is_transparent_by_material_morph = IsTransparentByMaterialMorph(); //材質モーフ
+ bool[] is_transparent_by_texture_alpha = IsTransparentByTextureAlpha(); //テクスチャのアルファ値(UV考慮済み)
+
+ return Enumerable.Range(0, format_.material_list.material.Length)
+ .Select(x=>new {material_index = (uint)x
+ , is_transparent = is_transparent_by_material[x] || is_transparent_by_material_morph[x] || is_transparent_by_texture_alpha[x]
+ }
+ )
+ .Select(x=>ConvertMaterial(x.material_index, x.is_transparent))
+ .ToArray();
+ }
+
+ ///
+ /// 材質に依る透過確認
+ ///
+ /// 透過かの配列(true:透過, false:不透明)
+ bool[] IsTransparentByMaterial()
+ {
+ //拡散色とエッジ色の透過確認
+ bool[] result = format_.material_list.material.Select(x=>(x.diffuse_color.a < 1.0f) || (x.edge_color.a < 1.0f))
+ .ToArray();
+ return result;
+ }
+
+ ///
+ /// 材質モーフに依る透過確認
+ ///
+ /// 透過かの配列(true:透過, false:不透明)
+ bool[] IsTransparentByMaterialMorph()
+ {
+ bool[] result = Enumerable.Repeat(false, format_.material_list.material.Length)
+ .ToArray();
+ var transparent_material_indices = format_.morph_list.morph_data.Where(x=>PMXFormat.MorphData.MorphType.Material==x.morph_type) //材質モーフなら
+ .SelectMany(x=>x.morph_offset) //材質モーフオフセット取得
+ .Select(x=>(PMXFormat.MaterialMorphOffset)x) //材質モーフオフセットにキャスト
+ .Where(x=>(PMXFormat.MaterialMorphOffset.OffsetMethod.Mul==x.offset_method)&&((x.diffuse.a < 1.0f)||(x.edge_color.a < 1.0f))) //拡散色かエッジ色が透過に為るなら
+ .Select(x=>x.material_index) //マテリアルインデックス取得
+ .Distinct(); //重複除去
+ foreach (uint material_index in transparent_material_indices) {
+ //材質モーフに依って透過が要望されているなら
+ //透過扱いにする
+ if (material_index < (uint)format_.material_list.material.Length) {
+ //単体モーフのマテリアルインデックスなら
+ //対象マテリアルだけ透過扱い
+ result[material_index] = true;
+ } else {
+ //全対象モーフのマテリアルインデックスなら
+ //全て透過扱い
+ result = Enumerable.Repeat(true, result.Length).ToArray();
+ break;
+ }
+ }
+ return result;
+ }
+
+ ///
+ /// テクスチャのアルファ値に依る透過確認
+ ///
+ /// 透過かの配列(true:透過, false:不透明)
+ bool[] IsTransparentByTextureAlpha()
+ {
+ Texture2D[] textures = GetTextureList();
+ Vector2[][] uvs = GetUvList();
+ bool[] result = Enumerable.Range(0, format_.material_list.material.Length)
+ .Select(x=>((null != textures[x])
+ ? IsTransparentByTextureAlphaWithUv(textures[x], uvs[x])
+ : false
+ ))
+ .ToArray();
+ return result;
+ }
+
+ ///
+ /// テクスチャの取得
+ ///
+ /// テクスチャ配列
+ Texture2D[] GetTextureList()
+ {
+ string[] texture_path = format_.material_list.material.Select(x=>x.usually_texture_index) //材質が使用しているテクスチャインデックスを取得
+ .Select(x=>((x
+ /// UVの取得
+ ///
+ /// UV配列
+ ///
+ /// UVモーフにて改変される場合は未適応(0.0f)と全適応(1.0f)の2段階のみを扱い、中間適応は考慮しない。
+ /// 複数のUVモーフが同一頂点に掛かる場合に多重適応すると単体では参照出来無い領域迄参照出来る様に為るが、これは考慮しない。
+ /// 同様にグループモーフに依る1.0f超えも考慮しない。
+ ///
+ Vector2[][] GetUvList()
+ {
+ uint[][] vertex_list = CreateMeshCreationInfoPacks().Select(x=>x.plane_indices).ToArray();
+
+ Dictionary[] uv_morphs = format_.morph_list.morph_data
+ .Where(x=>PMXFormat.MorphData.MorphType.Uv==x.morph_type) //UVモーフなら
+ .Select(x=>x.morph_offset.Select(y=>(PMXFormat.UVMorphOffset)y)
+ .ToDictionary(z=>z.vertex_index, z=>z.uv_offset) //頂点インデックスでディクショナリ化
+ ) //UVモーフオフセット取得
+ .ToArray();
+
+ List[] result = vertex_list.Select(x=>x.Select(y=>format_.vertex_list.vertex[y].uv).ToList()).ToArray();
+
+ //材質走査
+ bool is_cancel = false;
+ for (int material_index = 0, material_index_max = result.Length; material_index < material_index_max; ++material_index) {
+ //UVモーフ走査
+ for (int uv_morph_index = 0, uv_morph_index_max = uv_morphs.Length; uv_morph_index < uv_morph_index_max; ++uv_morph_index) {
+ var uv_morph = uv_morphs[uv_morph_index];
+ //ブログレスパー更新
+ is_cancel = EditorUtility.DisplayCancelableProgressBar("Create UV Area Infomation"
+ , "Material:[" + material_index + "|" + material_index_max + "]"
+ + format_.material_list.material[material_index].name
+ + "\t"
+ + "UV Morph:[" + uv_morph_index + "|" + uv_morph_index_max + "]"
+ + format_.morph_list.morph_data.Where(x=>PMXFormat.MorphData.MorphType.Uv==x.morph_type).Skip(uv_morph_index).First().morph_name
+ , ((((float)uv_morph_index / (float)uv_morph_index_max) + (float)material_index) / (float)material_index_max)
+ );
+ if (is_cancel) {
+ break;
+ }
+
+ //先行UVモーフ対象確認(三角形構成を無視して全頂点をUVモーフ参照)
+ var vertex_dictionary = vertex_list[material_index].Distinct().ToDictionary(x=>x, x=>true); //(UVモーフに設定されている頂点数依りも三角形構成頂点の方が多いと思うので、そちら側をlogNにする為に辞書作成)
+ if (uv_morph.Keys.Any(x=>vertex_dictionary.ContainsKey(x))) {
+ //UVモーフ対象なら
+ //頂点走査(三角形構成頂点走査)
+ for (int vertex_index = 0, vertex_index_max = vertex_list[material_index].Length; vertex_index < vertex_index_max; vertex_index+=3) {
+ //三角形構成頂点インデックス取り出し
+ uint[] tri_vertices = new []{vertex_list[material_index][vertex_index+0]
+ , vertex_list[material_index][vertex_index+1]
+ , vertex_list[material_index][vertex_index+2]
+ };
+ //UVモーフ対象確認
+ if (tri_vertices.Any(x=>uv_morph.ContainsKey(x))) {
+ //UVモーフ対象なら
+ //適応したUV値を作成
+ var tri_uv = tri_vertices.Select(x=>new{original_uv = format_.vertex_list.vertex[x].uv
+ , add_uv = ((uv_morph.ContainsKey(x))? uv_morph[x]: Vector4.zero)
+ }
+ )
+ .Select(x=>new Vector2(x.original_uv.x + x.add_uv.x, x.original_uv.y + x.add_uv.y));
+ //追加
+ result[material_index].AddRange(tri_uv);
+ }
+ }
+ }
+ }
+ if (is_cancel) {
+ break;
+ }
+ }
+ EditorUtility.ClearProgressBar();
+
+ return result.Select(x=>x.ToArray()).ToArray();
+ }
+
+ ///
+ /// UV値を考慮した、テクスチャのアルファ値に依る透過確認
+ ///
+ /// 透過か(true:透過, false:不透明)
+ /// テクスチャ
+ /// UV値(3つ単位で三角形を構成する)
+ static bool IsTransparentByTextureAlphaWithUv(Texture2D texture, Vector2[] uvs)
+ {
+ bool result = true;
+ if (TextureFormat.Alpha8 == texture.format) {
+ //ファイルがDDS以外なら(AlphaReadableTextureDirectoryImporterに依ってDDS以外はAlpha8に為る)
+ //alphaIsTransparencyを確認する
+ result = texture.alphaIsTransparency; //アルファ値を持たないなら透過フラグが立っていない
+ }
+ if (result) {
+ //アルファ値を持つなら
+ //詳細確認
+ result = Enumerable.Range(0, uvs.Length / 3) //3つ単位で取り出す為の元インデックス
+ .Select(x=>x*3) //3つ間隔に変換
+ .Any(x=>IsTransparentByTextureAlphaWithUv(texture, uvs[x+0],uvs[x+1],uvs[x+2])); //三角形を透過確認、どれかが透過していたら透過とする
+ }
+ return result;
+ }
+
+ ///
+ /// UV値を考慮した、テクスチャのアルファ値に依る透過確認
+ ///
+ /// 透過か(true:透過, false:不透明)
+ /// テクスチャ
+ /// 三角形頂点のUV値
+ /// 三角形頂点のUV値
+ /// 三角形頂点のUV値
+ ///
+ /// 理想ならば全テクセルを確認しなければならないが、
+ /// 現在の実装では三角形を構成する各頂点のUV・重心・各辺の中心点の7点のテクセルしか確認していない
+ ///
+ static bool IsTransparentByTextureAlphaWithUv(Texture2D texture, Vector2 uv1, Vector2 uv2, Vector2 uv3)
+ {
+ bool result = true; //透過
+ do {
+ //座標系が相違しているので補正
+ uv1.Set(uv1.x, 1.0f - uv1.y - (1.0f / texture.height));
+ uv2.Set(uv2.x, 1.0f - uv2.y - (1.0f / texture.height));
+ uv3.Set(uv3.x, 1.0f - uv3.y - (1.0f / texture.height));
+
+ const float c_threshold = 253.0f / 255.0f; //253程度迄は不透明として見逃す
+
+ //頂点直下
+ if (texture.GetPixelBilinear(uv1.x, uv1.y).a < c_threshold) {
+ break;
+ }
+ if (texture.GetPixelBilinear(uv2.x, uv2.y).a < c_threshold) {
+ break;
+ }
+ if (texture.GetPixelBilinear(uv3.x, uv3.y).a < c_threshold) {
+ break;
+ }
+
+ //重心
+ Vector2 center = new Vector2((uv1.x + uv2.x + uv3.x) / 3.0f, (uv1.y + uv2.y + uv3.y) / 3.0f);
+ if (texture.GetPixelBilinear(center.x, center.y).a < c_threshold) {
+ break;
+ }
+
+ //辺中央
+ Vector2 uv12 = new Vector2((uv1.x + uv2.x) / 2.0f, (uv1.y + uv2.y) / 2.0f);
+ if (texture.GetPixelBilinear(uv12.x, uv12.y).a < c_threshold) {
+ break;
+ }
+ Vector2 uv23 = new Vector2((uv2.x + uv3.x) / 2.0f, (uv2.y + uv3.y) / 2.0f);
+ if (texture.GetPixelBilinear(uv23.x, uv23.y).a < c_threshold) {
+ break;
+ }
+ Vector2 uv31 = new Vector2((uv3.x + uv1.x) / 2.0f, (uv3.y + uv1.y) / 2.0f);
+ if (texture.GetPixelBilinear(uv31.x, uv31.y).a < c_threshold) {
+ break;
+ }
+
+ //此処迄来たら不透明
+ result = false;
+ } while(false);
+ return result;
+ }
+
+ ///
+ /// マテリアルをUnity用に変換する
+ ///
+ /// Unity用マテリアル
+ /// PMX用マテリアルインデックス
+ /// 透過か
+ Material ConvertMaterial(uint material_index, bool is_transparent)
+ {
+ PMXFormat.Material material = format_.material_list.material[material_index];
+
+ //先にテクスチャ情報を検索
+ Texture2D main_texture = null;
+ if (material.usually_texture_index < format_.texture_list.texture_file.Length) {
+ string texture_file_name = format_.texture_list.texture_file[material.usually_texture_index];
+ string path = format_.meta_header.folder + "/" + texture_file_name;
+ main_texture = (Texture2D)AssetDatabase.LoadAssetAtPath(path, typeof(Texture2D));
+ }
+
+ //マテリアルに設定
+ string shader_path = GetMmdShaderPath(material, main_texture, is_transparent);
+ Material result = new Material(Shader.Find(shader_path));
+
+ // シェーダに依って値が有ったり無かったりするが、設定してもエラーに為らない様なので全部設定
+ result.SetColor("_Color", material.diffuse_color);
+ result.SetColor("_AmbColor", material.ambient_color);
+ result.SetFloat("_Opacity", material.diffuse_color.a);
+ result.SetColor("_SpecularColor", material.specular_color);
+ result.SetFloat("_Shininess", material.specularity);
+ // エッジ
+ const float c_default_scale = 0.085f; //0.085fの時にMMDと一致する様にしているので、それ以外なら補正
+ result.SetFloat("_OutlineWidth", material.edge_size * scale_ / c_default_scale);
+ result.SetColor("_OutlineColor", material.edge_color);
+ //カスタムレンダーキュー
+ {
+ MMDEngine engine = root_game_object_.GetComponent();
+ if (engine.enable_render_queue && IsTransparentMaterial(is_transparent)) {
+ //カスタムレンダーキューが有効 かつ マテリアルが透過なら
+ //マテリアル順に並べる
+ result.renderQueue = engine.render_queue_value + (int)material_index;
+ } else {
+ //非透明なら
+ result.renderQueue = -1;
+ }
+ }
+
+ // スフィアテクスチャ
+ if (material.sphere_texture_index < format_.texture_list.texture_file.Length) {
+ string sphere_texture_file_name = format_.texture_list.texture_file[material.sphere_texture_index];
+ string path = format_.meta_header.folder + "/" + sphere_texture_file_name;
+ Texture2D sphere_texture = (Texture2D)UnityEditor.AssetDatabase.LoadAssetAtPath(path, typeof(Texture2D));
+
+ switch (material.sphere_mode) {
+ case PMXFormat.Material.SphereMode.AddSphere: // 加算
+ result.SetTexture("_SphereAddTex", sphere_texture);
+ result.SetTextureScale("_SphereAddTex", new Vector2(1, -1));
+ break;
+ case PMXFormat.Material.SphereMode.MulSphere: // 乗算
+ result.SetTexture("_SphereMulTex", sphere_texture);
+ result.SetTextureScale("_SphereMulTex", new Vector2(1, -1));
+ break;
+ case PMXFormat.Material.SphereMode.SubTexture: // サブテクスチャ
+ //サブテクスチャ用シェーダーが無いので設定しない
+ break;
+ default:
+ //empty.
+ break;
+
+ }
+ }
+
+ // トゥーンテクスチャ
+ {
+ string toon_texture_name = null;
+ string toon_texture_path = null;
+ if (0 < material.common_toon) {
+ //共通トゥーン
+ string resource_path = System.IO.Path.GetDirectoryName(UnityEditor.AssetDatabase.GetAssetPath(Shader.Find("MMD/HalfLambertOutline")));
+ toon_texture_name = "toon" + material.common_toon.ToString("00") + ".bmp";
+ toon_texture_path = System.IO.Path.Combine(resource_path, toon_texture_name);
+ } else if (material.toon_texture_index < format_.texture_list.texture_file.Length) {
+ //自前トゥーン
+ toon_texture_name = format_.texture_list.texture_file[material.toon_texture_index];
+ toon_texture_path = System.IO.Path.Combine(format_.meta_header.folder, toon_texture_name);
+ }
+ if (!string.IsNullOrEmpty(toon_texture_path)) {
+ Texture2D toon_texture = (Texture2D)UnityEditor.AssetDatabase.LoadAssetAtPath(toon_texture_path, typeof(Texture2D));
+ result.SetTexture("_ToonTex", toon_texture);
+ result.SetTextureScale("_ToonTex", new Vector2(1, -1));
+ }
+ }
+
+ // テクスチャが空でなければ登録
+ if (null != main_texture) {
+ result.mainTexture = main_texture;
+ result.mainTextureScale = new Vector2(1, -1);
+ }
+
+ return result;
+ }
+
+ ///
+ /// MMDシェーダーパスの取得
+ ///
+ /// MMDシェーダーパス
+ /// シェーダーを設定するマテリアル
+ /// シェーダーに設定するメインテクスチャ
+ /// 透過か
+ string GetMmdShaderPath(PMXFormat.Material material, Texture2D texture, bool is_transparent) {
+ string result = "MMD/";
+ if (IsTransparentMaterial(is_transparent)) {
+ result += "Transparent/";
+ }
+ result += "PMDMaterial";
+ if (IsEdgeMaterial(material)) {
+ result += "-with-Outline";
+ }
+ if (IsCullBackMaterial(material)) {
+ result += "-CullBack";
+ }
+ if (IsNoCastShadowMaterial(material)) {
+ result += "-NoCastShadow";
+ }
+#if MFU_ENABLE_NO_RECEIVE_SHADOW_SHADER //影受け無しのシェーダはまだ無いので無効化
+ if (IsNoReceiveShadowMaterial(material)) {
+ result += "-NoReceiveShadow";
+ }
+#endif //MFU_ENABLE_NO_RECEIVE_SHADOW_SHADER
+ return result;
+ }
+
+ ///
+ /// 透過マテリアル確認
+ ///
+ /// true:透過, false:不透明
+ /// 透過か
+ bool IsTransparentMaterial(bool is_transparent) {
+ return is_transparent;
+ }
+
+ ///
+ /// エッジマテリアル確認
+ ///
+ /// true:エッジ有り, false:無エッジ
+ /// シェーダーを設定するマテリアル
+ bool IsEdgeMaterial(PMXFormat.Material material) {
+ bool result;
+ if (0 != (PMXFormat.Material.Flag.Edge & material.flag)) {
+ //エッジ有りなら
+ result = true;
+ } else {
+ //エッジ無し
+ result = false;
+ }
+ return result;
+ }
+
+ ///
+ /// 背面カリングマテリアル確認
+ ///
+ /// true:背面カリングする, false:背面カリングしない
+ /// シェーダーを設定するマテリアル
+ bool IsCullBackMaterial(PMXFormat.Material material) {
+ bool result;
+ if (0 != (PMXFormat.Material.Flag.Reversible & material.flag)) {
+ //両面描画なら
+ //背面カリングしない
+ result = false;
+ } else {
+ //両面描画で無いなら
+ //背面カリングする
+ result = true;
+ }
+ return result;
+ }
+
+ ///
+ /// 無影マテリアル確認
+ ///
+ /// true:無影, false:影放ち
+ /// シェーダーを設定するマテリアル
+ bool IsNoCastShadowMaterial(PMXFormat.Material material) {
+ bool result;
+ if (0 != (PMXFormat.Material.Flag.CastShadow & material.flag)) {
+ //影放ち
+ result = false;
+ } else {
+ //無影
+ result = true;
+ }
+ return result;
+ }
+
+ ///
+ /// 影受け無しマテリアル確認
+ ///
+ /// true:影受け無し, false:影受け
+ /// シェーダーを設定するマテリアル
+ bool IsNoReceiveShadowMaterial(PMXFormat.Material material) {
+ bool result;
+ if (0 != (PMXFormat.Material.Flag.ReceiveSelfShadow & material.flag)) {
+ //影受け
+ result = false;
+ } else {
+ //影受け無し
+ result = true;
+ }
+ return result;
+ }
+
+ ///
+ /// マテリアルをProjectに登録する
+ ///
+ /// 対象マテリアル
+ void CreateAssetForMaterials(Material[] materials) {
+ string path = format_.meta_header.folder + "/Materials/";
+
+ for (int i = 0, i_max = materials.Length; i < i_max; ++i) {
+ string name = GetFilePathString(format_.material_list.material[i].name);
+ string file_name = path + i.ToString() + "_" + name + ".asset";
+ AssetDatabase.CreateAsset(materials[i], file_name);
+ }
+ }
+
+ ///
+ /// ボーン作成
+ ///
+ /// ボーンのゲームオブジェクト
+ GameObject[] CreateBones()
+ {
+ GameObject[] bones = EntryAttributeForBones();
+ AttachParentsForBone(bones);
+ return bones;
+ }
+
+ ///
+ /// ボーンに基本情報(名前・位置)を登録する
+ ///
+ /// ボーンのゲームオブジェクト
+ GameObject[] EntryAttributeForBones()
+ {
+ return format_.bone_list.bone.Select(x=>{
+ GameObject game_object = new GameObject(x.bone_name);
+ game_object.transform.position = x.bone_position * scale_;
+ return game_object;
+ }).ToArray();
+ }
+
+ ///
+ /// 親子関係の構築
+ ///
+ /// ボーンのゲームオブジェクト
+ void AttachParentsForBone(GameObject[] bones)
+ {
+ //モデルルートを生成してルートの子供に付ける
+ Transform model_root_transform = (new GameObject("Model")).transform;
+ model_root_transform.parent = root_game_object_.transform;
+
+ for (int i = 0, i_max = format_.bone_list.bone.Length; i < i_max; ++i) {
+ uint parent_bone_index = format_.bone_list.bone[i].parent_bone_index;
+ if (parent_bone_index < (uint)bones.Length) {
+ //親のボーンが有るなら
+ //それの子に為る
+ bones[i].transform.parent = bones[parent_bone_index].transform;
+ } else {
+ //親のボーンが無いなら
+ //モデルルートの子に為る
+ bones[i].transform.parent = model_root_transform;
+ }
+ }
+ }
+
+ ///
+ /// モーフ作成
+ ///
+ /// 対象メッシュ
+ /// 対象マテリアル
+ /// 対象ボーン
+ /// 対象レンダラー
+ /// メッシュ作成情報
+ void CreateMorph(Mesh[] mesh, Material[][] materials, GameObject[] bones, SkinnedMeshRenderer[] renderers, MeshCreationInfo[] creation_info)
+ {
+ //表情ルートを生成してルートの子供に付ける
+ GameObject expression_root = new GameObject("Expression");
+ Transform expression_root_transform = expression_root.transform;
+ expression_root_transform.parent = root_game_object_.transform;
+
+ //表情マネージャー
+ MorphManager morph_manager = expression_root.AddComponent();
+ morph_manager.uv_morph = new MorphManager.UvMorphPack[1 + format_.header.additionalUV]; //UVモーフ数設定
+
+ //個別モーフスクリプト作成
+ GameObject[] morphs = new GameObject[format_.morph_list.morph_data.Length];
+ for (int i = 0, i_max = format_.morph_list.morph_data.Length; i < i_max; ++i) {
+ morphs[i] = new GameObject(format_.morph_list.morph_data[i].morph_name);
+ // 表情を親ボーンに付ける
+ morphs[i].transform.parent = expression_root_transform;
+ }
+
+ //グループモーフ作成
+ CreateGroupMorph(morph_manager, morphs);
+ //ボーンモーフ
+ morph_manager.bones = bones.Select(x=>x.transform).ToArray();
+ CreateBoneMorph(morph_manager, morphs);
+ //頂点モーフ作成
+ CreateVertexMorph(morph_manager, morphs, creation_info);
+ //UV・追加UVモーフ作成
+ CreateUvMorph(morph_manager, morphs, creation_info);
+ //材質モーフ作成
+ CreateMaterialMorph(morph_manager, morphs, creation_info);
+ //モーフ一覧設定(モーフコンポーネントの情報を拾う為、最後に設定する)
+ morph_manager.morphs = morphs.Select(x=>x.GetComponent()).ToArray();
+
+ //メッシュ・マテリアル設定
+ morph_manager.renderers = renderers;
+ morph_manager.mesh = mesh;
+ morph_manager.materials = materials;
+ }
+
+ ///
+ /// グループモーフ作成
+ ///
+ /// 表情マネージャー
+ /// モーフのゲームオブジェクト
+ void CreateGroupMorph(MorphManager morph_manager, GameObject[] morphs)
+ {
+ //インデックスと元データの作成
+ List original_indices = format_.morph_list.morph_data.Where(x=>(PMXFormat.MorphData.MorphType.Group == x.morph_type)) //該当モーフに絞る
+ .SelectMany(x=>x.morph_offset.Select(y=>((PMXFormat.GroupMorphOffset)y).morph_index)) //インデックスの取り出しと連結
+ .Distinct() //重複したインデックスの削除
+ .ToList(); //ソートに向けて一旦リスト化
+ original_indices.Sort(); //ソート
+ int[] indices = original_indices.Select(x=>(int)x).ToArray();
+ float[] source = Enumerable.Repeat(0.0f, indices.Length) //インデックスを用いて、元データをパック
+ .ToArray();
+
+ //インデックス逆引き用辞書の作成
+ Dictionary index_reverse_dictionary = new Dictionary();
+ for (uint i = 0, i_max = (uint)indices.Length; i < i_max; ++i) {
+ index_reverse_dictionary.Add((uint)indices[i], i);
+ }
+
+ //個別モーフスクリプトの作成
+ GroupMorph[] script = Enumerable.Range(0, format_.morph_list.morph_data.Length)
+ .Where(x=>PMXFormat.MorphData.MorphType.Group == format_.morph_list.morph_data[x].morph_type) //該当モーフに絞る
+ .Select(x=>AssignGroupMorph(morphs[x], format_.morph_list.morph_data[x], index_reverse_dictionary))
+ .ToArray();
+
+ //表情マネージャーにインデックス・元データ・スクリプトの設定
+ morph_manager.group_morph = new MorphManager.GroupMorphPack(indices, source, script);
+ }
+
+ ///
+ /// グループモーフ設定
+ ///
+ /// グループモーフスクリプト
+ /// モーフのゲームオブジェクト
+ /// PMX用モーフデータ
+ /// インデックス逆引き用辞書
+ GroupMorph AssignGroupMorph(GameObject morph, PMXFormat.MorphData data, Dictionary index_reverse_dictionary)
+ {
+ GroupMorph result = morph.AddComponent();
+ result.panel = (MorphManager.PanelType)data.handle_panel;
+ result.indices = data.morph_offset.Select(x=>((PMXFormat.GroupMorphOffset)x).morph_index) //インデックスを取り出し
+ .Select(x=>(int)index_reverse_dictionary[x]) //逆変換を掛ける
+ .ToArray();
+ result.values = data.morph_offset.Select(x=>((PMXFormat.GroupMorphOffset)x).morph_rate).ToArray();
+ return result;
+ }
+
+ ///
+ /// ボーンモーフ作成
+ ///
+ /// 表情マネージャー
+ /// モーフのゲームオブジェクト
+ void CreateBoneMorph(MorphManager morph_manager, GameObject[] morphs)
+ {
+ //インデックスと元データの作成
+ List original_indices = format_.morph_list.morph_data.Where(x=>(PMXFormat.MorphData.MorphType.Bone == x.morph_type)) //該当モーフに絞る
+ .SelectMany(x=>x.morph_offset.Select(y=>((PMXFormat.BoneMorphOffset)y).bone_index)) //インデックスの取り出しと連結
+ .Distinct() //重複したインデックスの削除
+ .ToList(); //ソートに向けて一旦リスト化
+ original_indices.Sort(); //ソート
+ int[] indices = original_indices.Select(x=>(int)x).ToArray();
+ BoneMorph.BoneMorphParameter[] source = indices.Where(x=>x{ //インデックスを用いて、元データをパック
+ PMXFormat.Bone y = format_.bone_list.bone[x];
+ BoneMorph.BoneMorphParameter result = new BoneMorph.BoneMorphParameter();
+ result.position = y.bone_position;
+ if (y.parent_bone_index < (uint)format_.bone_list.bone.Length) {
+ //親が居たらローカル座標化
+ result.position -= format_.bone_list.bone[y.parent_bone_index].bone_position;
+ }
+ result.position *= scale_;
+ result.rotation = Quaternion.identity;
+ return result;
+ })
+ .ToArray();
+
+ //インデックス逆引き用辞書の作成
+ Dictionary index_reverse_dictionary = new Dictionary();
+ for (uint i = 0, i_max = (uint)indices.Length; i < i_max; ++i) {
+ index_reverse_dictionary.Add((uint)indices[i], i);
+ }
+
+ //個別モーフスクリプトの作成
+ BoneMorph[] script = Enumerable.Range(0, format_.morph_list.morph_data.Length)
+ .Where(x=>PMXFormat.MorphData.MorphType.Bone == format_.morph_list.morph_data[x].morph_type) //該当モーフに絞る
+ .Select(x=>AssignBoneMorph(morphs[x], format_.morph_list.morph_data[x], index_reverse_dictionary))
+ .ToArray();
+
+ //表情マネージャーにインデックス・元データ・スクリプトの設定
+ morph_manager.bone_morph = new MorphManager.BoneMorphPack(indices, source, script);
+ }
+
+ ///
+ /// ボーンモーフ設定
+ ///
+ /// ボーンモーフスクリプト
+ /// モーフのゲームオブジェクト
+ /// PMX用モーフデータ
+ /// インデックス逆引き用辞書
+ BoneMorph AssignBoneMorph(GameObject morph, PMXFormat.MorphData data, Dictionary index_reverse_dictionary)
+ {
+ BoneMorph result = morph.AddComponent();
+ result.panel = (MorphManager.PanelType)data.handle_panel;
+ result.indices = data.morph_offset.Select(x=>((PMXFormat.BoneMorphOffset)x).bone_index) //インデックスを取り出し
+ .Select(x=>(int)index_reverse_dictionary[x]) //逆変換を掛ける
+ .ToArray();
+ result.values = data.morph_offset.Select(x=>{
+ PMXFormat.BoneMorphOffset y = (PMXFormat.BoneMorphOffset)x;
+ BoneMorph.BoneMorphParameter param = new BoneMorph.BoneMorphParameter();
+ param.position = y.move_value * scale_;
+ param.rotation = y.rotate_value;
+ return param;
+ })
+ .ToArray();
+ return result;
+ }
+
+ ///
+ /// 頂点モーフ作成
+ ///
+ /// 表情マネージャー
+ /// モーフのゲームオブジェクト
+ /// メッシュ作成情報
+ void CreateVertexMorph(MorphManager morph_manager, GameObject[] morphs, MeshCreationInfo[] creation_info)
+ {
+ //インデックスと元データの作成
+ List original_indices = format_.morph_list.morph_data.Where(x=>(PMXFormat.MorphData.MorphType.Vertex == x.morph_type)) //該当モーフに絞る
+ .SelectMany(x=>x.morph_offset.Select(y=>((PMXFormat.VertexMorphOffset)y).vertex_index)) //インデックスの取り出しと連結
+ .Distinct() //重複したインデックスの削除
+ .ToList(); //ソートに向けて一旦リスト化
+ original_indices.Sort(); //ソート
+ int[] indices = original_indices.Select(x=>(int)x).ToArray();
+ Vector3[] source = indices.Select(x=>format_.vertex_list.vertex[x].pos * scale_) //インデックスを用いて、元データをパック
+ .ToArray();
+
+ //インデックス逆引き用辞書の作成
+ Dictionary index_reverse_dictionary = new Dictionary();
+ for (uint i = 0, i_max = (uint)indices.Length; i < i_max; ++i) {
+ index_reverse_dictionary.Add((uint)indices[i], i);
+ }
+
+ //個別モーフスクリプトの作成
+ VertexMorph[] script = Enumerable.Range(0, format_.morph_list.morph_data.Length)
+ .Where(x=>PMXFormat.MorphData.MorphType.Vertex == format_.morph_list.morph_data[x].morph_type) //該当モーフに絞る
+ .Select(x=>AssignVertexMorph(morphs[x], format_.morph_list.morph_data[x], index_reverse_dictionary))
+ .ToArray();
+
+ //メッシュ別インデックスの作成
+ int invalid_vertex_index = format_.vertex_list.vertex.Length;
+ MorphManager.VertexMorphPack.Meshes[] multi_indices = new MorphManager.VertexMorphPack.Meshes[creation_info.Length];
+ for (int i = 0, i_max = creation_info.Length; i < i_max; ++i) {
+ multi_indices[i] = new MorphManager.VertexMorphPack.Meshes();
+ multi_indices[i].indices = new int[indices.Length];
+ for (int k = 0, k_max = indices.Length; k < k_max; ++k) {
+ if (creation_info[i].reassign_dictionary.ContainsKey((uint)indices[k])) {
+ //このメッシュで有効なら
+ multi_indices[i].indices[k] = (int)creation_info[i].reassign_dictionary[(uint)indices[k]];
+ } else {
+ //このメッシュでは無効なら
+ multi_indices[i].indices[k] = invalid_vertex_index; //最大頂点数を設定(uint.MaxValueでは無いので注意)
+ }
+ }
+ }
+
+ //表情マネージャーにインデックス・元データ・スクリプトの設定
+ morph_manager.vertex_morph = new MorphManager.VertexMorphPack(multi_indices, source, script);
+ }
+
+ ///
+ /// 頂点モーフ設定
+ ///
+ /// 頂点モーフスクリプト
+ /// モーフのゲームオブジェクト
+ /// PMX用モーフデータ
+ /// インデックス逆引き用辞書
+ VertexMorph AssignVertexMorph(GameObject morph, PMXFormat.MorphData data, Dictionary index_reverse_dictionary)
+ {
+ VertexMorph result = morph.AddComponent();
+ result.panel = (MorphManager.PanelType)data.handle_panel;
+ result.indices = data.morph_offset.Select(x=>((PMXFormat.VertexMorphOffset)x).vertex_index) //インデックスを取り出し
+ .Select(x=>(int)index_reverse_dictionary[x]) //逆変換を掛ける
+ .ToArray();
+ result.values = data.morph_offset.Select(x=>((PMXFormat.VertexMorphOffset)x).position_offset * scale_).ToArray();
+ return result;
+ }
+
+ ///
+ /// UV・追加UVモーフ作成
+ ///
+ /// 表情マネージャー
+ /// モーフのゲームオブジェクト
+ /// メッシュ作成情報
+ void CreateUvMorph(MorphManager morph_manager, GameObject[] morphs, MeshCreationInfo[] creation_info)
+ {
+ for (int morph_type_index = 0, morph_type_index_max = 1 + format_.header.additionalUV; morph_type_index < morph_type_index_max; ++morph_type_index) {
+ //モーフタイプ
+ PMXFormat.MorphData.MorphType morph_type;
+ switch (morph_type_index) {
+ case 0: morph_type = PMXFormat.MorphData.MorphType.Uv; break;
+ case 1: morph_type = PMXFormat.MorphData.MorphType.Adduv1; break;
+ case 2: morph_type = PMXFormat.MorphData.MorphType.Adduv2; break;
+ case 3: morph_type = PMXFormat.MorphData.MorphType.Adduv3; break;
+ case 4: morph_type = PMXFormat.MorphData.MorphType.Adduv4; break;
+ default: throw new System.ArgumentOutOfRangeException();
+ }
+
+ //インデックスと元データの作成
+ List original_indices = format_.morph_list.morph_data.Where(x=>(morph_type == x.morph_type)) //該当モーフに絞る
+ .SelectMany(x=>x.morph_offset.Select(y=>((PMXFormat.UVMorphOffset)y).vertex_index)) //インデックスの取り出しと連結
+ .Distinct() //重複したインデックスの削除
+ .ToList(); //ソートに向けて一旦リスト化
+ original_indices.Sort(); //ソート
+ int[] indices = original_indices.Select(x=>(int)x).ToArray();
+ Vector2[] source;
+ if (0 == morph_type_index) {
+ //通常UV
+ source = indices.Select(x=>format_.vertex_list.vertex[x].uv) //インデックスを用いて、元データをパック
+ .Select(x=>new Vector2(x.x, x.y))
+ .ToArray();
+ } else {
+ //追加UV
+ source = indices.Select(x=>format_.vertex_list.vertex[x].add_uv[morph_type_index - 1]) //インデックスを用いて、元データをパック
+ .Select(x=>new Vector2(x.x, x.y))
+ .ToArray();
+ }
+
+ //インデックス逆引き用辞書の作成
+ Dictionary index_reverse_dictionary = new Dictionary();
+ for (uint i = 0, i_max = (uint)indices.Length; i < i_max; ++i) {
+ index_reverse_dictionary.Add((uint)indices[i], i);
+ }
+
+ //個別モーフスクリプトの作成
+ UvMorph[] script = Enumerable.Range(0, format_.morph_list.morph_data.Length)
+ .Where(x=>morph_type == format_.morph_list.morph_data[x].morph_type) //該当モーフに絞る
+ .Select(x=>AssignUvMorph(morphs[x], format_.morph_list.morph_data[x], index_reverse_dictionary))
+ .ToArray();
+
+ //メッシュ別インデックスの作成
+ int invalid_vertex_index = format_.vertex_list.vertex.Length;
+ MorphManager.UvMorphPack.Meshes[] multi_indices = new MorphManager.UvMorphPack.Meshes[creation_info.Length];
+ for (int i = 0, i_max = creation_info.Length; i < i_max; ++i) {
+ multi_indices[i] = new MorphManager.UvMorphPack.Meshes();
+ multi_indices[i].indices = new int[indices.Length];
+ for (int k = 0, k_max = indices.Length; k < k_max; ++k) {
+ if (creation_info[i].reassign_dictionary.ContainsKey((uint)indices[k])) {
+ //このメッシュで有効なら
+ multi_indices[i].indices[k] = (int)creation_info[i].reassign_dictionary[(uint)indices[k]];
+ } else {
+ //このメッシュでは無効なら
+ multi_indices[i].indices[k] = invalid_vertex_index; //最大頂点数を設定(uint.MaxValueでは無いので注意)
+ }
+ }
+ }
+
+ //表情マネージャーにインデックス・元データ・スクリプトの設定
+ morph_manager.uv_morph[morph_type_index] = new MorphManager.UvMorphPack(multi_indices, source, script);
+ }
+ }
+
+ ///
+ /// UV・追加UVモーフ設定
+ ///
+ /// UVモーフスクリプト
+ /// モーフのゲームオブジェクト
+ /// PMX用モーフデータ
+ /// インデックス逆引き用辞書
+ UvMorph AssignUvMorph(GameObject morph, PMXFormat.MorphData data, Dictionary index_reverse_dictionary)
+ {
+ UvMorph result = morph.AddComponent();
+ result.panel = (MorphManager.PanelType)data.handle_panel;
+ result.indices = data.morph_offset.Select(x=>((PMXFormat.UVMorphOffset)x).vertex_index) //インデックスを取り出し
+ .Select(x=>(int)index_reverse_dictionary[x]) //逆変換を掛ける
+ .ToArray();
+ result.values = data.morph_offset.Select(x=>((PMXFormat.UVMorphOffset)x).uv_offset)
+ .Select(x=>new Vector2(x.x, x.y))
+ .ToArray();
+ return result;
+ }
+
+ ///
+ /// 材質モーフ作成
+ ///
+ /// 表情マネージャー
+ /// モーフのゲームオブジェクト
+ /// メッシュ作成情報
+ void CreateMaterialMorph(MorphManager morph_manager, GameObject[] morphs, MeshCreationInfo[] creation_info)
+ {
+ //インデックスと元データの作成
+ List original_indices = format_.morph_list.morph_data.Where(x=>(PMXFormat.MorphData.MorphType.Material == x.morph_type)) //該当モーフに絞る
+ .SelectMany(x=>x.morph_offset.Select(y=>((PMXFormat.MaterialMorphOffset)y).material_index)) //インデックスの取り出しと連結
+ .Distinct() //重複したインデックスの削除
+ .ToList(); //ソートに向けて一旦リスト化
+ original_indices.Sort(); //ソート
+ if (uint.MaxValue == original_indices.LastOrDefault()) {
+ //最後が uint.MaxValue(≒-1) なら
+ //全材質対象が存在するので全インデックスを取得
+ original_indices = Enumerable.Range(0, format_.material_list.material.Length + 1).Select(x=>(uint)x).ToList();
+ original_indices[format_.material_list.material.Length] = uint.MaxValue; //uint.MaxValueを忘れない
+ }
+ int[] indices = original_indices.Select(x=>(int)x).ToArray();
+ MaterialMorph.MaterialMorphParameter[] source = indices.Where(x=>x{ //インデックスを用いて、元データをパック
+ MaterialMorph.MaterialMorphParameter result = new MaterialMorph.MaterialMorphParameter();
+ if (0 <= x) {
+ //-1(全材質対象)で無いなら
+ //元データを取得
+ PMXFormat.Material y = format_.material_list.material[x];
+ result.color = y.diffuse_color;
+ result.specular = new Color(y.specular_color.r, y.specular_color.g, y.specular_color.b, y.specularity);
+ result.ambient = y.ambient_color;
+ result.outline_color = y.edge_color;
+ result.outline_width = y.edge_size;
+ result.texture_color = Color.white;
+ result.sphere_color = Color.white;
+ result.toon_color = Color.white;
+ } else {
+ //-1(全材質対象)なら
+ //適当にでっち上げる
+ result = MaterialMorph.MaterialMorphParameter.zero;
+ }
+ return result;
+ })
+ .ToArray();
+
+ //インデックス逆引き用辞書の作成
+ Dictionary index_reverse_dictionary = new Dictionary();
+ for (uint i = 0, i_max = (uint)indices.Length; i < i_max; ++i) {
+ index_reverse_dictionary.Add((uint)indices[i], i);
+ }
+
+ //個別モーフスクリプトの作成
+ MaterialMorph[] script = Enumerable.Range(0, format_.morph_list.morph_data.Length)
+ .Where(x=>PMXFormat.MorphData.MorphType.Material == format_.morph_list.morph_data[x].morph_type) //該当モーフに絞る
+ .Select(x=>AssignMaterialMorph(morphs[x], format_.morph_list.morph_data[x], index_reverse_dictionary))
+ .ToArray();
+
+ //材質リアサイン辞書の作成
+ Dictionary[] material_reassign_dictionary = new Dictionary[creation_info.Length + 1];
+ for (int i = 0, i_max = creation_info.Length; i < i_max; ++i) {
+ material_reassign_dictionary[i] = new Dictionary();
+ for (uint k = 0, k_max = (uint)creation_info[i].value.Length; k < k_max; ++k) {
+ material_reassign_dictionary[i][creation_info[i].value[k].material_index] = k;
+ }
+ if (-1 == indices.LastOrDefault()) {
+ //indices の最後が -1(≒uint.MaxValue) なら
+ //全材質対象が存在するので材質リアサイン辞書に追加
+ material_reassign_dictionary[i][uint.MaxValue] = uint.MaxValue;
+ }
+ }
+
+ //メッシュ別インデックスの作成
+ int invalid_material_index = format_.material_list.material.Length;
+ MorphManager.MaterialMorphPack.Meshes[] multi_indices = new MorphManager.MaterialMorphPack.Meshes[creation_info.Length];
+ for (int i = 0, i_max = creation_info.Length; i < i_max; ++i) {
+ multi_indices[i] = new MorphManager.MaterialMorphPack.Meshes();
+ multi_indices[i].indices = new int[indices.Length];
+ for (int k = 0, k_max = indices.Length; k < k_max; ++k) {
+ if (material_reassign_dictionary[i].ContainsKey((uint)indices[k])) {
+ //この材質で有効なら
+ multi_indices[i].indices[k] = (int)material_reassign_dictionary[i][(uint)indices[k]];
+ } else {
+ //この材質では無効なら
+ multi_indices[i].indices[k] = invalid_material_index; //最大材質数を設定(uint.MaxValueでは無いので注意)
+ }
+ }
+ }
+
+ //表情マネージャーにインデックス・元データ・スクリプトの設定
+ morph_manager.material_morph = new MorphManager.MaterialMorphPack(multi_indices, source, script);
+ }
+
+ ///
+ /// 材質モーフ設定
+ ///
+ /// 材質モーフスクリプト
+ /// モーフのゲームオブジェクト
+ /// PMX用モーフデータ
+ /// インデックス逆引き用辞書
+ MaterialMorph AssignMaterialMorph(GameObject morph, PMXFormat.MorphData data, Dictionary index_reverse_dictionary)
+ {
+ MaterialMorph result = morph.AddComponent();
+ result.panel = (MorphManager.PanelType)data.handle_panel;
+ result.indices = data.morph_offset.Select(x=>((PMXFormat.MaterialMorphOffset)x).material_index) //インデックスを取り出し
+ .Select(x=>(int)index_reverse_dictionary[x]) //逆変換を掛ける
+ .ToArray();
+ result.values = data.morph_offset.Select(x=>{
+ PMXFormat.MaterialMorphOffset y = (PMXFormat.MaterialMorphOffset)x;
+ MaterialMorph.MaterialMorphParameter param = new MaterialMorph.MaterialMorphParameter();
+ param.color = y.diffuse;
+ param.specular = new Color(y.specular.r, y.specular.g, y.specular.b, y.specularity);
+ param.ambient = y.ambient;
+ param.outline_color = y.edge_color;
+ param.outline_width = y.edge_size;
+ param.texture_color = y.texture_coefficient;
+ param.sphere_color = y.sphere_texture_coefficient;
+ param.toon_color = y.toon_texture_coefficient;
+ return param;
+ })
+ .ToArray();
+ result.operation = data.morph_offset.Select(x=>(MaterialMorph.OperationType)((PMXFormat.MaterialMorphOffset)x).offset_method)
+ .ToArray();
+ return result;
+ }
+
+ ///
+ /// バインドポーズの作成
+ ///
+ /// レンダラー
+ /// 対象メッシュ
+ /// 設定するマテリアル
+ /// 設定するボーン
+ SkinnedMeshRenderer[] BuildingBindpose(Mesh[] mesh, Material[][] materials, GameObject[] bones)
+ {
+ // メッシュルートを生成してルートの子供に付ける
+ Transform mesh_root_transform = (new GameObject("Mesh")).transform;
+ mesh_root_transform.parent = root_game_object_.transform;
+
+ //モデルルート取得
+ Transform model_root_transform = root_game_object_.transform.Find("Model");
+ //ボーン共通データ
+ Matrix4x4[] bindposes = bones.Select(x=>x.transform.worldToLocalMatrix).ToArray();
+ Transform[] bones_transform = bones.Select(x=>x.transform).ToArray();
+
+ //レンダー設定
+ SkinnedMeshRenderer[] result = new SkinnedMeshRenderer[mesh.Length];
+ for (int i = 0, i_max = mesh.Length; i < i_max; ++i) {
+ Transform mesh_transform = (new GameObject("Mesh" + i.ToString())).transform;
+ mesh_transform.parent = mesh_root_transform;
+ SkinnedMeshRenderer smr = mesh_transform.gameObject.AddComponent();
+ mesh[i].bindposes = bindposes;
+ smr.sharedMesh = mesh[i];
+ smr.bones = bones_transform;
+ smr.materials = materials[i];
+ smr.rootBone = model_root_transform;
+ smr.receiveShadows = false; //影を受けない
+
+ result[i] = smr;
+ }
+ return result;
+ }
+
+ ///
+ /// IK作成
+ ///
+ /// ボーンコントローラースクリプト
+ /// ボーンのゲームオブジェクト
+ BoneController[] EntryBoneController(GameObject[] bones)
+ {
+ //BoneControllerが他のBoneControllerを参照するので先に全ボーンに付与
+ foreach (var bone in bones) {
+ bone.AddComponent();
+ }
+ BoneController[] result = Enumerable.Range(0, format_.bone_list.bone.Length)
+ .OrderBy(x=>(int)(PMXFormat.Bone.Flag.PhysicsTransform & format_.bone_list.bone[x].bone_flag)) //物理後変形を後方へ
+ .ThenBy(x=>format_.bone_list.bone[x].transform_level) //変形階層で安定ソート
+ .Select(x=>ConvertBoneController(format_.bone_list.bone[x], x, bones)) //ConvertIk()を呼び出す
+ .ToArray();
+ return result;
+ }
+
+ ///
+ /// ボーンをボーンコントローラースクリプトに変換する
+ ///
+ /// ボーンコントローラースクリプト
+ /// PMX用ボーンデータ
+ /// 該当IKデータのボーン通しインデックス
+ /// ボーンのゲームオブジェクト
+ BoneController ConvertBoneController(PMXFormat.Bone bone, int bone_index, GameObject[] bones)
+ {
+ BoneController result = bones[bone_index].GetComponent();
+ if (0.0f != bone.additional_rate) {
+ //付与親が有るなら
+ result.additive_parent = bones[bone.additional_parent_index].GetComponent();
+ result.additive_rate = bone.additional_rate;
+ result.add_local = (0 != (PMXFormat.Bone.Flag.AddLocal & bone.bone_flag));
+ result.add_move = (0 != (PMXFormat.Bone.Flag.AddMove & bone.bone_flag));
+ result.add_rotate = (0 != (PMXFormat.Bone.Flag.AddRotation & bone.bone_flag));
+ }
+ if (use_ik_) {
+ //IKを使用するなら
+ if (0 != (PMXFormat.Bone.Flag.IkFlag & bone.bone_flag)) {
+ //IKが有るなら
+ result.ik_solver = bones[bone_index].AddComponent();
+ result.ik_solver.target = bones[bone.ik_data.ik_bone_index].transform;
+ result.ik_solver.controll_weight = bone.ik_data.limit_angle / 4; //HACK: CCDIKSolver側で4倍している様なので此処で逆補正
+ result.ik_solver.iterations = (int)bone.ik_data.iterations;
+ result.ik_solver.chains = bone.ik_data.ik_link.Select(x=>x.target_bone_index).Select(x=>bones[x].transform).ToArray();
+ //IK制御下のBoneController登録
+ result.ik_solver_targets = Enumerable.Repeat(result.ik_solver.target, 1)
+ .Concat(result.ik_solver.chains)
+ .Select(x=>x.GetComponent())
+ .ToArray();
+
+ //IK制御先のボーンについて、物理演算の挙動を調べる
+ var operation_types = Enumerable.Repeat(bone.ik_data.ik_bone_index, 1) //IK対象先をEnumerable化
+ .Concat(bone.ik_data.ik_link.Select(x=>x.target_bone_index)) //IK制御下を追加
+ .Join(format_.rigidbody_list.rigidbody, x=>x, y=>y.rel_bone_index, (x,y)=>y.operation_type); //剛体リストから関連ボーンにIK対象先・IK制御下と同じボーンを持つ物を列挙し、剛体タイプを返す
+ foreach (var operation_type in operation_types) {
+ if (PMXFormat.Rigidbody.OperationType.Static != operation_type) {
+ //ボーン追従で無い(≒物理演算)なら
+ //IK制御の無効化
+ result.ik_solver.enabled = false;
+ break;
+ }
+ }
+ }
+ }
+ return result;
+ }
+
+ ///
+ /// 剛体作成
+ ///
+ /// 剛体
+ GameObject[] CreateRigids()
+ {
+ if (!System.IO.Directory.Exists(System.IO.Path.Combine(format_.meta_header.folder, "Physics"))) {
+ AssetDatabase.CreateFolder(format_.meta_header.folder, "Physics");
+ }
+
+ // 剛体の登録
+ GameObject[] result = format_.rigidbody_list.rigidbody.Select(x=>ConvertRigidbody(x)).ToArray();
+ for (uint i = 0, i_max = (uint)result.Length; i < i_max; ++i) {
+ // マテリアルの設定
+ result[i].GetComponent().material = CreatePhysicMaterial(format_.rigidbody_list.rigidbody, i);
+
+ }
+
+ return result;
+ }
+
+ ///
+ /// 剛体をUnity用に変換する
+ ///
+ /// Unity用剛体ゲームオブジェクト
+ /// PMX用剛体データ
+ GameObject ConvertRigidbody(PMXFormat.Rigidbody rigidbody)
+ {
+ GameObject result = new GameObject("r_" + rigidbody.name);
+ //result.AddComponent(); // 1つのゲームオブジェクトに複数の剛体が付く事が有るので本体にはrigidbodyを適用しない
+
+ //位置・回転の設定
+ result.transform.position = rigidbody.collider_position * scale_;
+ result.transform.rotation = Quaternion.Euler(rigidbody.collider_rotation * Mathf.Rad2Deg);
+
+ // Colliderの設定
+ switch (rigidbody.shape_type) {
+ case PMXFormat.Rigidbody.ShapeType.Sphere:
+ EntrySphereCollider(rigidbody, result);
+ break;
+ case PMXFormat.Rigidbody.ShapeType.Box:
+ EntryBoxCollider(rigidbody, result);
+ break;
+ case PMXFormat.Rigidbody.ShapeType.Capsule:
+ EntryCapsuleCollider(rigidbody, result);
+ break;
+ default:
+ throw new System.ArgumentException();
+ }
+ return result;
+ }
+
+ ///
+ /// Sphere Colliderの設定
+ ///
+ /// PMX用剛体データ
+ /// Unity用剛体ゲームオブジェクト
+ void EntrySphereCollider(PMXFormat.Rigidbody rigidbody, GameObject obj)
+ {
+ SphereCollider collider = obj.AddComponent();
+ collider.radius = rigidbody.shape_size.x * scale_;
+ }
+
+ ///
+ /// Box Colliderの設定
+ ///
+ /// PMX用剛体データ
+ /// Unity用剛体ゲームオブジェクト
+ void EntryBoxCollider(PMXFormat.Rigidbody rigidbody, GameObject obj)
+ {
+ BoxCollider collider = obj.AddComponent();
+ collider.size = rigidbody.shape_size * 2.0f * scale_;
+ }
+
+ ///
+ /// Capsule Colliderの設定
+ ///
+ /// PMX用剛体データ
+ /// Unity用剛体ゲームオブジェクト
+ void EntryCapsuleCollider(PMXFormat.Rigidbody rigidbody, GameObject obj)
+ {
+ CapsuleCollider collider = obj.AddComponent();
+ collider.radius = rigidbody.shape_size.x * scale_;
+ collider.height = (rigidbody.shape_size.y + rigidbody.shape_size.x * 2.0f) * scale_;
+ }
+
+ ///
+ /// 物理素材の作成
+ ///
+ /// 物理素材
+ /// PMX用剛体データ
+ /// 剛体インデックス
+ PhysicsMaterial CreatePhysicMaterial(PMXFormat.Rigidbody[] rigidbodys, uint index)
+ {
+ PMXFormat.Rigidbody rigidbody = rigidbodys[index];
+ PhysicsMaterial material = new PhysicsMaterial(format_.meta_header.name + "_r_" + rigidbody.name);
+ material.bounciness = rigidbody.recoil;
+ material.staticFriction = rigidbody.friction;
+ material.dynamicFriction = rigidbody.friction;
+
+ string name = GetFilePathString(rigidbody.name);
+ string file_name = format_.meta_header.folder + "/Physics/" + index.ToString() + "_" + name + ".asset";
+ AssetDatabase.CreateAsset(material, file_name);
+ return material;
+ }
+
+ ///
+ /// 剛体とボーンを接続する
+ ///
+ /// ボーンのゲームオブジェクト
+ /// 剛体のゲームオブジェクト
+ void AssignRigidbodyToBone(GameObject[] bones, GameObject[] rigids)
+ {
+ // 物理演算ルートを生成してルートの子供に付ける
+ Transform physics_root_transform = (new GameObject("Physics", typeof(PhysicsManager))).transform;
+ physics_root_transform.parent = root_game_object_.transform;
+
+ // 剛体の数だけ回す
+ for (uint i = 0, i_max = (uint)rigids.Length; i < i_max; ++i) {
+ // 剛体を親ボーンに格納
+ uint rel_bone_index = GetRelBoneIndexFromNearbyRigidbody(i);
+ if (rel_bone_index < bones.Length) {
+ //親と為るボーンが有れば
+ //それの子と為る
+ rigids[i].transform.parent = bones[rel_bone_index].transform;
+ } else {
+ //親と為るボーンが無ければ
+ //物理演算ルートの子と為る
+ rigids[i].transform.parent = physics_root_transform;
+ }
+ }
+ }
+
+ ///
+ /// 剛体とボーンを接続する
+ ///
+ /// ボーンのゲームオブジェクト
+ /// 剛体のゲームオブジェクト
+ uint GetRelBoneIndexFromNearbyRigidbody(uint rigidbody_index)
+ {
+ uint bone_count = (uint)format_.bone_list.bone.Length;
+ //関連ボーンを探す
+ uint result = format_.rigidbody_list.rigidbody[rigidbody_index].rel_bone_index;
+ if (result < bone_count) {
+ //関連ボーンが有れば
+ return result;
+ }
+ Debug.Log(string.Format("No matching bone found for rigidbody: {0}", rigidbody_index));
+ //それでも無ければ
+ //諦める
+ result = uint.MaxValue;
+ return result;
+ }
+
+ ///
+ /// 剛体の値を設定する
+ ///
+ /// ボーンのゲームオブジェクト
+ /// 剛体のゲームオブジェクト
+ void SetRigidsSettings(GameObject[] bones, GameObject[] rigid)
+ {
+ uint bone_count = (uint)format_.bone_list.bone.Length;
+ for (uint i = 0, i_max = (uint)format_.rigidbody_list.rigidbody.Length; i < i_max; ++i) {
+ PMXFormat.Rigidbody rigidbody = format_.rigidbody_list.rigidbody[i];
+ GameObject target;
+ if (rigidbody.rel_bone_index < bone_count) {
+ //関連ボーンが有るなら
+ //関連ボーンに付与する
+ target = bones[rigidbody.rel_bone_index];
+ } else {
+ //関連ボーンが無いなら
+ //剛体に付与する
+ target = rigid[i];
+ }
+ UnityRigidbodySetting(rigidbody, target);
+ }
+ }
+
+ ///
+ /// Unity側のRigidbodyの設定を行う
+ ///
+ /// PMX用剛体データ
+ /// 設定対象のゲームオブジェクト
+ void UnityRigidbodySetting(PMXFormat.Rigidbody pmx_rigidbody, GameObject target)
+ {
+ Rigidbody rigidbody = target.GetComponent();
+ if (null != rigidbody) {
+ //減衰値は平均を取る
+ float totMass = rigidbody.mass + pmx_rigidbody.weight;
+ rigidbody.linearDamping = (rigidbody.linearDamping * rigidbody.mass + pmx_rigidbody.position_dim * pmx_rigidbody.weight) / totMass;
+ rigidbody.angularDamping = (rigidbody.angularDamping * rigidbody.mass + pmx_rigidbody.rotation_dim * pmx_rigidbody.weight) / totMass;
+ //既にRigidbodyが付与されているなら
+ //質量は合算する
+ rigidbody.mass = totMass;
+ }
+ else {
+ //まだRigidbodyが付与されていないなら
+ rigidbody = target.AddComponent();
+ rigidbody.isKinematic = (PMXFormat.Rigidbody.OperationType.Static == pmx_rigidbody.operation_type);
+ rigidbody.mass = Mathf.Max(float.Epsilon, pmx_rigidbody.weight);
+ rigidbody.linearDamping = pmx_rigidbody.position_dim;
+ rigidbody.angularDamping = pmx_rigidbody.rotation_dim;
+ }
+ }
+
+ ///
+ /// ジョイント作成
+ ///
+ /// ジョイントのゲームオブジェクト
+ /// 剛体のゲームオブジェクト
+ GameObject[] CreateJoints(GameObject[] rigids)
+ {
+ // ConfigurableJointの設定
+ GameObject[] joints = SetupConfigurableJoint(rigids);
+ return joints;
+ }
+
+ ///
+ /// ConfigurableJointの設定
+ ///
+ ///
+ /// 先に設定してからFixedJointを設定する
+ ///
+ /// ジョイントのゲームオブジェクト
+ /// 剛体のゲームオブジェクト
+ GameObject[] SetupConfigurableJoint(GameObject[] rigids)
+ {
+ List result_list = new List();
+ foreach (PMXFormat.Joint joint in format_.rigidbody_joint_list.joint) {
+ //相互接続する剛体の取得
+ Transform transform_a = rigids[joint.rigidbody_a].transform;
+ Rigidbody rigidbody_a = transform_a.GetComponent();
+ if (null == rigidbody_a) {
+ rigidbody_a = transform_a.parent.GetComponent();
+ }
+ Transform transform_b = rigids[joint.rigidbody_b].transform;
+ Rigidbody rigidbody_b = transform_b.GetComponent();
+ if (null == rigidbody_b) {
+ rigidbody_b = transform_b.parent.GetComponent();
+ }
+ if (rigidbody_a != rigidbody_b) {
+ //接続する剛体が同じ剛体を指さないなら
+ //(本来ならPMDの設定が間違っていない限り同一を指す事は無い)
+ //ジョイント設定
+ ConfigurableJoint config_joint = rigidbody_b.gameObject.AddComponent();
+ config_joint.connectedBody = rigidbody_a;
+ SetAttributeConfigurableJoint(joint, config_joint);
+
+ result_list.Add(config_joint.gameObject);
+ }
+ }
+ return result_list.ToArray();
+ }
+
+ ///
+ /// ConfigurableJointの値を設定する
+ ///
+ /// PMX用ジョイントデータ
+ /// Unity用ジョイント
+ void SetAttributeConfigurableJoint(PMXFormat.Joint joint, ConfigurableJoint conf)
+ {
+ SetMotionAngularLock(joint, conf);
+ SetDrive(joint, conf);
+ }
+
+ ///
+ /// ジョイントに移動・回転制限のパラメータを設定する
+ ///
+ /// PMX用ジョイントデータ
+ /// Unity用ジョイント
+ void SetMotionAngularLock(PMXFormat.Joint joint, ConfigurableJoint conf)
+ {
+ SoftJointLimit jlim;
+
+ // Motionの固定
+ if (joint.constrain_pos_lower.x == 0.0f && joint.constrain_pos_upper.x == 0.0f) {
+ conf.xMotion = ConfigurableJointMotion.Locked;
+ } else {
+ conf.xMotion = ConfigurableJointMotion.Limited;
+ }
+
+ if (joint.constrain_pos_lower.y == 0.0f && joint.constrain_pos_upper.y == 0.0f) {
+ conf.yMotion = ConfigurableJointMotion.Locked;
+ } else {
+ conf.yMotion = ConfigurableJointMotion.Limited;
+ }
+
+ if (joint.constrain_pos_lower.z == 0.0f && joint.constrain_pos_upper.z == 0.0f) {
+ conf.zMotion = ConfigurableJointMotion.Locked;
+ } else {
+ conf.zMotion = ConfigurableJointMotion.Limited;
+ }
+
+ // 角度の固定
+ if (joint.constrain_rot_lower.x == 0.0f && joint.constrain_rot_upper.x == 0.0f) {
+ conf.angularXMotion = ConfigurableJointMotion.Locked;
+ } else {
+ conf.angularXMotion = ConfigurableJointMotion.Limited;
+ float hlim = Mathf.Max(-joint.constrain_rot_lower.x, -joint.constrain_rot_upper.x); //回転方向が逆なので負数
+ float llim = Mathf.Min(-joint.constrain_rot_lower.x, -joint.constrain_rot_upper.x);
+ SoftJointLimit jhlim = new SoftJointLimit();
+ jhlim.limit = Mathf.Clamp(hlim * Mathf.Rad2Deg, -180.0f, 180.0f);
+ conf.highAngularXLimit = jhlim;
+
+ SoftJointLimit jllim = new SoftJointLimit();
+ jllim.limit = Mathf.Clamp(llim * Mathf.Rad2Deg, -180.0f, 180.0f);
+ conf.lowAngularXLimit = jllim;
+ }
+
+ if (joint.constrain_rot_lower.y == 0.0f && joint.constrain_rot_upper.y == 0.0f) {
+ conf.angularYMotion = ConfigurableJointMotion.Locked;
+ } else {
+ // 値がマイナスだとエラーが出るので注意
+ conf.angularYMotion = ConfigurableJointMotion.Limited;
+ float lim = Mathf.Min(Mathf.Abs(joint.constrain_rot_lower.y), Mathf.Abs(joint.constrain_rot_upper.y));//絶対値の小さい方
+ jlim = new SoftJointLimit();
+ jlim.limit = lim * Mathf.Clamp(Mathf.Rad2Deg, 0.0f, 180.0f);
+ conf.angularYLimit = jlim;
+ }
+
+ if (joint.constrain_rot_lower.z == 0f && joint.constrain_rot_upper.z == 0f) {
+ conf.angularZMotion = ConfigurableJointMotion.Locked;
+ } else {
+ conf.angularZMotion = ConfigurableJointMotion.Limited;
+ float lim = Mathf.Min(Mathf.Abs(-joint.constrain_rot_lower.z), Mathf.Abs(-joint.constrain_rot_upper.z));//絶対値の小さい方//回転方向が逆なので負数
+ jlim = new SoftJointLimit();
+ jlim.limit = Mathf.Clamp(lim * Mathf.Rad2Deg, 0.0f, 180.0f);
+ conf.angularZLimit = jlim;
+ }
+ }
+
+ ///
+ /// ジョイントにばねなどのパラメータを設定する
+ ///
+ /// PMX用ジョイントデータ
+ /// Unity用ジョイント
+ void SetDrive(PMXFormat.Joint joint, ConfigurableJoint conf)
+ {
+ JointDrive drive;
+
+ // Position
+ if (joint.spring_position.x != 0.0f) {
+ drive = new JointDrive();
+ drive.positionSpring = joint.spring_position.x * scale_;
+ conf.xDrive = drive;
+ }
+ if (joint.spring_position.y != 0.0f) {
+ drive = new JointDrive();
+ drive.positionSpring = joint.spring_position.y * scale_;
+ conf.yDrive = drive;
+ }
+ if (joint.spring_position.z != 0.0f) {
+ drive = new JointDrive();
+ drive.positionSpring = joint.spring_position.z * scale_;
+ conf.zDrive = drive;
+ }
+
+ // Angular
+ if (joint.spring_rotation.x != 0.0f) {
+ drive = new JointDrive();
+ drive.positionSpring = joint.spring_rotation.x;
+ conf.angularXDrive = drive;
+ }
+ if (joint.spring_rotation.y != 0.0f || joint.spring_rotation.z != 0.0f) {
+ drive = new JointDrive();
+ drive.positionSpring = (joint.spring_rotation.y + joint.spring_rotation.z) * 0.5f;
+ conf.angularYZDrive = drive;
+ }
+
+ conf.projectionMode = JointProjectionMode.PositionAndRotation;
+ }
+
+ ///
+ /// 剛体のグローバル座標化
+ ///
+ /// ジョイントのゲームオブジェクト
+ void GlobalizeRigidbody(GameObject[] joints)
+ {
+ Transform physics_root_transform = root_game_object_.transform.Find("Physics");
+ PhysicsManager physics_manager = physics_root_transform.gameObject.GetComponent();
+
+ if ((null != joints) && (0 < joints.Length)) {
+ // PhysicsManagerに移動前の状態を覚えさせる(幾つか重複しているので重複は削除)
+ physics_manager.connect_bone_list = joints.Select(x=>x.gameObject)
+ .Distinct()
+ .Select(x=>new PhysicsManager.ConnectBone(x, x.transform.parent.gameObject))
+ .ToArray();
+ //isKinematicで無くConfigurableJointを持つ場合はグローバル座標化
+ foreach (ConfigurableJoint joint in joints.Where(x=>!x.GetComponent().isKinematic)
+ .Select(x=>x.GetComponent())) {
+ joint.transform.parent = physics_root_transform;
+ }
+ }
+ }
+
+ ///
+ /// 非衝突剛体の設定
+ ///
+ /// 非衝突剛体のリスト
+ /// 剛体のゲームオブジェクト
+ List[] SettingIgnoreRigidGroups(GameObject[] rigids)
+ {
+ // 非衝突グループ用リストの初期化
+ const int MaxGroup = 16; // グループの最大数
+ List[] result = new List[MaxGroup];
+ for (int i = 0, i_max = MaxGroup; i < i_max; ++i) {
+ result[i] = new List();
+ }
+
+ // それぞれの剛体が所属している非衝突グループを追加していく
+ for (int i = 0, i_max = format_.rigidbody_list.rigidbody.Length; i < i_max; ++i) {
+ result[format_.rigidbody_list.rigidbody[i].group_index].Add(i);
+ }
+ return result;
+ }
+
+ ///
+ /// グループターゲットの取得
+ ///
+ /// グループターゲット
+ /// 剛体のゲームオブジェクト
+ int[] GetRigidbodyGroupTargets(GameObject[] rigids)
+ {
+ return format_.rigidbody_list.rigidbody.Select(x=>(int)x.ignore_collision_group).ToArray();
+ }
+
+ ///
+ /// ファイルパス文字列の取得
+ ///
+ /// ファイルパスに使用可能な文字列
+ /// ファイルパスに使用したい文字列
+ private static string GetFilePathString(string src) {
+ return src.Replace('\\', '\')
+ .Replace('/', '/')
+ .Replace(':', ':')
+ .Replace('*', '*')
+ .Replace('?', '?')
+ .Replace('"', '”')
+ .Replace('<', '<')
+ .Replace('>', '>')
+ .Replace('|', '|')
+ .Replace("\n", string.Empty)
+ .Replace("\r", string.Empty);
+ }
+
+ const uint c_max_vertex_count_in_mesh = 65535; //meshに含まれる最大頂点数(Unity3D的には65536迄入ると思われるが、ushort.MaxValueは特別な値として使うのでその分を除外)
+
+ GameObject root_game_object_;
+ PMXFormat format_;
+ bool use_ik_;
+ float scale_;
+ AlphaReadableTexture alpha_readable_texture_ = null;
+ }
+}
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/Editor/MMDLoader/Private/PMXLoaderScript.PMD2PMX.cs b/Assets/Scripts/3rd/mmd-for-unity-master/Editor/MMDLoader/Private/PMXLoaderScript.PMD2PMX.cs
new file mode 100644
index 000000000..cadaaec9d
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/Editor/MMDLoader/Private/PMXLoaderScript.PMD2PMX.cs
@@ -0,0 +1,411 @@
+using UnityEngine;
+using UnityEditor;
+using System.Collections.Generic;
+using System.Linq;
+using MMD.PMX;
+using MMD.PMD;
+
+public partial class PMXLoaderScript {
+
+ ///
+ /// PMXファイルのヘッダー取得
+ ///
+ /// PMDヘッダー
+ /// ヘッダー
+ public static PMXFormat.Header PMD2PMX(PMDFormat.Header pmd_header) {
+ PMXFormat.Header pmx_header = ConvertHeader(pmd_header, null, null);
+ return pmx_header;
+ }
+
+ ///
+ /// PMXファイルの取得
+ ///
+ /// PMDファイル
+ /// 内部形式データ
+ public static PMXFormat PMD2PMX(PMDFormat pmd) {
+ PMXFormat result = new PMXFormat();
+ result.meta_header = CreateMetaHeader(pmd);
+ result.header = ConvertHeader(pmd.head, pmd.eg_head, pmd);
+ result.vertex_list = ConvertVertexList(pmd);
+ result.face_vertex_list = ConvertFaceVertexList(pmd);
+ result.texture_list = ConvertTextureList(pmd);
+ result.material_list = ConvertMaterialList(pmd, x=>CreateTextureIndex(ref result.texture_list.texture_file, x));
+ result.bone_list = ConvertBoneList(pmd);
+ result.morph_list = ConvertMorphList(pmd);
+ result.display_frame_list = ConvertDisplayFrameList(pmd);
+ result.rigidbody_list = ConvertRigidbodyList(pmd);
+ result.rigidbody_joint_list = ConvertRigidbodyJointList(pmd);
+ return result;
+ }
+
+ ///
+ /// テクスチャインデックス取得用関数
+ ///
+ /// テクスチャインデックス
+ /// テクスチャリスト
+ /// 検索するテクスチャ名
+ private static uint CreateTextureIndex(ref string[] list, string name) {
+ uint result = uint.MaxValue;
+ for (int i = 0, i_max = list.Length; i < i_max; ++i) {
+ if (name == list[i]) {
+ //発見したらインデックスを返す
+ result = (uint)i;
+ break;
+ }
+ }
+ if (uint.MaxValue == result) {
+ //未発見なら
+ //末尾に登録して返す
+ string[] new_list = new string[list.Length + 1];
+ System.Array.Copy(list, new_list, list.Length);
+ new_list[list.Length] = name; //最後に追加
+ result = (uint)list.Length;
+ list = new_list;
+ }
+ return result;
+ }
+
+ private static PMXFormat.MetaHeader CreateMetaHeader(PMDFormat pmd) {
+ PMXFormat.MetaHeader result = new PMXFormat.MetaHeader();
+ result.path = pmd.path;
+ result.name = pmd.name;
+ result.folder = pmd.folder;
+ return result;
+ }
+
+ private static PMXFormat.Header ConvertHeader(PMDFormat.Header pmd_header, PMDFormat.EnglishHeader pmd_english_header, PMDFormat pmd) {
+ PMXFormat.Header result = new PMXFormat.Header();
+ result.magic = pmd_header.magic;
+ result.version = pmd_header.version;
+
+ result.dataSize = 0;
+ result.encodeMethod = PMXFormat.Header.StringCode.Utf16le;
+ result.additionalUV = 0;
+ result.vertexIndexSize = PMXFormat.Header.IndexSize.Byte1;
+ result.textureIndexSize = PMXFormat.Header.IndexSize.Byte1;
+ result.materialIndexSize = PMXFormat.Header.IndexSize.Byte1;
+ result.boneIndexSize = PMXFormat.Header.IndexSize.Byte1;
+ result.morphIndexSize = PMXFormat.Header.IndexSize.Byte1;
+ result.rigidbodyIndexSize = PMXFormat.Header.IndexSize.Byte1;
+ if (null != pmd) {
+ result.vertexIndexSize = GetIndexSize(pmd.vertex_list.vertex.Length);
+ result.textureIndexSize = GetIndexSize(pmd.toon_texture_list.toon_texture_file.Length);
+ result.materialIndexSize = GetIndexSize(pmd.material_list.material.Length);
+ result.boneIndexSize = GetIndexSize(pmd.bone_list.bone.Length);
+ result.morphIndexSize = GetIndexSize(pmd.skin_list.skin_data.Length);
+ result.rigidbodyIndexSize = GetIndexSize(pmd.rigidbody_list.rigidbody.Length);
+ }
+
+ result.model_name = pmd_header.model_name;
+ result.comment = pmd_header.comment;
+ result.model_english_name = "";
+ result.english_comment = "";
+ if (null != pmd_english_header) {
+ result.model_english_name = pmd_english_header.model_name_eg;
+ result.english_comment = pmd_english_header.comment_eg;
+ } else if (null != pmd) {
+ result.model_english_name = pmd.eg_head.model_name_eg;
+ result.english_comment = pmd.eg_head.comment_eg;
+ }
+ return result;
+ }
+
+ private static PMXFormat.Header.IndexSize GetIndexSize(int size) {
+ PMXFormat.Header.IndexSize result;
+ if ((int)ushort.MaxValue <= size) {
+ result = PMXFormat.Header.IndexSize.Byte4;
+ } else if ((int)byte.MaxValue <= size) {
+ result = PMXFormat.Header.IndexSize.Byte2;
+ } else {
+ result = PMXFormat.Header.IndexSize.Byte1;
+ }
+ return result;
+ }
+
+ private static PMXFormat.VertexList ConvertVertexList(PMDFormat pmd) {
+ PMXFormat.VertexList result = new PMXFormat.VertexList();
+ result.vertex = pmd.vertex_list.vertex.Select(x=>ConvertVertex(x)).ToArray();
+ return result;
+ }
+
+ private static PMXFormat.Vertex ConvertVertex(PMDFormat.Vertex pmd_vertex) {
+ PMXFormat.Vertex result = new PMXFormat.Vertex();
+ result.pos = pmd_vertex.pos;
+ result.normal_vec = pmd_vertex.normal_vec;
+ result.uv = pmd_vertex.uv;
+ result.add_uv = new Vector4[0];
+ if (100 == pmd_vertex.bone_weight) {
+ //1頂点
+ PMXFormat.BDEF1 bone_weight = new PMXFormat.BDEF1();
+ bone_weight.bone1_ref = pmd_vertex.bone_num[0];
+ result.bone_weight = bone_weight;
+ } else {
+ //2頂点
+ PMXFormat.BDEF2 bone_weight = new PMXFormat.BDEF2();
+ bone_weight.bone1_ref = pmd_vertex.bone_num[0];
+ bone_weight.bone2_ref = pmd_vertex.bone_num[1];
+ bone_weight.bone1_weight = pmd_vertex.bone_weight / 100.0f;
+ result.bone_weight = bone_weight;
+ }
+ result.edge_magnification = (float)pmd_vertex.edge_flag;
+ return result;
+ }
+
+ private static PMXFormat.FaceVertexList ConvertFaceVertexList(PMDFormat pmd) {
+ PMXFormat.FaceVertexList result = new PMXFormat.FaceVertexList();
+ result.face_vert_index = pmd.face_vertex_list.face_vert_index.Select(x=>(uint)x).ToArray();
+ return result;
+ }
+
+ private static PMXFormat.TextureList ConvertTextureList(PMDFormat pmd) {
+ PMXFormat.TextureList result = new PMXFormat.TextureList();
+ result.texture_file = pmd.toon_texture_list.toon_texture_file.ToArray(); //複製する
+ return result;
+ }
+
+ private static PMXFormat.MaterialList ConvertMaterialList(PMDFormat pmd, System.Func get_texture_index) {
+ PMXFormat.MaterialList result = new PMXFormat.MaterialList();
+ result.material = new PMXFormat.Material[pmd.material_list.material.Length];
+ for (int i = 0; i < result.material.Length; i++) {
+ result.material[i] = ConvertMaterial(pmd, i, get_texture_index);
+ }
+ return result;
+ }
+
+ private static PMXFormat.Material ConvertMaterial(PMDFormat pmd, int material_index, System.Func get_texture_index) {
+ PMXFormat.Material result = new PMXFormat.Material();
+ PMDFormat.Material pmd_material = pmd.material_list.material[material_index];
+
+ result.name = "材質_" + material_index.ToString();
+ result.english_name = "Material_" + material_index.ToString();
+ result.diffuse_color = new Color(pmd_material.diffuse_color.r, pmd_material.diffuse_color.g, pmd_material.diffuse_color.b, pmd_material.alpha);
+ result.specularity = pmd_material.specularity;
+ result.specular_color = pmd_material.specular_color;
+ result.ambient_color = pmd_material.mirror_color;
+ result.flag = new PMXFormat.Material.Flag();
+ if (pmd_material.alpha < 1.0f) {
+ result.flag |= PMXFormat.Material.Flag.Reversible;
+ }
+ if (0 != pmd_material.edge_flag) {
+ result.flag |= PMXFormat.Material.Flag.Edge | PMXFormat.Material.Flag.CastShadow | PMXFormat.Material.Flag.CastSelfShadow;
+ }
+ if (!(0.98f == pmd_material.alpha)) { //浮動小数点の比較だけど、0.98fとの同値確認でPMXエディタの0.98と一致したので一旦これで。
+ result.flag |= PMXFormat.Material.Flag.ReceiveSelfShadow;
+ }
+ result.edge_color = Color.black;
+ result.edge_size = 1.0f;
+ result.usually_texture_index = uint.MaxValue;
+ if (!string.IsNullOrEmpty(pmd_material.texture_file_name)) {
+ result.usually_texture_index = get_texture_index(pmd_material.texture_file_name);
+ }
+ result.sphere_texture_index = uint.MaxValue;
+ result.sphere_mode = PMXFormat.Material.SphereMode.Null;
+ if (!string.IsNullOrEmpty(pmd_material.sphere_map_name)) {
+ result.sphere_texture_index = get_texture_index(pmd_material.sphere_map_name);
+ switch (System.IO.Path.GetExtension(pmd_material.sphere_map_name)) {
+ case ".sph": result.sphere_mode = PMXFormat.Material.SphereMode.MulSphere; break;
+ case ".spa": result.sphere_mode = PMXFormat.Material.SphereMode.AddSphere; break;
+ default: break;
+ }
+ }
+ result.common_toon = pmd_material.toon_index;
+ result.toon_texture_index = ((0 < pmd_material.toon_index)? pmd_material.toon_index: uint.MaxValue);
+ result.memo = "";
+ result.face_vert_count = pmd_material.face_vert_count;
+ return result;
+ }
+
+ private static PMXFormat.BoneList ConvertBoneList(PMDFormat pmd) {
+ PMXFormat.BoneList result = new PMXFormat.BoneList();
+ result.bone = new PMXFormat.Bone[pmd.bone_list.bone.Length];
+ for (int i = 0, i_max = pmd.bone_list.bone.Length; i < i_max; ++i) {
+ result.bone[i] = ConvertBone(pmd, i);
+ }
+ return result;
+ }
+
+ private static PMXFormat.Bone ConvertBone(PMDFormat pmd, int bone_index) {
+ PMXFormat.Bone result = new PMXFormat.Bone();
+ PMDFormat.Bone pmd_bone = pmd.bone_list.bone[bone_index];
+
+ result.bone_name = pmd_bone.bone_name;
+ result.bone_english_name = ((null != pmd.eg_bone_name_list)? pmd.eg_bone_name_list.bone_name_eg[bone_index]: null);
+ result.bone_position = pmd_bone.bone_head_pos;
+ result.parent_bone_index = ((ushort.MaxValue == pmd_bone.parent_bone_index)? uint.MaxValue: (uint)pmd_bone.parent_bone_index);
+ result.transform_level = 0;
+ switch (pmd_bone.bone_type) {
+ case 0: //回転
+ result.bone_flag = PMXFormat.Bone.Flag.Movable | PMXFormat.Bone.Flag.DisplayFlag | PMXFormat.Bone.Flag.CanOperate;
+ break;
+ case 1: //回転と移動
+ result.bone_flag = PMXFormat.Bone.Flag.Movable | PMXFormat.Bone.Flag.Rotatable | PMXFormat.Bone.Flag.DisplayFlag | PMXFormat.Bone.Flag.CanOperate;
+ break;
+ case 2: //IK
+ result.bone_flag = PMXFormat.Bone.Flag.IkFlag | PMXFormat.Bone.Flag.DisplayFlag | PMXFormat.Bone.Flag.CanOperate;
+ break;
+ case 3: //不明
+ goto default;
+ case 4: //IK影響下
+ goto default;
+ case 5: //回転影響下
+ goto default; //付与親に変換しないといけないのかも
+ case 6: //IK接続先
+ goto default;
+ case 7: //非表示
+ goto default;
+ case 8: //捻り
+ goto default;
+ case 9: //回転運動
+ goto default;
+ default:
+ result.bone_flag = new PMXFormat.Bone.Flag();
+ break;
+ }
+ result.position_offset = Vector3.zero;
+ result.connection_index = 0;
+ result.additional_parent_index = 0;
+ result.additional_rate = 0.0f;
+ result.axis_vector = Vector3.zero;
+ result.x_axis_vector = Vector3.zero;
+ result.z_axis_vector = Vector3.zero;
+ result.key_value = 0;
+ result.ik_data = ConvertIKData(pmd.ik_list.ik_data.Where(x=>x.ik_bone_index==bone_index).FirstOrDefault());
+ return result;
+ }
+
+ private static PMXFormat.IK_Data ConvertIKData(PMDFormat.IK pmd_ik) {
+ PMXFormat.IK_Data result = null;
+ if (null != pmd_ik) {
+ result = new PMXFormat.IK_Data();
+ result.ik_bone_index = pmd_ik.ik_target_bone_index;
+ result.iterations = pmd_ik.iterations;
+ result.limit_angle = pmd_ik.control_weight * 4.0f; //PMXConverter側で4倍されるので逆補正
+ result.ik_link = pmd_ik.ik_child_bone_index.Select(x=>ConvertIKLink(x)).ToArray();
+ }
+ return result;
+ }
+
+ private static PMXFormat.IK_Link ConvertIKLink(ushort ik_child_bone_index) {
+ PMXFormat.IK_Link result = new PMXFormat.IK_Link();
+ result.target_bone_index = ik_child_bone_index;
+ return result;
+ }
+
+ private static PMXFormat.MorphList ConvertMorphList(PMDFormat pmd) {
+ PMXFormat.MorphList result = new PMXFormat.MorphList();
+ //頂点インデックス用辞書の作成
+ PMDFormat.SkinData pmd_skin_data_base = pmd.skin_list.skin_data.Where(x=>0==x.skin_type).First();
+ Dictionary morph_vertex_index_dictionary = new Dictionary(pmd_skin_data_base.skin_vert_data.Length);
+ for (uint i = 0, i_max = (uint)pmd_skin_data_base.skin_vert_data.Length; i < i_max; ++i) {
+ morph_vertex_index_dictionary.Add(i, pmd_skin_data_base.skin_vert_data[i].skin_vert_index);
+ }
+ //base以外の変換
+ result.morph_data = new PMXFormat.MorphData[pmd.skin_list.skin_data.Where(x=>0!=x.skin_type).Count()]; //base分を除外
+ int morph_data_count = 0;
+ for (int i = 0, i_max = pmd.skin_list.skin_data.Length; i < i_max; ++i) {
+ if (0 != pmd.skin_list.skin_data[i].skin_type) {
+ //base以外なら
+ string eg_skin_name = (((null != pmd.eg_skin_name_list) && (1 <= i))? pmd.eg_skin_name_list.skin_name_eg[i - 1]: null);
+ result.morph_data[morph_data_count++] = ConvertMorphData(pmd.skin_list.skin_data[i], eg_skin_name, morph_vertex_index_dictionary);
+ }
+ }
+ return result;
+ }
+
+ private static PMXFormat.MorphData ConvertMorphData(PMDFormat.SkinData pmd_skin, string pmd_eg_skin_name, Dictionary morph_vertex_index_dictionary) {
+ PMXFormat.MorphData result = new PMXFormat.MorphData();
+ result.morph_name = pmd_skin.skin_name;
+ result.morph_english_name = pmd_eg_skin_name;
+ result.handle_panel = (PMXFormat.MorphData.Panel)pmd_skin.skin_type;
+ result.morph_type = PMXFormat.MorphData.MorphType.Vertex;
+ result.morph_offset = pmd_skin.skin_vert_data.Select(x=>ConvertVertexMorphOffset(x, morph_vertex_index_dictionary)).ToArray();
+ return result;
+ }
+
+ private static PMXFormat.VertexMorphOffset ConvertVertexMorphOffset(PMDFormat.SkinVertexData pmd_skin_vertex_data, Dictionary morph_vertex_index_dictionary) {
+ PMXFormat.VertexMorphOffset result = new PMXFormat.VertexMorphOffset();
+ result.vertex_index = morph_vertex_index_dictionary[pmd_skin_vertex_data.skin_vert_index];
+ result.position_offset = pmd_skin_vertex_data.skin_vert_pos;
+ return result;
+ }
+
+ private static PMXFormat.DisplayFrameList ConvertDisplayFrameList(PMDFormat pmd) {
+ PMXFormat.DisplayFrameList result = new PMXFormat.DisplayFrameList();
+ result.display_frame = new PMXFormat.DisplayFrame[pmd.bone_display_list.bone_disp.Length];
+ for (int i = 0, i_max = result.display_frame.Length; i < i_max; ++i) {
+ result.display_frame[i] = ConvertDisplayFrame(pmd, i);
+ }
+ return result;
+ }
+
+ private static PMXFormat.DisplayFrame ConvertDisplayFrame(PMDFormat pmd, int bone_display_index) {
+ PMXFormat.DisplayFrame result = new PMXFormat.DisplayFrame();
+ PMDFormat.BoneDisplay pmd_bone_display = pmd.bone_display_list.bone_disp[bone_display_index];
+ result.display_name = pmd.bone_name_list.disp_name[pmd_bone_display.bone_disp_frame_index - 1];
+ result.display_english_name = ((null != pmd.eg_bone_display_list)? pmd.eg_bone_display_list.disp_name_eg[pmd_bone_display.bone_disp_frame_index - 1]: null);
+ result.special_frame_flag = new byte();
+ result.display_element = new []{new PMXFormat.DisplayElement()};
+ result.display_element[0].element_target = pmd_bone_display.bone_disp_frame_index;
+ result.display_element[0].element_target_index = pmd_bone_display.bone_index;
+ return result;
+ }
+
+ private static PMXFormat.RigidbodyList ConvertRigidbodyList(PMDFormat pmd) {
+ PMXFormat.RigidbodyList result = new PMXFormat.RigidbodyList();
+ result.rigidbody = new PMXFormat.Rigidbody[pmd.rigidbody_list.rigidbody.Length];
+ for (int i = 0, i_max = result.rigidbody.Length; i < i_max; ++i) {
+ result.rigidbody[i] = ConvertRigidbody(pmd, i);
+ }
+ return result;
+ }
+
+ private static PMXFormat.Rigidbody ConvertRigidbody(PMDFormat pmd, int rigidbody_index) {
+ PMXFormat.Rigidbody result = new PMXFormat.Rigidbody();
+ PMDFormat.Rigidbody pmd_rigidbody = pmd.rigidbody_list.rigidbody[rigidbody_index];
+ result.name = pmd_rigidbody.rigidbody_name;
+ result.english_name = "";
+ result.rel_bone_index = (uint)pmd_rigidbody.rigidbody_rel_bone_index;
+ result.group_index = pmd_rigidbody.rigidbody_group_index;
+ result.ignore_collision_group = pmd_rigidbody.rigidbody_group_target;
+ result.shape_type = (PMXFormat.Rigidbody.ShapeType)pmd_rigidbody.shape_type;
+ result.shape_size = new Vector3(pmd_rigidbody.shape_w, pmd_rigidbody.shape_h, pmd_rigidbody.shape_d);
+ result.collider_position = pmd_rigidbody.pos_pos;
+ if (pmd_rigidbody.rigidbody_rel_bone_index < pmd.bone_list.bone.Length) {
+ result.collider_position += pmd.bone_list.bone[pmd_rigidbody.rigidbody_rel_bone_index].bone_head_pos;
+ } else {
+ result.collider_position += pmd.bone_list.bone[0].bone_head_pos;
+ }
+ result.collider_rotation = pmd_rigidbody.pos_rot;
+ result.weight = pmd_rigidbody.rigidbody_weight;
+ result.position_dim = pmd_rigidbody.rigidbody_pos_dim;
+ result.rotation_dim = pmd_rigidbody.rigidbody_rot_dim;
+ result.recoil = pmd_rigidbody.rigidbody_recoil;
+ result.friction = pmd_rigidbody.rigidbody_friction;
+ result.operation_type = (PMXFormat.Rigidbody.OperationType)pmd_rigidbody.rigidbody_type;
+ return result;
+ }
+
+ private static PMXFormat.RigidbodyJointList ConvertRigidbodyJointList(PMDFormat pmx) {
+ PMXFormat.RigidbodyJointList result = new PMXFormat.RigidbodyJointList();
+ result.joint = pmx.rigidbody_joint_list.joint.Select(x=>ConvertJoint(x)).ToArray();
+ return result;
+ }
+
+ private static PMXFormat.Joint ConvertJoint(PMDFormat.Joint pmd_joint) {
+ PMXFormat.Joint result = new PMXFormat.Joint();
+ result.name = pmd_joint.joint_name;
+ result.english_name = "";
+ result.operation_type = PMXFormat.Joint.OperationType.Spring6DOF;
+ result.rigidbody_a = pmd_joint.joint_rigidbody_a;
+ result.rigidbody_b = pmd_joint.joint_rigidbody_b;
+ result.position = pmd_joint.joint_pos;
+ result.rotation = pmd_joint.joint_rot;
+ result.constrain_pos_lower = pmd_joint.constrain_pos_1;
+ result.constrain_pos_upper = pmd_joint.constrain_pos_2;
+ result.constrain_rot_lower = pmd_joint.constrain_rot_1;
+ result.constrain_rot_upper = pmd_joint.constrain_rot_2;
+ result.spring_position = pmd_joint.spring_pos;
+ result.spring_rotation = pmd_joint.spring_rot;
+ return result;
+ }
+}
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/Editor/MMDLoader/Private/PMXLoaderScript.PMX2PMD.cs b/Assets/Scripts/3rd/mmd-for-unity-master/Editor/MMDLoader/Private/PMXLoaderScript.PMX2PMD.cs
new file mode 100644
index 000000000..eadba1191
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/Editor/MMDLoader/Private/PMXLoaderScript.PMX2PMD.cs
@@ -0,0 +1,453 @@
+using UnityEngine;
+using UnityEditor;
+using System.Collections.Generic;
+using System.Linq;
+using MMD.PMX;
+using MMD.PMD;
+
+public partial class PMXLoaderScript {
+
+ ///
+ /// PMDファイルのヘッダー取得
+ ///
+ /// PMXヘッダー
+ /// ヘッダー
+ public static PMDFormat.Header PMX2PMD(PMXFormat.Header pmx_header) {
+ PMDFormat.Header pmd_header = ConvertHeader(pmx_header);
+ return pmd_header;
+ }
+
+ ///
+ /// PMDファイルの取得
+ ///
+ /// PMXファイル
+ /// 内部形式データ
+ public static PMDFormat PMX2PMD(PMXFormat pmx) {
+ PMDFormat result = new PMDFormat();
+ ConvertPathes(result, pmx);
+ result.head = ConvertHeader(pmx.header);
+ result.vertex_list = ConvertVertexList(pmx);
+ result.face_vertex_list = ConvertFaceVertexList(pmx);
+ result.material_list = ConvertMaterialList(pmx);
+ result.bone_list = ConvertBoneList(pmx);
+ result.ik_list = ConvertIKList(pmx);
+ result.skin_list = ConvertSkinList(pmx);
+ result.skin_name_list = ConvertSkinNameList(pmx);
+ result.bone_name_list = ConvertBoneNameList(pmx);
+ result.bone_display_list = ConvertBoneDisplayList(pmx);
+ result.eg_head = ConvertEnglishHeader(pmx);
+ result.eg_bone_name_list = ConvertEnglishBoneNameList(pmx);
+ result.eg_skin_name_list = ConvertEnglishSkinNameList(pmx);
+ result.eg_bone_display_list = ConvertEnglishBoneDisplayList(pmx);
+ result.toon_texture_list = ConvertToonTextureList(pmx);
+ result.rigidbody_list = ConvertRigidbodyList(pmx);
+ result.rigidbody_joint_list = ConvertRigidbodyJointList(pmx);
+ return result;
+ }
+
+ private static void ConvertPathes(PMDFormat pmd, PMXFormat pmx) {
+ pmd.path = pmx.meta_header.path;
+ pmd.name = pmx.meta_header.name;
+ pmd.folder = pmx.meta_header.folder;
+ }
+
+ private static PMDFormat.Header ConvertHeader(PMXFormat.Header pmx_header) {
+ PMDFormat.Header result = new PMDFormat.Header();
+ result.magic = pmx_header.magic;
+ result.version = pmx_header.version;
+ result.model_name = pmx_header.model_name;
+ result.comment = pmx_header.comment;
+ return result;
+ }
+
+ private static PMDFormat.VertexList ConvertVertexList(PMXFormat pmx) {
+ PMDFormat.VertexList result = new PMDFormat.VertexList();
+ result.vert_count = (uint)pmx.vertex_list.vertex.Length;
+ result.vertex = new PMDFormat.Vertex[result.vert_count];
+ for (int i = 0; i < result.vert_count; i++) {
+ result.vertex[i] = ConvertVertex(pmx, i);
+ }
+ return result;
+ }
+
+ private static PMDFormat.Vertex ConvertVertex(PMXFormat pmx, int vertex_index) {
+ PMDFormat.Vertex result = new PMDFormat.Vertex();
+ PMXFormat.Vertex pmx_vertex = pmx.vertex_list.vertex[vertex_index];
+ result.pos = pmx_vertex.pos;
+ result.normal_vec = pmx_vertex.normal_vec;
+ result.uv = pmx_vertex.uv;
+ switch (pmx_vertex.bone_weight.method) {
+ case PMXFormat.Vertex.WeightMethod.BDEF1: goto case PMXFormat.Vertex.WeightMethod.BDEF2;
+ case PMXFormat.Vertex.WeightMethod.BDEF2:
+ //BDEF1,BDEF2なら
+ //完全互換
+ result.bone_num = new ushort[]{(ushort)pmx_vertex.bone_weight.bone1_ref, (ushort)pmx_vertex.bone_weight.bone2_ref};
+ result.bone_weight = (byte)(pmx_vertex.bone_weight.bone1_weight * 100.0f + 0.5f);
+ break;
+ case PMXFormat.Vertex.WeightMethod.BDEF4:
+ //BDEF4なら
+ //ボーン3,4の情報を捨てる
+ result.bone_num = new ushort[]{(ushort)pmx_vertex.bone_weight.bone1_ref, (ushort)pmx_vertex.bone_weight.bone2_ref};
+ float bone1_weight = pmx_vertex.bone_weight.bone1_weight / (pmx_vertex.bone_weight.bone1_weight + pmx_vertex.bone_weight.bone2_weight);
+ result.bone_weight = (byte)(bone1_weight * 100.0f + 0.5f);
+ break;
+ case PMXFormat.Vertex.WeightMethod.SDEF:
+ //SDEFなら
+ //SDEFの情報を捨ててBDEF2扱い
+ goto case PMXFormat.Vertex.WeightMethod.BDEF2;
+ case PMXFormat.Vertex.WeightMethod.QDEF:
+ //QDEFなら
+ //BDEF4と同じ対応
+ goto case PMXFormat.Vertex.WeightMethod.BDEF4;
+ default:
+ throw new System.ArgumentOutOfRangeException();
+ }
+ result.edge_flag = (byte)((0.5f <= pmx_vertex.edge_magnification)? 1: 0);
+ return result;
+ }
+
+ private static PMDFormat.FaceVertexList ConvertFaceVertexList(PMXFormat pmx) {
+ PMDFormat.FaceVertexList result = new PMDFormat.FaceVertexList();
+ result.face_vert_count = (uint)pmx.face_vertex_list.face_vert_index.Length;
+ result.face_vert_index = pmx.face_vertex_list.face_vert_index.Select(x=>(ushort)x).ToArray();
+ return result;
+ }
+
+ private static PMDFormat.MaterialList ConvertMaterialList(PMXFormat pmx) {
+ PMDFormat.MaterialList result = new PMDFormat.MaterialList();
+ result.material_count = (uint)pmx.material_list.material.Length;
+ result.material = new PMDFormat.Material[result.material_count];
+ for (int i = 0; i < result.material_count; i++) {
+ result.material[i] = ConvertMaterial(pmx, i);
+ }
+ return result;
+ }
+
+ private static PMDFormat.Material ConvertMaterial(PMXFormat pmx, int material_index) {
+ PMDFormat.Material result = new PMDFormat.Material();
+ PMXFormat.Material pmx_material = pmx.material_list.material[material_index];
+ result.diffuse_color = pmx_material.diffuse_color;
+ result.alpha = result.diffuse_color.a;
+ result.diffuse_color.a = 1.0f;
+ result.specularity = pmx_material.specularity;
+ result.specular_color = pmx_material.specular_color;
+ result.mirror_color = pmx_material.ambient_color;
+ if (0 < pmx_material.common_toon) {
+ //共通トゥーン
+ string toon_name = "toon" + pmx_material.common_toon.ToString("00") + ".bmp";
+ int toon_name_index = -1;
+ for (int i = 0, i_max = pmx.texture_list.texture_file.Length; i < i_max; ++i) {
+ if (toon_name == pmx.texture_list.texture_file[i]) {
+ //既存の pmx.texture_list.texture_file に有れば
+ //使う
+ toon_name_index = i;
+ break;
+ }
+ }
+ if (toon_name_index < 0) {
+ //既存の pmx.texture_list.texture_file になければ
+ //後ろに追加する
+ string[] texture_file = new string[pmx.texture_list.texture_file.Length + 1];
+ System.Array.Copy(pmx.texture_list.texture_file, texture_file, pmx.texture_list.texture_file.Length);
+ texture_file[pmx.texture_list.texture_file.Length] = toon_name; //最後に追加
+ toon_name_index = pmx.texture_list.texture_file.Length;
+ pmx.texture_list.texture_file = texture_file;
+ }
+ result.toon_index = (byte)toon_name_index;
+ } else {
+ //自前トゥーン
+ result.toon_index = (byte)pmx_material.toon_texture_index;
+ }
+ result.edge_flag = (byte)((0 != ((int)pmx_material.flag & (int)PMXFormat.Material.Flag.Edge))? 1: 0);
+ result.face_vert_count = pmx_material.face_vert_count;
+ if (uint.MaxValue != pmx_material.sphere_texture_index) {
+ string tex = pmx.texture_list.texture_file[pmx_material.sphere_texture_index];
+ result.sphere_map_name = ((0 == tex.IndexOf("./"))? tex.Substring(2): tex); //"./"開始なら除去
+#if MFU_PMX2PMD_SPHERE_MAP_NAME_ADD_EXTENSION_FOR_SPHERE_MODE //スフィアモードの為に、拡張子を付加する(ファイルパスが変更されるのでMMDConverter側で2重拡張子に対応する迄無効化)
+ switch (pmx_material.sphere_mode) {
+ case PMXFormat.Material.SphereMode.AddSphere:
+ result.sphere_map_name += ".spa";
+ break;
+ case PMXFormat.Material.SphereMode.MulSphere:
+ result.sphere_map_name += ".sph";
+ break;
+ default:
+ break;
+ }
+#endif
+ }
+ if (uint.MaxValue != pmx_material.usually_texture_index) {
+ string tex = pmx.texture_list.texture_file[pmx_material.usually_texture_index];
+ result.texture_file_name = ((0 == tex.IndexOf("./"))? tex.Substring(2): tex); //"./"開始なら除去
+ }
+ return result;
+ }
+
+ private static PMDFormat.BoneList ConvertBoneList(PMXFormat pmx) {
+ PMDFormat.BoneList result = new PMDFormat.BoneList();
+ result.bone_count = (ushort)pmx.bone_list.bone.Length;
+ result.bone = new PMDFormat.Bone[result.bone_count];
+ for (int i = 0; i < result.bone_count; i++) {
+ result.bone[i] = ConvertBone(pmx, i);
+ }
+ return result;
+ }
+
+ private static PMDFormat.Bone ConvertBone(PMXFormat pmx, int bone_index) {
+ PMDFormat.Bone result = new PMDFormat.Bone();
+ PMXFormat.Bone pmx_bone = pmx.bone_list.bone[bone_index];
+ result.bone_name = pmx_bone.bone_name;
+ result.parent_bone_index = (ushort)((uint.MaxValue == pmx_bone.parent_bone_index)? ushort.MaxValue: pmx_bone.parent_bone_index);
+ result.tail_pos_bone_index = ushort.MaxValue;
+#if false
+ //PMD側 0:回転 1:回転と移動 2:IK 3:不明 4:IK影響下 5:回転影響下 6:IK接続先 7:非表示 8:捻り 9:回転運動
+ result.bone_type = pmx_bone.bone_flag;
+ //PMX側
+ public enum Flag {
+ Connection = 1<< 0,
+ Rotatable = 1<< 1,
+ Movable = 1<< 2,
+ DisplayFlag = 1<< 3,
+ CanOperate = 1<< 4,
+ IkFlag = 1<< 5,
+ AddRotation = 1<< 8,
+ AddMove = 1<< 9,
+ FixedAxis = 1<<10,
+ LocalAxis = 1<<11,
+ PhysicsTransform = 1<<12,
+ ExternalParentTransform = 1<<13,
+ }
+#else
+ result.bone_type = 2; //TODO: ボーンタイプを入れる
+#endif
+ if (null != pmx_bone.ik_data) {
+ result.ik_parent_bone_index = (ushort)pmx_bone.ik_data.ik_bone_index;
+ }
+ result.bone_head_pos = pmx_bone.bone_position;
+ return result;
+ }
+
+ private static PMDFormat.IKList ConvertIKList(PMXFormat pmx) {
+ PMDFormat.IKList result = new PMDFormat.IKList();
+ uint index = 0;
+ result.ik_data = pmx.bone_list.bone.Select(x=>new {data=x, index=index++}) //ボーン通しインデックスが要るのでデータと通しインデックスをパック
+ .Where(x=>((0 != ((int)PMXFormat.Bone.Flag.IkFlag & (int)x.data.bone_flag)) && (null != x.data.ik_data))) //IkFlagが有効でik_dataデータを持つもののみに絞る
+ .Select(x=>ConvertIK(x.data.ik_data, x.index)) //ConvertIK()を呼び出す
+ .ToArray();
+ result.ik_data_count = (ushort)result.ik_data.Length;
+ return result;
+ }
+
+ private static PMDFormat.IK ConvertIK(PMXFormat.IK_Data pmx_ik_data, uint bone_index) {
+ PMDFormat.IK result = new PMDFormat.IK();
+ result.ik_bone_index = (ushort)bone_index;
+ result.ik_target_bone_index = (ushort)pmx_ik_data.ik_bone_index;
+ result.ik_chain_length = (byte)pmx_ik_data.ik_link.Length;
+ result.iterations = (ushort)pmx_ik_data.iterations;
+ result.control_weight = pmx_ik_data.limit_angle / 4.0f; //MMDConverter側で4倍されるので逆補正
+ result.ik_child_bone_index = pmx_ik_data.ik_link.Select(x=>(ushort)x.target_bone_index).ToArray();
+ return result;
+ }
+
+ private static PMDFormat.SkinList ConvertSkinList(PMXFormat pmx) {
+ PMDFormat.SkinList result = new PMDFormat.SkinList();
+ result.skin_count = (ushort)pmx.morph_list.morph_data.Length;
+ result.skin_data = new PMDFormat.SkinData[result.skin_count + 1]; //base分が含まれていないので確保
+ //base設定
+ PMDFormat.SkinData base_skin = CreateBaseSkinData(pmx);
+ result.skin_data[0] = base_skin;
+ //頂点インデックス逆引き用辞書の作成
+ Dictionary skin_vertex_index_reverse_dictionary = new Dictionary((int)base_skin.skin_vert_count);
+ for (uint i = 0, i_max = base_skin.skin_vert_count; i < i_max; ++i) {
+ skin_vertex_index_reverse_dictionary.Add(base_skin.skin_vert_data[i].skin_vert_index, i);
+ }
+ //base以外の設定
+ for (int i = 0; i < result.skin_count; i++) {
+ result.skin_data[i + 1] = ConvertSkinData(pmx, i, skin_vertex_index_reverse_dictionary);
+ }
+ return result;
+ }
+
+ private static PMDFormat.SkinData ConvertSkinData(PMXFormat pmx, int skin_index, Dictionary skin_vertex_index_reverse_dictionary) {
+ PMDFormat.SkinData result = new PMDFormat.SkinData();
+ PMXFormat.MorphData pmx_morph = pmx.morph_list.morph_data[skin_index];
+ result.skin_name = pmx_morph.morph_name;
+ result.skin_vert_count = (uint)pmx_morph.morph_offset.Length;
+ result.skin_type = (byte)pmx_morph.handle_panel;
+ result.skin_vert_data = new PMDFormat.SkinVertexData[result.skin_vert_count];
+ for (int i = 0; i < result.skin_vert_count; i++) {
+ result.skin_vert_data[i] = ConvertSkinVertexData(pmx, skin_index, i, skin_vertex_index_reverse_dictionary);
+ }
+ return result;
+ }
+
+ private static PMDFormat.SkinVertexData ConvertSkinVertexData(PMXFormat pmx, int skin_index, int skin_vertex_index, Dictionary skin_vertex_index_reverse_dictionary) {
+ PMDFormat.SkinVertexData result = new PMDFormat.SkinVertexData();
+ PMXFormat.MorphData pmx_morph = pmx.morph_list.morph_data[skin_index];
+ PMXFormat.MorphOffset pmx_offset = pmx.morph_list.morph_data[skin_index].morph_offset[skin_vertex_index];
+ switch (pmx_morph.morph_type) {
+ case PMXFormat.MorphData.MorphType.Vertex: //頂点変形モーフなら
+ PMXFormat.VertexMorphOffset vertex_pmx_offset = (PMXFormat.VertexMorphOffset)pmx_offset;
+ result.skin_vert_index = skin_vertex_index_reverse_dictionary[vertex_pmx_offset.vertex_index];
+ result.skin_vert_pos = vertex_pmx_offset.position_offset;
+ break;
+ default: //頂点変形モーフ以外なら
+ //全て無効化
+ result.skin_vert_index = skin_vertex_index_reverse_dictionary.FirstOrDefault().Value;
+ result.skin_vert_pos = Vector3.zero;
+ break;
+ }
+ return result;
+ }
+
+ private static PMDFormat.SkinData CreateBaseSkinData(PMXFormat pmx) {
+ PMDFormat.SkinData result = new PMDFormat.SkinData();
+ result.skin_name = "base";
+ result.skin_type = (byte)PMXFormat.MorphData.Panel.Base;
+ var all_vertex_index_list = pmx.morph_list.morph_data.Where(x=>(PMXFormat.MorphData.MorphType.Vertex == x.morph_type)) //頂点変形ボーンに絞る
+ .SelectMany(x=>x.morph_offset.Select(y=>((PMXFormat.VertexMorphOffset)y).vertex_index)) //頂点インデックスの取り出しと連結
+ .Distinct() //重複した頂点インデックスの削除
+ .ToList(); //ソートに向けて一旦リスト化
+ all_vertex_index_list.Sort(); //ソート
+ result.skin_vert_data = all_vertex_index_list.Select(x=>{
+ PMDFormat.SkinVertexData skin_vertex_data = new PMDFormat.SkinVertexData();
+ skin_vertex_data.skin_vert_index = x;
+ skin_vertex_data.skin_vert_pos = pmx.vertex_list.vertex[x].pos;
+ return skin_vertex_data;
+ }) //頂点インデックスを用いて、元の頂点座標をパック
+ .ToArray();
+ result.skin_vert_count = (uint)result.skin_vert_data.Length;
+ return result;
+ }
+
+ private static PMDFormat.SkinNameList ConvertSkinNameList(PMXFormat pmx) {
+ PMDFormat.SkinNameList result = new PMDFormat.SkinNameList();
+ result.skin_disp_count = (byte)pmx.morph_list.morph_data.Length;
+ result.skin_index = new ushort[result.skin_disp_count];
+ for (int i = 0, i_max = result.skin_index.Length; i < i_max; ++i) {
+ result.skin_index[i] = (ushort)i;
+ }
+ return result;
+ }
+
+ private static PMDFormat.BoneNameList ConvertBoneNameList(PMXFormat pmx) {
+ PMDFormat.BoneNameList result = new PMDFormat.BoneNameList();
+ result.bone_disp_name_count = (byte)pmx.bone_list.bone.Length;
+ result.disp_name = pmx.bone_list.bone.Select(x=>x.bone_name).ToArray();
+ return result;
+ }
+
+ private static PMDFormat.BoneDisplayList ConvertBoneDisplayList(PMXFormat pmx) {
+ PMDFormat.BoneDisplayList result = new PMDFormat.BoneDisplayList();
+ result.bone_disp_count = (uint)pmx.bone_list.bone.Length;
+ result.bone_disp = new PMDFormat.BoneDisplay[result.bone_disp_count];
+ for (int i = 0; i < result.bone_disp_count; i++) {
+ result.bone_disp[i] = ConvertBoneDisplay(pmx, i);
+ }
+ return result;
+ }
+
+ private static PMDFormat.BoneDisplay ConvertBoneDisplay(PMXFormat pmx, int bone_index) {
+ PMDFormat.BoneDisplay result = new PMDFormat.BoneDisplay();
+ result.bone_index = (ushort)bone_index;
+ result.bone_disp_frame_index = (byte)bone_index;
+ return result;
+ }
+
+ private static PMDFormat.EnglishHeader ConvertEnglishHeader(PMXFormat pmx) {
+ PMDFormat.EnglishHeader result = new PMDFormat.EnglishHeader();
+ result.english_name_compatibility = 1;
+ result.model_name_eg = pmx.header.model_english_name;
+ result.comment_eg = pmx.header.english_comment;
+ return result;
+ }
+
+ private static PMDFormat.EnglishBoneNameList ConvertEnglishBoneNameList(PMXFormat pmx) {
+ PMDFormat.EnglishBoneNameList result = new PMDFormat.EnglishBoneNameList();
+ result.bone_name_eg = pmx.bone_list.bone.Select(x=>x.bone_english_name).ToArray();
+ return result;
+ }
+
+ private static PMDFormat.EnglishSkinNameList ConvertEnglishSkinNameList(PMXFormat pmx) {
+ PMDFormat.EnglishSkinNameList result = new PMDFormat.EnglishSkinNameList();
+ result.skin_name_eg = pmx.morph_list.morph_data.Select(x=>x.morph_english_name).ToArray();
+ return result;
+ }
+
+ private static PMDFormat.EnglishBoneDisplayList ConvertEnglishBoneDisplayList(PMXFormat pmx) {
+ PMDFormat.EnglishBoneDisplayList result = new PMDFormat.EnglishBoneDisplayList();
+ result.disp_name_eg = pmx.display_frame_list.display_frame.Select(x=>x.display_english_name).ToArray();
+ return result;
+ }
+
+ private static PMDFormat.ToonTextureList ConvertToonTextureList(PMXFormat pmx) {
+ PMDFormat.ToonTextureList result = new PMDFormat.ToonTextureList();
+ result.toon_texture_file = pmx.texture_list.texture_file.Select(x=>((0 == x.IndexOf("./"))? x.Substring(2): x)) //"./"開始なら除去
+ .ToArray();
+ return result;
+ }
+
+ private static PMDFormat.RigidbodyList ConvertRigidbodyList(PMXFormat pmx) {
+ PMDFormat.RigidbodyList result = new PMDFormat.RigidbodyList();
+ result.rigidbody_count = (uint)pmx.rigidbody_list.rigidbody.Length;
+ result.rigidbody = new PMDFormat.Rigidbody[result.rigidbody_count];
+ for (int i = 0; i < result.rigidbody_count; i++) {
+ result.rigidbody[i] = ConvertRigidbody(pmx, i);
+ }
+ return result;
+ }
+
+ private static PMDFormat.Rigidbody ConvertRigidbody(PMXFormat pmx, int rigidbody_index) {
+ PMDFormat.Rigidbody result = new PMDFormat.Rigidbody();
+ PMXFormat.Rigidbody pmx_rigidbody = pmx.rigidbody_list.rigidbody[rigidbody_index];
+ result.rigidbody_name = pmx_rigidbody.name;
+ result.rigidbody_rel_bone_index = (int)pmx_rigidbody.rel_bone_index;
+ result.rigidbody_group_index = pmx_rigidbody.group_index;
+ result.rigidbody_group_target = pmx_rigidbody.ignore_collision_group;
+ result.shape_type = (byte)pmx_rigidbody.shape_type;
+ result.shape_w = pmx_rigidbody.shape_size.x;
+ result.shape_h = pmx_rigidbody.shape_size.y;
+ result.shape_d = pmx_rigidbody.shape_size.z;
+ result.pos_pos = pmx_rigidbody.collider_position;
+ if (pmx_rigidbody.rel_bone_index < pmx.bone_list.bone.Length) {
+ result.pos_pos -= pmx.bone_list.bone[pmx_rigidbody.rel_bone_index].bone_position;
+ } else {
+ result.pos_pos -= pmx.bone_list.bone[0].bone_position;
+ }
+ result.pos_rot = pmx_rigidbody.collider_rotation;
+ result.rigidbody_weight = pmx_rigidbody.weight;
+ result.rigidbody_pos_dim = pmx_rigidbody.position_dim;
+ result.rigidbody_rot_dim = pmx_rigidbody.rotation_dim;
+ result.rigidbody_recoil = pmx_rigidbody.recoil;
+ result.rigidbody_friction = pmx_rigidbody.friction;
+ result.rigidbody_type = (byte)pmx_rigidbody.operation_type;
+ return result;
+ }
+
+ private static PMDFormat.RigidbodyJointList ConvertRigidbodyJointList(PMXFormat pmx) {
+ PMDFormat.RigidbodyJointList result = new PMDFormat.RigidbodyJointList();
+ result.joint_count = (uint)pmx.rigidbody_joint_list.joint.Length;
+ result.joint = new PMDFormat.Joint[result.joint_count];
+ for (int i = 0; i < result.joint_count; i++) {
+ result.joint[i] = ConvertJoint(pmx, i);
+ }
+ return result;
+ }
+
+ private static PMDFormat.Joint ConvertJoint(PMXFormat pmx, int joint_index) {
+ PMDFormat.Joint result = new PMDFormat.Joint();
+ PMXFormat.Joint pmx_joint = pmx.rigidbody_joint_list.joint[joint_index];
+ result.joint_name = pmx_joint.name;
+ result.joint_rigidbody_a = pmx_joint.rigidbody_a;
+ result.joint_rigidbody_b = pmx_joint.rigidbody_b;
+ result.joint_pos = pmx_joint.position;
+ result.joint_rot = pmx_joint.rotation;
+ result.constrain_pos_1 = pmx_joint.constrain_pos_lower;
+ result.constrain_pos_2 = pmx_joint.constrain_pos_upper;
+ result.constrain_rot_1 = pmx_joint.constrain_rot_lower;
+ result.constrain_rot_2 = pmx_joint.constrain_rot_upper;
+ result.spring_pos = pmx_joint.spring_position;
+ result.spring_rot = pmx_joint.spring_rotation;
+ return result;
+ }
+}
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/Editor/MMDLoader/Private/PMXLoaderScript.cs b/Assets/Scripts/3rd/mmd-for-unity-master/Editor/MMDLoader/Private/PMXLoaderScript.cs
new file mode 100644
index 000000000..10e77ced6
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/Editor/MMDLoader/Private/PMXLoaderScript.cs
@@ -0,0 +1,639 @@
+using UnityEngine;
+using UnityEditor;
+using System.Collections.Generic;
+using System.Text;
+using System.IO;
+using MMD.PMX;
+using MMD.PMD;
+
+public partial class PMXLoaderScript {
+
+ ///
+ /// PMXファイルのヘッダー取得
+ ///
+ /// PMDファイルのパス
+ /// ヘッダー
+ public static PMXFormat.Header GetHeader(string file_path) {
+ PMXLoaderScript loader = new PMXLoaderScript();
+ return loader.GetHeader_(file_path);
+ }
+
+ ///
+ /// PMXファイルのインポート
+ ///
+ /// PMDファイルのパス
+ /// 内部形式データ
+ public static PMXFormat Import(string file_path) {
+ PMXLoaderScript loader = new PMXLoaderScript();
+ return loader.Import_(file_path);
+ }
+
+ ///
+ /// デフォルトコンストラクタ
+ ///
+ ///
+ /// ユーザーに依るインスタンス作成を禁止する
+ ///
+ private PMXLoaderScript() {}
+
+ private PMXFormat.Header GetHeader_(string file_path) {
+ PMXFormat.Header result;
+ using (FileStream stream = new FileStream(file_path, FileMode.Open, FileAccess.Read))
+ using (BinaryReader bin = new BinaryReader(stream)) {
+ file_path_ = null;
+ binary_reader_ = bin;
+ result = ReadHeader();
+ }
+ return result;
+ }
+
+ private PMXFormat Import_(string file_path) {
+ using (FileStream stream = new FileStream(file_path, FileMode.Open, FileAccess.Read))
+ using (BinaryReader bin = new BinaryReader(stream)) {
+ file_path_ = file_path;
+ binary_reader_ = bin;
+ Read();
+ }
+ return format_;
+ }
+
+ private PMXFormat Read() {
+ format_ = new PMXFormat();
+ format_.meta_header = CreateMetaHeader();
+ format_.header = ReadHeader();
+ format_.vertex_list = ReadVertexList();
+ format_.face_vertex_list = ReadFaceVertexList();
+ format_.texture_list = ReadTextureList();
+ format_.material_list = ReadMaterialList();
+ format_.bone_list = ReadBoneList();
+ format_.morph_list = ReadMorphList();
+ format_.display_frame_list = ReadDisplayFrameList();
+ format_.rigidbody_list = ReadRigidbodyList();
+ format_.rigidbody_joint_list = ReadRigidbodyJointList();
+ return format_;
+ }
+
+ private PMXFormat.MetaHeader CreateMetaHeader() {
+ PMXFormat.MetaHeader result = new PMXFormat.MetaHeader();
+ result.path = file_path_;
+ result.name = Path.GetFileNameWithoutExtension(file_path_); // .pmdを抜かす
+ result.folder = Path.GetDirectoryName(file_path_); // PMDが格納されているフォルダ
+ return result;
+ }
+
+ private PMXFormat.Header ReadHeader() {
+ PMXFormat.Header result = new PMXFormat.Header();
+ result.magic = binary_reader_.ReadBytes(4);
+ if (Encoding.ASCII.GetString(result.magic) != "PMX ") {
+ throw new System.FormatException();
+ }
+ result.version = binary_reader_.ReadSingle();
+ binary_reader_.ReadByte(); // Fixed at 8 for PMX 2.0
+ result.encodeMethod = (PMXFormat.Header.StringCode)binary_reader_.ReadByte();
+ result.additionalUV = binary_reader_.ReadByte();
+ result.vertexIndexSize = (PMXFormat.Header.IndexSize)binary_reader_.ReadByte();
+ result.textureIndexSize = (PMXFormat.Header.IndexSize)binary_reader_.ReadByte();
+ result.materialIndexSize = (PMXFormat.Header.IndexSize)binary_reader_.ReadByte();
+ result.boneIndexSize = (PMXFormat.Header.IndexSize)binary_reader_.ReadByte();
+ result.morphIndexSize = (PMXFormat.Header.IndexSize)binary_reader_.ReadByte();
+ result.rigidbodyIndexSize = (PMXFormat.Header.IndexSize)binary_reader_.ReadByte();
+
+ string_code_ = result.encodeMethod;
+ result.model_name = ReadString();
+ result.model_english_name = ReadString();
+ result.comment = ReadString();
+ result.english_comment = ReadString();
+
+ return result;
+ }
+
+ private PMXFormat.VertexList ReadVertexList() {
+ PMXFormat.VertexList result = new PMXFormat.VertexList();
+ uint vert_count = binary_reader_.ReadUInt32();
+ result.vertex = new PMXFormat.Vertex[vert_count];
+ for (uint i = 0, i_max = (uint)result.vertex.Length; i < i_max; ++i) {
+ result.vertex[i] = ReadVertex();
+ }
+ return result;
+ }
+
+ private PMXFormat.Vertex ReadVertex() {
+ PMXFormat.Vertex result = new PMXFormat.Vertex();
+ result.pos = ReadSinglesToVector3(binary_reader_);
+ result.normal_vec = ReadSinglesToVector3(binary_reader_);
+ result.uv = ReadSinglesToVector2(binary_reader_);
+ result.add_uv = new Vector4[format_.header.additionalUV];
+ for (int i = 0; i < format_.header.additionalUV; i++) {
+ result.add_uv[i] = ReadSinglesToVector4(binary_reader_);
+ }
+ PMXFormat.Vertex.WeightMethod weight_method = (PMXFormat.Vertex.WeightMethod)binary_reader_.ReadByte();
+ switch(weight_method) {
+ case PMXFormat.Vertex.WeightMethod.BDEF1:
+ result.bone_weight = ReadBoneWeightBDEF1();
+ break;
+ case PMXFormat.Vertex.WeightMethod.BDEF2:
+ result.bone_weight = ReadBoneWeightBDEF2();
+ break;
+ case PMXFormat.Vertex.WeightMethod.BDEF4:
+ result.bone_weight = ReadBoneWeightBDEF4();
+ break;
+ case PMXFormat.Vertex.WeightMethod.SDEF:
+ result.bone_weight = ReadBoneWeightSDEF();
+ break;
+ case PMXFormat.Vertex.WeightMethod.QDEF:
+ result.bone_weight = ReadBoneWeightQDEF();
+ break;
+ default:
+ result.bone_weight = null;
+ throw new System.FormatException();
+ }
+ result.edge_magnification = binary_reader_.ReadSingle();
+ return result;
+ }
+
+ private PMXFormat.BoneWeight ReadBoneWeightBDEF1() {
+ PMXFormat.BDEF1 result = new PMXFormat.BDEF1();
+ result.bone1_ref = CastIntRead(binary_reader_, format_.header.boneIndexSize);
+ return result;
+ }
+ private PMXFormat.BoneWeight ReadBoneWeightBDEF2() {
+ PMXFormat.BDEF2 result = new PMXFormat.BDEF2();
+ result.bone1_ref = CastIntRead(binary_reader_, format_.header.boneIndexSize);
+ result.bone2_ref = CastIntRead(binary_reader_, format_.header.boneIndexSize);
+ result.bone1_weight = binary_reader_.ReadSingle();
+ return result;
+ }
+ private PMXFormat.BoneWeight ReadBoneWeightBDEF4() {
+ PMXFormat.BDEF4 result = new PMXFormat.BDEF4();
+ result.bone1_ref = CastIntRead(binary_reader_, format_.header.boneIndexSize);
+ result.bone2_ref = CastIntRead(binary_reader_, format_.header.boneIndexSize);
+ result.bone3_ref = CastIntRead(binary_reader_, format_.header.boneIndexSize);
+ result.bone4_ref = CastIntRead(binary_reader_, format_.header.boneIndexSize);
+ result.bone1_weight = binary_reader_.ReadSingle();
+ result.bone2_weight = binary_reader_.ReadSingle();
+ result.bone3_weight = binary_reader_.ReadSingle();
+ result.bone4_weight = binary_reader_.ReadSingle();
+ return result;
+ }
+ private PMXFormat.BoneWeight ReadBoneWeightSDEF() {
+ PMXFormat.SDEF result = new PMXFormat.SDEF();
+ result.bone1_ref = CastIntRead(binary_reader_, format_.header.boneIndexSize);
+ result.bone2_ref = CastIntRead(binary_reader_, format_.header.boneIndexSize);
+ result.bone1_weight = binary_reader_.ReadSingle();
+ result.c_value = ReadSinglesToVector3(binary_reader_);
+ result.r0_value = ReadSinglesToVector3(binary_reader_);
+ result.r1_value = ReadSinglesToVector3(binary_reader_);
+ return result;
+ }
+ private PMXFormat.BoneWeight ReadBoneWeightQDEF() {
+ PMXFormat.BDEF4 result = new PMXFormat.BDEF4();
+ result.bone1_ref = CastIntRead(binary_reader_, format_.header.boneIndexSize);
+ result.bone2_ref = CastIntRead(binary_reader_, format_.header.boneIndexSize);
+ result.bone3_ref = CastIntRead(binary_reader_, format_.header.boneIndexSize);
+ result.bone4_ref = CastIntRead(binary_reader_, format_.header.boneIndexSize);
+ result.bone1_weight = binary_reader_.ReadSingle();
+ result.bone2_weight = binary_reader_.ReadSingle();
+ result.bone3_weight = binary_reader_.ReadSingle();
+ result.bone4_weight = binary_reader_.ReadSingle();
+ return result;
+ }
+
+ private PMXFormat.FaceVertexList ReadFaceVertexList() {
+ PMXFormat.FaceVertexList result = new PMXFormat.FaceVertexList();
+ uint face_vert_count = binary_reader_.ReadUInt32();
+ result.face_vert_index = new uint[face_vert_count];
+ for (uint i = 0, i_max = (uint)result.face_vert_index.Length; i < i_max; ++i) {
+ result.face_vert_index[i] = CastIntRead(binary_reader_, format_.header.vertexIndexSize);
+ }
+ return result;
+ }
+
+ private PMXFormat.TextureList ReadTextureList() {
+ PMXFormat.TextureList result = new PMXFormat.TextureList();
+ uint texture_file_count = binary_reader_.ReadUInt32();
+ result.texture_file = new string[texture_file_count];
+ for (uint i = 0, i_max = (uint)result.texture_file.Length; i < i_max; ++i) {
+ result.texture_file[i] = ReadString();
+ //"./"開始なら削除する
+ if (('.' == result.texture_file[i][0]) && (1 == result.texture_file[i].IndexOfAny(new[]{'/', '\\'}, 1, 1))) {
+ result.texture_file[i] = result.texture_file[i].Substring(2);
+ }
+ }
+ return result;
+ }
+
+ private PMXFormat.MaterialList ReadMaterialList() {
+ PMXFormat.MaterialList result = new PMXFormat.MaterialList();
+ uint material_count = binary_reader_.ReadUInt32();
+ result.material = new PMXFormat.Material[material_count];
+ for (uint i = 0, i_max = (uint)result.material.Length; i < i_max; ++i) {
+ result.material[i] = ReadMaterial();
+ }
+ return result;
+ }
+
+ private PMXFormat.Material ReadMaterial() {
+ PMXFormat.Material result = new PMXFormat.Material();
+ result.name = ReadString();
+ result.english_name = ReadString();
+ result.diffuse_color = ReadSinglesToColor(binary_reader_); // dr, dg, db, da // 減衰色
+ result.specular_color = ReadSinglesToColor(binary_reader_, 1); // sr, sg, sb // 光沢色
+ result.specularity = binary_reader_.ReadSingle();
+ result.ambient_color = ReadSinglesToColor(binary_reader_, 1); // mr, mg, mb // 環境色(ambient)
+ result.flag = (PMXFormat.Material.Flag)binary_reader_.ReadByte();
+ result.edge_color = ReadSinglesToColor(binary_reader_); // r, g, b, a
+ result.edge_size = binary_reader_.ReadSingle();
+ result.usually_texture_index = CastIntRead(binary_reader_, format_.header.textureIndexSize);
+ result.sphere_texture_index = CastIntRead(binary_reader_, format_.header.textureIndexSize);
+ result.sphere_mode = (PMXFormat.Material.SphereMode)binary_reader_.ReadByte();
+ result.common_toon = binary_reader_.ReadByte();
+ PMXFormat.Header.IndexSize texture_index_size = ((result.common_toon == 0)? format_.header.textureIndexSize: PMXFormat.Header.IndexSize.Byte1);
+ result.toon_texture_index = CastIntRead(binary_reader_, texture_index_size);
+ result.memo = ReadString();
+ result.face_vert_count = binary_reader_.ReadUInt32(); // 面頂点数 // インデックスに変換する場合は、材質0から順に加算
+ return result;
+ }
+
+ private PMXFormat.BoneList ReadBoneList() {
+ PMXFormat.BoneList result = new PMXFormat.BoneList();
+ uint bone_count = binary_reader_.ReadUInt32();
+ result.bone = new PMXFormat.Bone[bone_count];
+ for (uint i = 0, i_max = (uint)result.bone.Length; i < i_max; ++i) {
+ result.bone[i] = ReadBone();
+ }
+ return result;
+ }
+
+ private PMXFormat.Bone ReadBone() {
+ PMXFormat.Bone result = new PMXFormat.Bone();
+ result.bone_name = ReadString();
+ result.bone_english_name = ReadString();
+ result.bone_position = ReadSinglesToVector3(binary_reader_);
+ result.parent_bone_index = CastIntRead(binary_reader_, format_.header.boneIndexSize);
+ result.transform_level = binary_reader_.ReadInt32();
+ result.bone_flag = (PMXFormat.Bone.Flag)binary_reader_.ReadUInt16();
+
+ if ((result.bone_flag & PMXFormat.Bone.Flag.Connection) == 0) {
+ // 座標オフセットで指定
+ result.position_offset = ReadSinglesToVector3(binary_reader_);
+ } else {
+ // ボーンで指定
+ result.connection_index = CastIntRead(binary_reader_, format_.header.boneIndexSize);
+ }
+ if ((result.bone_flag & (PMXFormat.Bone.Flag.AddRotation | PMXFormat.Bone.Flag.AddMove)) != 0) {
+ result.additional_parent_index = CastIntRead(binary_reader_, format_.header.boneIndexSize);
+ result.additional_rate = binary_reader_.ReadSingle();
+ }
+ if ((result.bone_flag & PMXFormat.Bone.Flag.FixedAxis) != 0) {
+ result.axis_vector = ReadSinglesToVector3(binary_reader_);
+ }
+ if ((result.bone_flag & PMXFormat.Bone.Flag.LocalAxis) != 0) {
+ result.x_axis_vector = ReadSinglesToVector3(binary_reader_);
+ result.z_axis_vector = ReadSinglesToVector3(binary_reader_);
+ }
+ if((result.bone_flag & PMXFormat.Bone.Flag.ExternalParentTransform) != 0) {
+ result.key_value = binary_reader_.ReadUInt32();
+ }
+ if((result.bone_flag & PMXFormat.Bone.Flag.IkFlag) != 0) {
+ result.ik_data = ReadIkData();
+ }
+ return result;
+ }
+
+ private PMXFormat.IK_Data ReadIkData() {
+ PMXFormat.IK_Data result = new PMXFormat.IK_Data();
+ result.ik_bone_index = CastIntRead(binary_reader_, format_.header.boneIndexSize);
+ result.iterations = binary_reader_.ReadUInt32();
+ result.limit_angle = binary_reader_.ReadSingle();
+ uint ik_link_count = binary_reader_.ReadUInt32();
+ result.ik_link = new PMXFormat.IK_Link[ik_link_count];
+ for (uint i = 0, i_max = (uint)result.ik_link.Length; i < i_max; ++i) {
+ result.ik_link[i] = ReadIkLink();
+ }
+ return result;
+ }
+
+ private PMXFormat.IK_Link ReadIkLink() {
+ PMXFormat.IK_Link result = new PMXFormat.IK_Link();
+ result.target_bone_index = CastIntRead(binary_reader_, format_.header.boneIndexSize);
+ result.angle_limit = binary_reader_.ReadByte();
+ if (result.angle_limit == 1) {
+ result.lower_limit = ReadSinglesToVector3(binary_reader_);
+ result.upper_limit = ReadSinglesToVector3(binary_reader_);
+ }
+ return result;
+ }
+
+ private PMXFormat.MorphList ReadMorphList() {
+ PMXFormat.MorphList result = new PMXFormat.MorphList();
+ uint morph_count = binary_reader_.ReadUInt32();
+ result.morph_data = new PMXFormat.MorphData[morph_count];
+ for (uint i = 0, i_max = (uint)result.morph_data.Length; i < i_max; ++i) {
+ result.morph_data[i] = ReadMorphData();
+ }
+ return result;
+ }
+
+ private PMXFormat.MorphData ReadMorphData() {
+ PMXFormat.MorphData result = new PMXFormat.MorphData();
+ result.morph_name = ReadString();
+ result.morph_english_name = ReadString();
+ result.handle_panel = (PMXFormat.MorphData.Panel)binary_reader_.ReadByte();
+ result.morph_type = (PMXFormat.MorphData.MorphType)binary_reader_.ReadByte();
+ uint morph_offset_count = binary_reader_.ReadUInt32();
+ result.morph_offset = new PMXFormat.MorphOffset[morph_offset_count];
+ for (uint i = 0, i_max = (uint)result.morph_offset.Length; i < i_max; ++i) {
+ switch(result.morph_type) {
+ case PMXFormat.MorphData.MorphType.Group:
+ case PMXFormat.MorphData.MorphType.Flip:
+ result.morph_offset[i] = ReadGroupMorphOffset();
+ break;
+ case PMXFormat.MorphData.MorphType.Vertex:
+ result.morph_offset[i] = ReadVertexMorphOffset();
+ break;
+ case PMXFormat.MorphData.MorphType.Bone:
+ result.morph_offset[i] = ReadBoneMorphOffset();
+ break;
+ case PMXFormat.MorphData.MorphType.Uv:
+ case PMXFormat.MorphData.MorphType.Adduv1:
+ case PMXFormat.MorphData.MorphType.Adduv2:
+ case PMXFormat.MorphData.MorphType.Adduv3:
+ case PMXFormat.MorphData.MorphType.Adduv4:
+ result.morph_offset[i] = ReadUVMorphOffset();
+ break;
+ case PMXFormat.MorphData.MorphType.Material:
+ result.morph_offset[i] = ReadMaterialMorphOffset();
+ break;
+ case PMXFormat.MorphData.MorphType.Impulse:
+ result.morph_offset[i] = ReadImpulseMorphOffset();
+ break;
+ default:
+ throw new System.FormatException();
+ }
+ }
+ return result;
+ }
+ private PMXFormat.MorphOffset ReadGroupMorphOffset() {
+ PMXFormat.GroupMorphOffset result = new PMXFormat.GroupMorphOffset();
+ result.morph_index = CastIntRead(binary_reader_, format_.header.morphIndexSize);
+ result.morph_rate = binary_reader_.ReadSingle();
+ return result;
+ }
+ private PMXFormat.MorphOffset ReadVertexMorphOffset() {
+ PMXFormat.VertexMorphOffset result = new PMXFormat.VertexMorphOffset();
+ result.vertex_index = CastIntRead(binary_reader_, format_.header.vertexIndexSize);
+ result.position_offset = ReadSinglesToVector3(binary_reader_);
+ return result;
+ }
+ private PMXFormat.MorphOffset ReadBoneMorphOffset() {
+ PMXFormat.BoneMorphOffset result = new PMXFormat.BoneMorphOffset();
+ result.bone_index = CastIntRead(binary_reader_, format_.header.boneIndexSize);
+ result.move_value = ReadSinglesToVector3(binary_reader_);
+ result.rotate_value = ReadSinglesToQuaternion(binary_reader_);
+ return result;
+ }
+ private PMXFormat.MorphOffset ReadUVMorphOffset() {
+ PMXFormat.UVMorphOffset result = new PMXFormat.UVMorphOffset();
+ result.vertex_index = CastIntRead(binary_reader_, format_.header.vertexIndexSize);
+ result.uv_offset = ReadSinglesToVector4(binary_reader_);
+ return result;
+ }
+ private PMXFormat.MorphOffset ReadMaterialMorphOffset() {
+ PMXFormat.MaterialMorphOffset result = new PMXFormat.MaterialMorphOffset();
+ result.material_index = CastIntRead(binary_reader_, format_.header.materialIndexSize);
+ result.offset_method = (PMXFormat.MaterialMorphOffset.OffsetMethod)binary_reader_.ReadByte();
+ result.diffuse = ReadSinglesToColor(binary_reader_);
+ result.specular = ReadSinglesToColor(binary_reader_, 1);
+ result.specularity = binary_reader_.ReadSingle();
+ result.ambient = ReadSinglesToColor(binary_reader_, 1);
+ result.edge_color = ReadSinglesToColor(binary_reader_);
+ result.edge_size = binary_reader_.ReadSingle();
+ result.texture_coefficient = ReadSinglesToColor(binary_reader_);
+ result.sphere_texture_coefficient = ReadSinglesToColor(binary_reader_);
+ result.toon_texture_coefficient = ReadSinglesToColor(binary_reader_);
+ return result;
+ }
+ private PMXFormat.MorphOffset ReadImpulseMorphOffset() {
+ PMXFormat.ImpulseMorphOffset result = new PMXFormat.ImpulseMorphOffset();
+ result.rigidbody_index = CastIntRead(binary_reader_, format_.header.morphIndexSize);
+ result.local_flag = binary_reader_.ReadByte();
+ result.move_velocity = ReadSinglesToVector3(binary_reader_);
+ result.rotation_torque = ReadSinglesToVector3(binary_reader_);
+ return result;
+ }
+
+ private PMXFormat.DisplayFrameList ReadDisplayFrameList() {
+ PMXFormat.DisplayFrameList result = new PMXFormat.DisplayFrameList();
+ uint display_frame_count = binary_reader_.ReadUInt32();
+ result.display_frame = new PMXFormat.DisplayFrame[display_frame_count];
+ for (uint i = 0, i_max = (uint)result.display_frame.Length; i < i_max; ++i) {
+ result.display_frame[i] = ReadDisplayFrame();
+ }
+ return result;
+ }
+
+
+ private PMXFormat.DisplayFrame ReadDisplayFrame() {
+ PMXFormat.DisplayFrame result = new PMXFormat.DisplayFrame();
+ result.display_name = ReadString();
+ result.display_english_name = ReadString();
+ result.special_frame_flag = binary_reader_.ReadByte();
+ uint display_element_count = binary_reader_.ReadUInt32();
+ result.display_element = new PMXFormat.DisplayElement[display_element_count];
+ for (uint i = 0, i_max = (uint)result.display_element.Length; i < i_max; ++i) {
+ result.display_element[i] = ReadDisplayElement();
+ }
+ return result;
+ }
+
+ private PMXFormat.DisplayElement ReadDisplayElement() {
+ PMXFormat.DisplayElement result = new PMXFormat.DisplayElement();
+ result.element_target = binary_reader_.ReadByte();
+ PMXFormat.Header.IndexSize element_target_index_size = ((result.element_target == 0) ? format_.header.boneIndexSize : format_.header.morphIndexSize);
+ result.element_target_index = CastIntRead(binary_reader_, element_target_index_size);
+ return result;
+ }
+
+ private PMXFormat.RigidbodyList ReadRigidbodyList() {
+ PMXFormat.RigidbodyList result = new PMXFormat.RigidbodyList();
+ uint rigidbody_count = binary_reader_.ReadUInt32();
+ result.rigidbody = new PMXFormat.Rigidbody[rigidbody_count];
+ for (uint i = 0, i_max = (uint)result.rigidbody.Length; i < i_max; ++i) {
+ result.rigidbody[i] = ReadRigidbody();
+ }
+ return result;
+ }
+
+ private PMXFormat.Rigidbody ReadRigidbody() {
+ PMXFormat.Rigidbody result = new PMXFormat.Rigidbody();
+ result.name = ReadString();
+ result.english_name = ReadString();
+ result.rel_bone_index = CastIntRead(binary_reader_, format_.header.boneIndexSize);
+ result.group_index = binary_reader_.ReadByte();
+ result.ignore_collision_group = binary_reader_.ReadUInt16();
+ result.shape_type = (PMXFormat.Rigidbody.ShapeType)binary_reader_.ReadByte();
+ result.shape_size = ReadSinglesToVector3(binary_reader_);
+ result.collider_position = ReadSinglesToVector3(binary_reader_);
+ result.collider_rotation = ReadSinglesToVector3(binary_reader_);
+ result.weight = binary_reader_.ReadSingle();
+ result.position_dim = binary_reader_.ReadSingle();
+ result.rotation_dim = binary_reader_.ReadSingle();
+ result.recoil = binary_reader_.ReadSingle();
+ result.friction = binary_reader_.ReadSingle();
+ result.operation_type = (PMXFormat.Rigidbody.OperationType)binary_reader_.ReadByte();
+ return result;
+ }
+
+ private PMXFormat.RigidbodyJointList ReadRigidbodyJointList() {
+ PMXFormat.RigidbodyJointList result = new PMXFormat.RigidbodyJointList();
+ uint joint_count = binary_reader_.ReadUInt32();
+ result.joint = new PMXFormat.Joint[joint_count];
+ for (uint i = 0, i_max = (uint)result.joint.Length; i < i_max; ++i) {
+ result.joint[i] = ReadJoint();
+ }
+ return result;
+ }
+
+ private PMXFormat.Joint ReadJoint() {
+ PMXFormat.Joint result = new PMXFormat.Joint();
+ result.name = ReadString();
+ result.english_name = ReadString();
+ result.operation_type = (PMXFormat.Joint.OperationType)binary_reader_.ReadByte();
+ switch (result.operation_type) {
+ case PMXFormat.Joint.OperationType.Spring6DOF:
+ result.rigidbody_a = CastIntRead(binary_reader_, format_.header.rigidbodyIndexSize);
+ result.rigidbody_b = CastIntRead(binary_reader_, format_.header.rigidbodyIndexSize);
+ result.position = ReadSinglesToVector3(binary_reader_);
+ result.rotation = ReadSinglesToVector3(binary_reader_);
+ result.constrain_pos_lower = ReadSinglesToVector3(binary_reader_);
+ result.constrain_pos_upper = ReadSinglesToVector3(binary_reader_);
+ result.constrain_rot_lower = ReadSinglesToVector3(binary_reader_);
+ result.constrain_rot_upper = ReadSinglesToVector3(binary_reader_);
+ result.spring_position = ReadSinglesToVector3(binary_reader_);
+ result.spring_rotation = ReadSinglesToVector3(binary_reader_);
+ break;
+ default:
+ //empty.
+ break;
+ }
+ return result;
+ }
+
+ private string ReadString()
+ {
+ string result;
+ int stringLength = binary_reader_.ReadInt32();
+ byte[] buf = binary_reader_.ReadBytes(stringLength);
+ switch (string_code_) {
+ case PMXFormat.Header.StringCode.Utf16le:
+ result = Encoding.UTF8.GetString(Encoding.Convert(Encoding.Unicode, Encoding.UTF8, buf));
+ break;
+ case PMXFormat.Header.StringCode.Utf8:
+ result = Encoding.UTF8.GetString(buf);
+ break;
+ default:
+ throw new System.InvalidOperationException();
+ }
+ return result;
+ }
+
+ private uint CastIntRead(BinaryReader bin, PMXFormat.Header.IndexSize index_size)
+ {
+ uint result = 0;
+ switch(index_size) {
+ case PMXFormat.Header.IndexSize.Byte1:
+ result = (uint)binary_reader_.ReadByte();
+ if (byte.MaxValue == result) {
+ result = uint.MaxValue;
+ }
+ break;
+ case PMXFormat.Header.IndexSize.Byte2:
+ result = (uint)binary_reader_.ReadUInt16();
+ if (ushort.MaxValue == result) {
+ result = uint.MaxValue;
+ }
+ break;
+ case PMXFormat.Header.IndexSize.Byte4:
+ result = binary_reader_.ReadUInt32();
+ break;
+ default:
+ throw new System.ArgumentOutOfRangeException();
+ }
+ return result;
+ }
+
+ private static Vector4 ReadSinglesToVector4(BinaryReader binary_reader_)
+ {
+ const int count = 4;
+ float[] result = new float[count];
+ for (int i = 0; i < count; i++)
+ {
+ result[i] = binary_reader_.ReadSingle();
+ if (float.IsNaN(result[i])) result[i] = 0.0f; //非数値なら回避
+ }
+ return new Vector4(result[0], result[1], result[2], result[3]);
+ }
+
+ private static Vector3 ReadSinglesToVector3(BinaryReader binary_reader_)
+ {
+ const int count = 3;
+ float[] result = new float[count];
+ for (int i = 0; i < count; i++)
+ {
+ result[i] = binary_reader_.ReadSingle();
+ if (float.IsNaN(result[i])) result[i] = 0.0f; //非数値なら回避
+ }
+ return new Vector3(result[0], result[1], result[2]);
+ }
+
+ private static Vector2 ReadSinglesToVector2(BinaryReader binary_reader_)
+ {
+ const int count = 2;
+ float[] result = new float[count];
+ for (int i = 0; i < count; i++)
+ {
+ result[i] = binary_reader_.ReadSingle();
+ if (float.IsNaN(result[i])) result[i] = 0.0f; //非数値なら回避
+ }
+ return new Vector2(result[0], result[1]);
+ }
+
+ private static Color ReadSinglesToColor(BinaryReader binary_reader_)
+ {
+ const int count = 4;
+ float[] result = new float[count];
+ for (int i = 0; i < count; i++)
+ {
+ result[i] = binary_reader_.ReadSingle();
+ }
+ return new Color(result[0], result[1], result[2], result[3]);
+ }
+
+ private static Color ReadSinglesToColor(BinaryReader binary_reader_, float fix_alpha)
+ {
+ const int count = 3;
+ float[] result = new float[count];
+ for (int i = 0; i < count; i++)
+ {
+ result[i] = binary_reader_.ReadSingle();
+ }
+ return new Color(result[0], result[1], result[2], fix_alpha);
+ }
+
+ private Quaternion ReadSinglesToQuaternion(BinaryReader binary_reader_)
+ {
+ const int count = 4;
+ float[] result = new float[count];
+ for (int i = 0; i < count; i++)
+ {
+ result[i] = binary_reader_.ReadSingle();
+ if (float.IsNaN(result[i])) result[i] = 0.0f; //非数値なら回避
+ }
+ return new Quaternion(result[0], result[1], result[2], result[3]);
+ }
+
+ string file_path_;
+ BinaryReader binary_reader_;
+ PMXFormat format_;
+ PMXFormat.Header.StringCode string_code_;
+}
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/Editor/MMDLoader/Private/VMDConverter.cs b/Assets/Scripts/3rd/mmd-for-unity-master/Editor/MMDLoader/Private/VMDConverter.cs
new file mode 100644
index 000000000..00093c1a1
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/Editor/MMDLoader/Private/VMDConverter.cs
@@ -0,0 +1,559 @@
+using UnityEngine;
+using UnityEditor;
+using System.Collections.Generic;
+using System.Linq;
+using MMD.VMD;
+
+namespace MMD
+{
+ public class VMDConverter
+ {
+ ///
+ /// AnimationClipを作成する
+ ///
+ /// 内部形式データ
+ /// 使用するPMDのGameObject
+ /// 補完曲線品質
+ public static AnimationClip CreateAnimationClip(VMDFormat format, GameObject assign_pmd, int interpolationQuality) {
+ VMDConverter converter = new VMDConverter();
+ return converter.CreateAnimationClip_(format, assign_pmd, interpolationQuality);
+ }
+
+ ///
+ /// デフォルトコンストラクタ
+ ///
+ ///
+ /// ユーザーに依るインスタンス作成を禁止する
+ ///
+ private VMDConverter() {}
+
+ // クリップをアニメーションに登録する
+ private AnimationClip CreateAnimationClip_(MMD.VMD.VMDFormat format, GameObject assign_pmd, int interpolationQuality)
+ {
+ //スケール設定
+ scale_ = 1.0f;
+ if (!assign_pmd)
+ {
+ return null;
+ }
+ MMDEngine engine = assign_pmd.GetComponent();
+ if (!engine)
+ {
+ return null;
+ }
+ scale_ = engine.scale;
+
+ //Animation anim = assign_pmd.GetComponent();
+
+ // クリップの作成
+ AnimationClip clip = new AnimationClip();
+ clip.name = assign_pmd.name + "_" + format.name;
+
+ Dictionary bone_path = new Dictionary();
+ Dictionary gameobj = new Dictionary();
+ GetGameObjects(gameobj, assign_pmd); // 親ボーン下のGameObjectを取得
+ FullSearchBonePath(assign_pmd.transform, bone_path);
+ FullEntryBoneAnimation(format, clip, bone_path, gameobj, interpolationQuality);
+
+ CreateKeysForSkin(format, clip); // 表情の追加
+
+ return clip;
+ }
+
+ // ベジェハンドルを取得する
+ // 0~127の値を 0f~1fとして返す
+ static Vector2 GetBezierHandle(byte[] interpolation, int type, int ab)
+ {
+ // 0=X, 1=Y, 2=Z, 3=R
+ // abはa?かb?のどちらを使いたいか
+ Vector2 bezierHandle = new Vector2((float)interpolation[ab*8+type], (float)interpolation[ab*8+4+type]);
+ return bezierHandle/127f;
+ }
+ // p0:(0f,0f),p3:(1f,1f)のベジェ曲線上の点を取得する
+ // tは0~1の範囲
+ static Vector2 SampleBezier(Vector2 bezierHandleA, Vector2 bezierHandleB, float t)
+ {
+ Vector2 p0 = Vector2.zero;
+ Vector2 p1 = bezierHandleA;
+ Vector2 p2 = bezierHandleB;
+ Vector2 p3 = new Vector2(1f,1f);
+
+ Vector2 q0 = Vector2.Lerp(p0, p1, t);
+ Vector2 q1 = Vector2.Lerp(p1, p2, t);
+ Vector2 q2 = Vector2.Lerp(p2, p3, t);
+
+ Vector2 r0 = Vector2.Lerp(q0, q1, t);
+ Vector2 r1 = Vector2.Lerp(q1, q2, t);
+
+ Vector2 s0 = Vector2.Lerp(r0, r1, t);
+ return s0;
+ }
+ // 補間曲線が線形補間と等価か
+ static bool IsLinear(byte[] interpolation, int type)
+ {
+ byte ax=interpolation[0*8+type];
+ byte ay=interpolation[0*8+4+type];
+ byte bx=interpolation[1*8+type];
+ byte by=interpolation[1*8+4+type];
+ return (ax == ay) && (bx == by);
+ }
+ // 補間曲線の近似のために追加するキーフレームを含めたキーフレーム数を取得する
+ int GetKeyframeCount(List mlist, int type, int interpolationQuality)
+ {
+ int count = 0;
+ for(int i = 0; i < mlist.Count; i++)
+ {
+ if(i>0 && !IsLinear(mlist[i].interpolation, type))
+ {
+ count += interpolationQuality;//Interpolation Keyframes
+ }
+ else
+ {
+ count += 1;//Keyframe
+ }
+ }
+ return count;
+ }
+ //キーフレームが1つの時、ダミーキーフレームを追加する
+ void AddDummyKeyframe(ref Keyframe[] keyframes)
+ {
+ if(keyframes.Length==1)
+ {
+ Keyframe[] newKeyframes=new Keyframe[2];
+ newKeyframes[0]=keyframes[0];
+ newKeyframes[1]=keyframes[0];
+ newKeyframes[1].time+=0.001f/60f;//1[ms]
+ newKeyframes[0].outTangent=0f;
+ newKeyframes[1].inTangent=0f;
+ keyframes=newKeyframes;
+ }
+ }
+ // 任意の型のvalueを持つキーフレーム
+ abstract class CustomKeyframe
+ {
+ public CustomKeyframe(float time,Type value)
+ {
+ this.time=time;
+ this.value=value;
+ }
+ public float time{ get; set; }
+ public Type value{ get; set; }
+ }
+ // float型のvalueを持つキーフレーム
+ class FloatKeyframe:CustomKeyframe
+ {
+ public FloatKeyframe(float time,float value):base(time,value)
+ {
+ }
+ // 線形補間
+ public static FloatKeyframe Lerp(FloatKeyframe from, FloatKeyframe to,Vector2 t)
+ {
+ return new FloatKeyframe(
+ Mathf.Lerp(from.time,to.time,t.x),
+ Mathf.Lerp(from.value,to.value,t.y)
+ );
+ }
+ // ベジェを線形補間で近似したキーフレームを追加する
+ public static void AddBezierKeyframes(byte[] interpolation, int type,
+ FloatKeyframe prev_keyframe,FloatKeyframe cur_keyframe, int interpolationQuality,
+ ref FloatKeyframe[] keyframes,ref int index)
+ {
+ if(prev_keyframe==null || IsLinear(interpolation,type))
+ {
+ keyframes[index++]=cur_keyframe;
+ }
+ else
+ {
+ Vector2 bezierHandleA=GetBezierHandle(interpolation,type,0);
+ Vector2 bezierHandleB=GetBezierHandle(interpolation,type,1);
+ int sampleCount = interpolationQuality;
+ for(int j = 0; j < sampleCount; j++)
+ {
+ float t = (j+1)/(float)sampleCount;
+ Vector2 sample = SampleBezier(bezierHandleA,bezierHandleB,t);
+ keyframes[index++] = FloatKeyframe.Lerp(prev_keyframe,cur_keyframe,sample);
+ }
+ }
+ }
+ }
+ // Quaternion型のvalueを持つキーフレーム
+ class QuaternionKeyframe:CustomKeyframe
+ {
+ public QuaternionKeyframe(float time,Quaternion value):base(time,value)
+ {
+ }
+ // 線形補間
+ public static QuaternionKeyframe Lerp(QuaternionKeyframe from, QuaternionKeyframe to,Vector2 t)
+ {
+ return new QuaternionKeyframe(
+ Mathf.Lerp(from.time,to.time,t.x),
+ Quaternion.Slerp(from.value,to.value,t.y)
+ );
+ }
+ // ベジェを線形補間で近似したキーフレームを追加する
+ public static void AddBezierKeyframes(byte[] interpolation, int type,
+ QuaternionKeyframe prev_keyframe,QuaternionKeyframe cur_keyframe, int interpolationQuality,
+ ref QuaternionKeyframe[] keyframes,ref int index)
+ {
+ if(prev_keyframe==null || IsLinear(interpolation,type))
+ {
+ keyframes[index++]=cur_keyframe;
+ }
+ else
+ {
+ Vector2 bezierHandleA=GetBezierHandle(interpolation,type,0);
+ Vector2 bezierHandleB=GetBezierHandle(interpolation,type,1);
+ int sampleCount = interpolationQuality;
+ for(int j = 0; j < sampleCount; j++)
+ {
+ float t=(j+1)/(float)sampleCount;
+ Vector2 sample = SampleBezier(bezierHandleA,bezierHandleB,t);
+ keyframes[index++] = QuaternionKeyframe.Lerp(prev_keyframe,cur_keyframe,sample);
+ }
+ }
+ }
+
+ }
+
+ //移動の線形補間用tangentを求める
+ float GetLinearTangentForPosition(Keyframe from_keyframe,Keyframe to_keyframe)
+ {
+ return (to_keyframe.value-from_keyframe.value)/(to_keyframe.time-from_keyframe.time);
+ }
+ //-359~+359度の範囲を等価な0~359度へ変換する。
+ float Mod360(float angle)
+ {
+ //剰余演算の代わりに加算にする
+ return (angle<0)?(angle+360f):(angle);
+ }
+ //回転の線形補間用tangentを求める
+ float GetLinearTangentForRotation(Keyframe from_keyframe,Keyframe to_keyframe)
+ {
+ float tv=Mod360(to_keyframe.value);
+ float fv=Mod360(from_keyframe.value);
+ float delta_value=Mod360(tv-fv);
+ //180度を越える場合は逆回転
+ if(delta_value<180f)
+ {
+ return delta_value/(to_keyframe.time-from_keyframe.time);
+ }
+ else
+ {
+ return (delta_value-360f)/(to_keyframe.time-from_keyframe.time);
+ }
+ }
+ //アニメーションエディタでBothLinearを選択したときの値
+ private const int TangentModeBothLinear=21;
+
+ //UnityのKeyframeに変換する(回転用)
+ void ToAnimationCurveForRotation(QuaternionKeyframe[] custom_keys,
+ out AnimationCurve curve_x, out AnimationCurve curve_y, out AnimationCurve curve_z)
+ {
+ Keyframe[] rx_keys = new Keyframe[custom_keys.Length];
+ Keyframe[] ry_keys = new Keyframe[custom_keys.Length];
+ Keyframe[] rz_keys = new Keyframe[custom_keys.Length];
+
+ for (int i = 0; i < custom_keys.Length; i++)
+ {
+ //オイラー角を取り出す
+ Vector3 eulerAngles=custom_keys[i].value.eulerAngles;
+ rx_keys[i]=new Keyframe(custom_keys[i].time,eulerAngles.x);
+ ry_keys[i]=new Keyframe(custom_keys[i].time,eulerAngles.y);
+ rz_keys[i]=new Keyframe(custom_keys[i].time,eulerAngles.z);
+ //線形補間する
+ if (i > 0)
+ {
+ float tx = GetLinearTangentForRotation(rx_keys[i - 1], rx_keys[i]);
+ float ty = GetLinearTangentForRotation(ry_keys[i - 1], ry_keys[i]);
+ float tz = GetLinearTangentForRotation(rz_keys[i - 1], rz_keys[i]);
+ rx_keys[i - 1].outTangent = tx;
+ ry_keys[i - 1].outTangent = ty;
+ rz_keys[i - 1].outTangent = tz;
+ rx_keys[i].inTangent = tx;
+ ry_keys[i].inTangent = ty;
+ rz_keys[i].inTangent = tz;
+ }
+ }
+ AddDummyKeyframe(ref rx_keys);
+ AddDummyKeyframe(ref ry_keys);
+ AddDummyKeyframe(ref rz_keys);
+
+ curve_x = new AnimationCurve(rx_keys);
+ curve_y = new AnimationCurve(ry_keys);
+ curve_z = new AnimationCurve(rz_keys);
+
+ for (int i = 0; i < curve_x.keys.Length; i++)
+ {
+ AnimationUtility.SetKeyLeftTangentMode(curve_x, i, AnimationUtility.TangentMode.ClampedAuto);
+ AnimationUtility.SetKeyRightTangentMode(curve_x, i, AnimationUtility.TangentMode.ClampedAuto);
+ }
+ for (int i = 0; i < curve_y.keys.Length; i++)
+ {
+ AnimationUtility.SetKeyLeftTangentMode(curve_y, i, AnimationUtility.TangentMode.ClampedAuto);
+ AnimationUtility.SetKeyRightTangentMode(curve_y, i, AnimationUtility.TangentMode.ClampedAuto);
+ }
+ for (int i = 0; i < curve_z.keys.Length; i++)
+ {
+ AnimationUtility.SetKeyLeftTangentMode(curve_z, i, AnimationUtility.TangentMode.ClampedAuto);
+ AnimationUtility.SetKeyRightTangentMode(curve_z, i, AnimationUtility.TangentMode.ClampedAuto);
+ }
+ }
+
+
+ // あるボーンに含まれるキーフレを抽出
+ // これは回転のみ
+ void CreateKeysForRotation(MMD.VMD.VMDFormat format, AnimationClip clip, string current_bone, string bone_path, int interpolationQuality)
+ {
+ try
+ {
+ const float tick_time = 1.0f / VMD_FPS;
+
+ List mlist = format.motion_list.motion[current_bone];
+ int keyframeCount = GetKeyframeCount(mlist, 3, interpolationQuality);
+
+ QuaternionKeyframe[] r_keys = new QuaternionKeyframe[keyframeCount];
+ QuaternionKeyframe r_prev_key=null;
+ int ir=0;
+ for (int i = 0; i < mlist.Count; i++)
+ {
+ float tick = mlist[i].frame_no * tick_time;
+
+ Quaternion rotation=mlist[i].rotation;
+ QuaternionKeyframe r_cur_key=new QuaternionKeyframe(tick,rotation);
+ QuaternionKeyframe.AddBezierKeyframes(mlist[i].interpolation,3,r_prev_key,r_cur_key,interpolationQuality,ref r_keys,ref ir);
+ r_prev_key=r_cur_key;
+ }
+
+ AnimationCurve curve_x = null;
+ AnimationCurve curve_y = null;
+ AnimationCurve curve_z = null;
+ ToAnimationCurveForRotation(r_keys, out curve_x, out curve_y, out curve_z);
+ // ここで回転オイラー角をセット(補間はクォータニオン)
+ AnimationUtility.SetEditorCurve(clip, EditorCurveBinding.FloatCurve(bone_path, typeof(Transform), "localEulerAngles.x"), curve_x);
+ AnimationUtility.SetEditorCurve(clip, EditorCurveBinding.FloatCurve(bone_path, typeof(Transform), "localEulerAngles.y"), curve_y);
+ AnimationUtility.SetEditorCurve(clip, EditorCurveBinding.FloatCurve(bone_path, typeof(Transform), "localEulerAngles.z"), curve_z);
+ }
+ catch (KeyNotFoundException)
+ {
+ Debug.LogError("互換性のないボーンが読み込まれました:" + bone_path);
+ }
+ }
+ //UnityのKeyframeに変換する(移動用)
+ AnimationCurve ToAnimationCurveForLocation(FloatKeyframe[] custom_keys)
+ {
+ Keyframe[] keys=new Keyframe[custom_keys.Length];
+ for(int i = 0; i < custom_keys.Length; i++)
+ {
+ keys[i]=new Keyframe(custom_keys[i].time,custom_keys[i].value);
+ //線形補間する
+ if (i > 0)
+ {
+ float t = GetLinearTangentForPosition(keys[i - 1], keys[i]);
+ keys[i - 1].outTangent = t;
+ keys[i].inTangent = t;
+ }
+ }
+ AddDummyKeyframe(ref keys);
+
+ AnimationCurve retCurve = new AnimationCurve(keys);
+ for (int i = 0; i < retCurve.keys.Length; i++)
+ {
+ AnimationUtility.SetKeyLeftTangentMode(retCurve, i, AnimationUtility.TangentMode.ClampedAuto);
+ AnimationUtility.SetKeyRightTangentMode(retCurve, i, AnimationUtility.TangentMode.ClampedAuto);
+ }
+
+ return retCurve;
+ }
+ // 移動のみの抽出
+ void CreateKeysForLocation(MMD.VMD.VMDFormat format, AnimationClip clip, string current_bone, string bone_path, int interpolationQuality, GameObject current_obj = null)
+ {
+ try
+ {
+ const float tick_time = 1.0f / VMD_FPS;
+
+ Vector3 default_position = Vector3.zero;
+ if(current_obj != null)
+ default_position = current_obj.transform.localPosition;
+
+ List mlist = format.motion_list.motion[current_bone];
+
+ int keyframeCountX = GetKeyframeCount(mlist, 0, interpolationQuality);
+ int keyframeCountY = GetKeyframeCount(mlist, 1, interpolationQuality);
+ int keyframeCountZ = GetKeyframeCount(mlist, 2, interpolationQuality);
+
+ FloatKeyframe[] lx_keys = new FloatKeyframe[keyframeCountX];
+ FloatKeyframe[] ly_keys = new FloatKeyframe[keyframeCountY];
+ FloatKeyframe[] lz_keys = new FloatKeyframe[keyframeCountZ];
+
+ FloatKeyframe lx_prev_key=null;
+ FloatKeyframe ly_prev_key=null;
+ FloatKeyframe lz_prev_key=null;
+ int ix=0;
+ int iy=0;
+ int iz=0;
+ for (int i = 0; i < mlist.Count; i++)
+ {
+ float tick = mlist[i].frame_no * tick_time;
+
+ FloatKeyframe lx_cur_key=new FloatKeyframe(tick,mlist[i].location.x * scale_ + default_position.x);
+ FloatKeyframe ly_cur_key=new FloatKeyframe(tick,mlist[i].location.y * scale_ + default_position.y);
+ FloatKeyframe lz_cur_key=new FloatKeyframe(tick,mlist[i].location.z * scale_ + default_position.z);
+
+ // 各軸別々に補間が付いてる
+ FloatKeyframe.AddBezierKeyframes(mlist[i].interpolation,0,lx_prev_key,lx_cur_key,interpolationQuality,ref lx_keys,ref ix);
+ FloatKeyframe.AddBezierKeyframes(mlist[i].interpolation,1,ly_prev_key,ly_cur_key,interpolationQuality,ref ly_keys,ref iy);
+ FloatKeyframe.AddBezierKeyframes(mlist[i].interpolation,2,lz_prev_key,lz_cur_key,interpolationQuality,ref lz_keys,ref iz);
+
+ lx_prev_key=lx_cur_key;
+ ly_prev_key=ly_cur_key;
+ lz_prev_key=lz_cur_key;
+ }
+
+ // 回転ボーンの場合はデータが入ってないはず
+ if (mlist.Count != 0)
+ {
+ AnimationCurve curve_x = ToAnimationCurveForLocation(lx_keys);
+ AnimationCurve curve_y = ToAnimationCurveForLocation(ly_keys);
+ AnimationCurve curve_z = ToAnimationCurveForLocation(lz_keys);
+
+ AnimationUtility.SetEditorCurve(clip,EditorCurveBinding.FloatCurve(bone_path,typeof(Transform),"m_LocalPosition.x"),curve_x);
+ AnimationUtility.SetEditorCurve(clip,EditorCurveBinding.FloatCurve(bone_path,typeof(Transform),"m_LocalPosition.y"),curve_y);
+ AnimationUtility.SetEditorCurve(clip,EditorCurveBinding.FloatCurve(bone_path,typeof(Transform),"m_LocalPosition.z"),curve_z);
+ }
+ }
+ catch (KeyNotFoundException)
+ {
+ Debug.LogError("互換性のないボーンが読み込まれました:" + current_bone);
+ }
+ }
+
+ void CreateKeysForSkin(MMD.VMD.VMDFormat format, AnimationClip clip)
+ {
+ const float tick_time = 1f / 30f;
+
+ // 全ての表情に打たれているキーフレームを探索
+ List s;
+
+ foreach (var skin in format.skin_list.skin)
+ {
+ s = skin.Value;
+ Keyframe[] keyframe = new Keyframe[skin.Value.Count];
+
+ // キーフレームの登録を行う
+ for (int i = 0; i < skin.Value.Count; i++)
+ {
+ keyframe[i] = new Keyframe(s[i].frame_no * tick_time, s[i].weight);
+ //線形補間する
+ if (i > 0)
+ {
+ float t = GetLinearTangentForPosition(keyframe[i - 1], keyframe[i]);
+ keyframe[i - 1].outTangent = t;
+ keyframe[i].inTangent = t;
+ }
+ }
+ AddDummyKeyframe(ref keyframe);
+
+ // Z軸移動にキーフレームを打つ
+ AnimationCurve curve = new AnimationCurve(keyframe);
+ for (int i = 0; i < curve.keys.Length; i++)
+ {
+ AnimationUtility.SetKeyLeftTangentMode(curve, i, AnimationUtility.TangentMode.Linear);
+ AnimationUtility.SetKeyRightTangentMode(curve, i, AnimationUtility.TangentMode.Linear);
+ }
+
+ AnimationUtility.SetEditorCurve(clip,EditorCurveBinding.FloatCurve("Expression/" + skin.Key,typeof(Transform),"m_LocalPosition.z"),curve);
+ }
+ }
+
+ // ボーンのパスを取得する
+ string GetBonePath(Transform transform)
+ {
+ string buf;
+ if (transform.parent == null)
+ return transform.name;
+ else
+ buf = GetBonePath(transform.parent);
+ return buf + "/" + transform.name;
+ }
+
+ // ボーンの子供を再帰的に走査
+ void FullSearchBonePath(Transform transform, Dictionary dic)
+ {
+ int count = transform.childCount;
+ for (int i = 0; i < count; i++)
+ {
+ Transform t = transform.GetChild(i);
+ FullSearchBonePath(t, dic);
+ }
+
+ // オブジェクト名が足されてしまうので抜く
+ string buf = "";
+ string[] spl = GetBonePath(transform).Split('/');
+ for (int i = 1; i < spl.Length-1; i++)
+ buf += spl[i] + "/";
+ buf += spl[spl.Length-1];
+
+ try
+ {
+ dic.Add(transform.name, buf);
+ }
+ catch (System.ArgumentException arg)
+ {
+ Debug.Log(arg.Message);
+ Debug.Log("An element with the same key already exists in the dictionary. -> " + transform.name);
+ }
+
+ // dicには全てのボーンの名前, ボーンのパス名が入る
+ }
+
+ // 無駄なカーブを登録してるけどどうするか
+ void FullEntryBoneAnimation(MMD.VMD.VMDFormat format, AnimationClip clip, Dictionary dic, Dictionary obj, int interpolationQuality)
+ {
+ foreach (KeyValuePair> p in format.motion_list.motion)
+ {
+ // 互いに名前の一致する場合にRigidbodyが存在するか調べたい
+ GameObject current_obj = null;
+ string bonePath = null;
+ // keyはtransformの名前, valueはパス
+ if (dic.TryGetValue(p.Key, out bonePath)){
+ current_obj = obj[p.Key];
+
+ // Rigidbodyがある場合はキーフレの登録を無視する
+ var rigid = current_obj.GetComponent();
+ if (rigid != null && !rigid.isKinematic)
+ {
+ continue;
+ }
+ }
+
+ // キーフレの登録
+ //CreateKeysForLocation(format, clip, p.Key, bonePath, interpolationQuality, current_obj);
+ CreateKeysForRotation(format, clip, p.Key, bonePath, interpolationQuality);
+ }
+ }
+
+ // とりあえず再帰的に全てのゲームオブジェクトを取得する
+ void GetGameObjects(Dictionary obj, GameObject assign_pmd)
+ {
+ for (int i = 0; i < assign_pmd.transform.childCount; i++)
+ {
+ var transf = assign_pmd.transform.GetChild(i);
+ try
+ {
+ obj.Add(transf.name, transf.gameObject);
+ }
+ catch (System.ArgumentException arg)
+ {
+ Debug.Log(arg.Message);
+ Debug.Log("An element with the same key already exists in the dictionary. -> " + transf.name);
+ }
+
+ if (transf == null) continue; // ストッパー
+ GetGameObjects(obj, transf.gameObject);
+ }
+ }
+
+ private float scale_ = 1.0f;
+ private const float VMD_FPS = 30.0f;
+ }
+}
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/Editor/MMDLoader/Private/VMDLoaderScript.cs b/Assets/Scripts/3rd/mmd-for-unity-master/Editor/MMDLoader/Private/VMDLoaderScript.cs
new file mode 100644
index 000000000..99b1c3dad
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/Editor/MMDLoader/Private/VMDLoaderScript.cs
@@ -0,0 +1,326 @@
+using UnityEngine;
+using UnityEditor;
+using System.Collections;
+using System.Collections.Generic;
+using System;
+using System.IO;
+using System.Text;
+using MMD.VMD;
+
+public class VMDLoaderScript {
+
+ ///
+ /// VMDファイルのヘッダー取得
+ ///
+ /// VMDファイルのパス
+ /// ヘッダー
+ public static VMDFormat.Header GetHeader(string file_path) {
+ VMDLoaderScript loader = new VMDLoaderScript();
+ return loader.GetHeader_(file_path);
+ }
+
+ ///
+ /// VMDファイルのインポート
+ ///
+ /// VMDファイルのパス
+ /// 内部形式データ
+ public static VMDFormat Import(string file_path) {
+ VMDLoaderScript loader = new VMDLoaderScript();
+ return loader.Import_(file_path);
+ }
+
+ ///
+ /// デフォルトコンストラクタ
+ ///
+ ///
+ /// ユーザーに依るインスタンス作成を禁止する
+ ///
+ private VMDLoaderScript() {}
+
+ private VMDFormat.Header GetHeader_(string file_path) {
+ VMDFormat.Header result;
+ using (FileStream stream = new FileStream(file_path, FileMode.Open, FileAccess.Read))
+ using (BinaryReader bin = new BinaryReader(stream)) {
+ file_path_ = null;
+ binary_reader_ = bin;
+ result = ReadHeader();
+ }
+ return result;
+ }
+
+ private VMDFormat Import_(string file_path) {
+ using (FileStream stream = new FileStream(file_path, FileMode.Open, FileAccess.Read))
+ using (BinaryReader bin = new BinaryReader(stream)) {
+ file_path_ = file_path;
+ binary_reader_ = bin;
+ Read();
+ }
+ return format_;
+ }
+
+ private VMDFormat Read() {
+ format_ = new VMDFormat();
+ EntryPathes();
+
+ // 読み込み失敗した場合はだいたいデータがない
+ // 失敗しても読み込み続けることがあるので例外でキャッチして残りはnullにしておく
+ int read_count = 0;
+ try {
+ format_.header = ReadHeader(); read_count++;
+ format_.motion_list = ReadMotionList(); read_count++;
+ format_.skin_list = ReadSkinList(); read_count++;
+ format_.camera_list = ReadCameraList(); read_count++;
+ format_.light_list = ReadLightList(); read_count++;
+ format_.self_shadow_list = ReadSelfShadowList(); read_count++;
+ } catch (EndOfStreamException e) {
+ Debug.Log(e.Message);
+ if (read_count <= 0)
+ format_.header = null;
+ if (read_count <= 1 || format_.motion_list.motion_count <= 0)
+ format_.motion_list = null;
+ if (read_count <= 2 || format_.skin_list.skin_count <= 0)
+ format_.skin_list = null;
+ if (read_count <= 3 || format_.camera_list.camera_count <= 0)
+ format_.camera_list = null;
+ if (read_count <= 4 || format_.light_list.light_count <= 0)
+ format_.light_list = null;
+ if (read_count <= 5 || format_.self_shadow_list.self_shadow_count <= 0)
+ format_.self_shadow_list = null;
+ }
+ return format_;
+ }
+
+ private void EntryPathes() {
+ format_.path = file_path_;
+ format_.name = Path.GetFileNameWithoutExtension(file_path_); // .vmdを抜かす
+ format_.folder = Path.GetDirectoryName(file_path_); // VMDが格納されているフォルダ
+ }
+
+ public VMDFormat.Header ReadHeader() {
+ VMDFormat.Header result = new VMDFormat.Header();
+ result.vmd_header = ConvertByteToString(binary_reader_.ReadBytes(30), "");
+ result.vmd_model_name = ConvertByteToString(binary_reader_.ReadBytes(20), "");
+ return result;
+ }
+
+ private VMDFormat.MotionList ReadMotionList() {
+ VMDFormat.MotionList result = new VMDFormat.MotionList();
+ result.motion_count = binary_reader_.ReadUInt32();
+ result.motion = new Dictionary>();
+
+ // 一度バッファに貯めてソートする
+ VMDFormat.Motion[] buf = new VMDFormat.Motion[result.motion_count];
+ for (int i = 0; i < result.motion_count; i++) {
+ buf[i] = ReadMotion();
+ }
+ Array.Sort(buf, (x,y)=>((int)x.frame_no - (int)y.frame_no));
+
+ try
+ {
+ // モーションの数だけnewされないよね?
+ for (int i = 0; i < result.motion_count; i++)
+ {
+ result.motion.Add(buf[i].bone_name, new List());
+ }
+ }
+ catch { }
+
+ // dictionaryにどんどん登録
+ for (int i = 0; i < result.motion_count; i++)
+ {
+ result.motion[buf[i].bone_name].Add(buf[i]);
+ }
+
+ return result;
+ }
+
+ private VMDFormat.Motion ReadMotion() {
+ VMDFormat.Motion result = new VMDFormat.Motion();
+ result.bone_name = ConvertByteToString(binary_reader_.ReadBytes(15), "");
+ result.frame_no = binary_reader_.ReadUInt32();
+ result.location = ReadSinglesToVector3(binary_reader_);
+ result.rotation = ReadSinglesToQuaternion(binary_reader_);
+ result.interpolation = binary_reader_.ReadBytes(64);
+ return result;
+ }
+
+ ///
+ /// 表情リスト
+ ///
+ private VMDFormat.SkinList ReadSkinList() {
+ VMDFormat.SkinList result = new VMDFormat.SkinList();
+ result.skin_count = binary_reader_.ReadUInt32();
+ result.skin = new Dictionary>();
+
+ // 一度バッファに貯めてソートする
+ VMDFormat.SkinData[] buf = new VMDFormat.SkinData[result.skin_count];
+ for (int i = 0; i < result.skin_count; i++) {
+ buf[i] = ReadSkinData();
+ }
+ Array.Sort(buf, (x,y)=>((int)x.frame_no - (int)y.frame_no));
+
+ try
+ {
+ // 全てのモーションを探索し、利用されているボーンを特定する
+ for (int i = 0; i < result.skin_count; i++)
+ {
+ result.skin.Add(buf[i].skin_name, new List());
+ }
+ }
+ catch
+ {
+ //重複している場合はこの処理に入る
+ }
+
+ // 辞書に登録する作業
+ for (int i = 0; i < result.skin_count; i++)
+ {
+ result.skin[buf[i].skin_name].Add(buf[i]);
+ }
+
+ return result;
+ }
+
+ private VMDFormat.SkinData ReadSkinData() {
+ VMDFormat.SkinData result = new VMDFormat.SkinData();
+ result.skin_name = ConvertByteToString(binary_reader_.ReadBytes(15), "");
+ result.frame_no = binary_reader_.ReadUInt32();
+ result.weight = binary_reader_.ReadSingle();
+ return result;
+ }
+
+ private VMDFormat.CameraList ReadCameraList() {
+ VMDFormat.CameraList result = new VMDFormat.CameraList();
+ result.camera_count = binary_reader_.ReadUInt32();
+ result.camera = new VMDFormat.CameraData[result.camera_count];
+ for (int i = 0; i < result.camera_count; i++) {
+ result.camera[i] = ReadCameraData();
+ }
+ Array.Sort(result.camera, (x,y)=>((int)x.frame_no - (int)y.frame_no));
+ return result;
+ }
+
+ private VMDFormat.CameraData ReadCameraData() {
+ VMDFormat.CameraData result = new VMDFormat.CameraData();
+ result.frame_no = binary_reader_.ReadUInt32();
+ result.length = binary_reader_.ReadSingle();
+ result.location = ReadSinglesToVector3(binary_reader_);
+ result.rotation = ReadSinglesToVector3(binary_reader_);
+ result.interpolation = binary_reader_.ReadBytes(24);
+ result.viewing_angle = binary_reader_.ReadUInt32();
+ result.perspective = binary_reader_.ReadByte();
+ return result;
+ }
+
+ private VMDFormat.LightList ReadLightList() {
+ VMDFormat.LightList result = new VMDFormat.LightList();
+ result.light_count = binary_reader_.ReadUInt32();
+ result.light = new VMDFormat.LightData[result.light_count];
+ for (int i = 0; i < result.light_count; i++) {
+ result.light[i] = ReadLightData();
+ }
+
+ Array.Sort(result.light, (x,y)=>((int)x.frame_no - (int)y.frame_no));
+ return result;
+ }
+
+ private VMDFormat.LightData ReadLightData() {
+ VMDFormat.LightData result = new VMDFormat.LightData();
+ result.frame_no = binary_reader_.ReadUInt32();
+ result.rgb = ReadSinglesToColor(binary_reader_, 1);
+ result.location = ReadSinglesToVector3(binary_reader_);
+ return result;
+ }
+
+ private VMDFormat.SelfShadowList ReadSelfShadowList() {
+ VMDFormat.SelfShadowList result = new VMDFormat.SelfShadowList();
+ result.self_shadow_count = binary_reader_.ReadUInt32();
+ result.self_shadow = new VMDFormat.SelfShadowData[result.self_shadow_count];
+ for (int i = 0; i < result.self_shadow_count; i++) {
+ result.self_shadow[i] = ReadSelfShadowData();
+ }
+
+ Array.Sort(result.self_shadow, (x,y)=>((int)x.frame_no - (int)y.frame_no));
+ return result;
+ }
+
+ private VMDFormat.SelfShadowData ReadSelfShadowData() {
+ VMDFormat.SelfShadowData result = new VMDFormat.SelfShadowData();
+ result.frame_no = binary_reader_.ReadUInt32();
+ result.mode = binary_reader_.ReadByte();
+ result.distance = binary_reader_.ReadSingle();
+ return result;
+ }
+
+ // ShiftJISからUTF-8に変換してstringで返す
+ private static string ConvertByteToString(byte[] bytes, string line_feed_code = null)
+ {
+ // パディングの消去, 文字を詰める
+ if (bytes[0] == 0) return "";
+ int count;
+ for (count = 0; count < bytes.Length; count++) if (bytes[count] == 0) break;
+ byte[] buf = new byte[count]; // NULL文字を含めるとうまく行かない
+ for (int i = 0; i < count; i++) {
+ buf[i] = bytes[i];
+ }
+
+ buf = Encoding.Convert(Encoding.GetEncoding(932), Encoding.UTF8, buf);
+
+ string result = Encoding.UTF8.GetString(buf);
+ if (null != line_feed_code) {
+ //改行コード統一(もしくは除去)
+ result = result.Replace("\r\n", "\n").Replace('\r', '\n').Replace("\n", line_feed_code);
+ }
+ return result;
+ }
+
+ private static Vector3 ReadSinglesToVector3(BinaryReader bin)
+ {
+ const int count = 3;
+ float[] result = new float[count];
+ for (int i = 0; i < count; i++)
+ {
+ result[i] = bin.ReadSingle();
+ if (float.IsNaN(result[i])) result[i] = 0.0f; //非数値なら回避
+ }
+ return new Vector3(result[0], result[1], result[2]);
+ }
+
+ private static Color ReadSinglesToColor(BinaryReader bin)
+ {
+ const int count = 4;
+ float[] result = new float[count];
+ for (int i = 0; i < count; i++)
+ {
+ result[i] = bin.ReadSingle();
+ }
+ return new Color(result[0], result[1], result[2], result[3]);
+ }
+
+ private static Color ReadSinglesToColor(BinaryReader bin, float fix_alpha)
+ {
+ const int count = 3;
+ float[] result = new float[count];
+ for (int i = 0; i < count; i++)
+ {
+ result[i] = bin.ReadSingle();
+ }
+ return new Color(result[0], result[1], result[2], fix_alpha);
+ }
+
+ private static Quaternion ReadSinglesToQuaternion(BinaryReader bin)
+ {
+ const int count = 4;
+ float[] result = new float[count];
+ for (int i = 0; i < count; i++)
+ {
+ result[i] = bin.ReadSingle();
+ if (float.IsNaN(result[i])) result[i] = 0.0f; //非数値なら回避
+ }
+ return new Quaternion(result[0], result[1], result[2], result[3]);
+ }
+
+ string file_path_;
+ BinaryReader binary_reader_;
+ VMDFormat format_;
+}
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/Editor/MMDLoader/VMDLoaderWindow.cs b/Assets/Scripts/3rd/mmd-for-unity-master/Editor/MMDLoader/VMDLoaderWindow.cs
new file mode 100644
index 000000000..c038c0783
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/Editor/MMDLoader/VMDLoaderWindow.cs
@@ -0,0 +1,52 @@
+using UnityEngine;
+using System.Collections;
+using UnityEditor;
+
+public class VMDLoaderWindow : EditorWindow {
+ Object vmdFile;
+ GameObject pmdPrefab;
+ MMD.VMDImportConfig vmd_config;
+
+ [MenuItem ("MMD for Unity/VMD Loader")]
+ static void Init() {
+ var window = (VMDLoaderWindow)EditorWindow.GetWindow(true, "VMDLoader");
+ window.Show();
+ }
+
+ void OnEnable()
+ {
+ // デフォルトコンフィグ
+ vmdFile = null;
+ pmdPrefab = null;
+ vmd_config = MMD.Config.LoadAndCreate().vmd_config.Clone();
+ }
+
+ void OnGUI() {
+ // GUIの有効化
+ GUI.enabled = !EditorApplication.isPlaying;
+
+ // GUI描画
+ pmdPrefab = (GameObject)EditorGUILayout.ObjectField("PMD Prefab", pmdPrefab, typeof(GameObject), false);
+ vmdFile = EditorGUILayout.ObjectField("VMD File", vmdFile, typeof(Object), false);
+ vmd_config.OnGUIFunction();
+
+ {
+ bool gui_enabled_old = GUI.enabled;
+ GUI.enabled = !EditorApplication.isPlaying && (pmdPrefab != null) && (vmdFile != null);
+ if (GUILayout.Button("Convert")) {
+ LoadMotion();
+ vmdFile = null;
+ }
+ GUI.enabled = gui_enabled_old;
+ }
+ }
+
+ void LoadMotion() {
+ string file_path = AssetDatabase.GetAssetPath(vmdFile);
+ MMD.MotionAgent motion_agent = new MMD.MotionAgent(file_path);
+ motion_agent.CreateAnimationClip(pmdPrefab
+ , vmd_config.createAnimationFile
+ , vmd_config.interpolationQuality
+ );
+ }
+}
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/Editor/MorphManagerEditor.cs b/Assets/Scripts/3rd/mmd-for-unity-master/Editor/MorphManagerEditor.cs
new file mode 100644
index 000000000..ae6f261e3
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/Editor/MorphManagerEditor.cs
@@ -0,0 +1,123 @@
+using UnityEngine;
+using UnityEditor;
+using System.Collections.Generic;
+using System.Linq;
+
+///
+/// 表情用Inspector拡張
+///
+[CustomEditor(typeof(MorphManager))]
+public sealed class MorphManagerEditor : Editor
+{
+ ///
+ /// スタティックコンストラクタ
+ ///
+ static MorphManagerEditor()
+ {
+ panel_displays_ = new bool[System.Enum.GetValues(typeof(MorphManager.PanelType)).Length];
+ for (int i = 0, i_max = panel_displays_.Length; i < i_max; ++i) {
+ panel_displays_[i] = true;
+ }
+ }
+
+ ///
+ /// 初回処理
+ ///
+ public void Awake()
+ {
+ MorphManager self = (MorphManager)target;
+
+ children_ = new Transform[System.Enum.GetValues(typeof(MorphManager.PanelType)).Length][];
+ //子登録
+ for (int i = 0, i_max = children_.Length; i < i_max; ++i) {
+ children_[i] = self.vertex_morph.script.Where(x=>x.panel == (MorphManager.PanelType)i)
+ .Select(x=>x.transform)
+ .Concat(self.uv_morph.SelectMany(x=>x.script)
+ .Where(x=>x.panel == (MorphManager.PanelType)i)
+ .Select(x=>x.transform)
+ )
+ .Concat(self.material_morph.script.Where(x=>x.panel == (MorphManager.PanelType)i)
+ .Select(x=>x.transform)
+ )
+ .Concat(self.bone_morph.script.Where(x=>x.panel == (MorphManager.PanelType)i)
+ .Select(x=>x.transform)
+ )
+ .Concat(self.group_morph.script.Where(x=>x.panel == (MorphManager.PanelType)i)
+ .Select(x=>x.transform)
+ )
+ .ToArray();
+ }
+ }
+
+ ///
+ /// Inspector描画
+ ///
+ public override void OnInspectorGUI()
+ {
+ bool is_dirty = false;
+
+ is_dirty = OnInspectorGUIforPanelList() || is_dirty;
+
+ if (is_dirty) {
+ //更新が有ったなら
+ //Inspector更新
+ EditorUtility.SetDirty(target);
+ }
+ }
+
+ ///
+ /// パネルリストの為のInspector描画
+ ///
+ /// 更新が有ったか(true:更新有り, false:未更新)
+ private bool OnInspectorGUIforPanelList()
+ {
+ bool is_update = false;
+
+ for (int i = 0, i_max = children_.Length; i < i_max; ++i) {
+ if (MorphManager.PanelType.Base == (MorphManager.PanelType)i) {
+ //Baseだったらスキップ
+ continue;
+ }
+
+ //パネルツリータイトル
+ string panel_name = ((MMDSkinsScript.SkinType)i).ToString();
+ panel_displays_[i] = EditorGUILayout.Foldout(panel_displays_[i], panel_name);
+ //パネルツリー内部
+ if (panel_displays_[i]) {
+ //このパネルを表示するなら
+ ++EditorGUI.indentLevel;
+ EditorGUILayout.BeginVertical();
+ {
+ //モーフオブジェクト走査
+ foreach (Transform child in children_[i]) {
+ float value = child.localPosition.z;
+ value = EditorGUILayout.Slider(child.name, value, 0.0f, 1.0f);
+ if (child.localPosition.z != value) {
+ //変更が掛かったなら
+ //Undo登録
+#if !UNITY_4_2 //4.3以降
+ Undo.RecordObject(child, "Morph Change");
+#else
+ Undo.RegisterUndo(child, "Morph Change");
+#endif
+ //Z位置更新
+ Vector3 position = child.localPosition;
+ position.z = value;
+ child.localPosition = position;
+ //改変モーフオブジェクトのInspector更新
+ EditorUtility.SetDirty(child.transform);
+
+ is_update = true;
+ }
+ }
+ }
+ EditorGUILayout.EndVertical();
+ --EditorGUI.indentLevel;
+ }
+ }
+ return is_update;
+ }
+
+ private static bool[] panel_displays_; //パネルの表示
+ private Transform[][] children_; //パネル別子モーフオブジェクト
+}
diff --git a/Assets/Scripts/3rd/mmd-for-unity-master/Editor/PhysicsManagerEditor.cs b/Assets/Scripts/3rd/mmd-for-unity-master/Editor/PhysicsManagerEditor.cs
new file mode 100644
index 000000000..d3b1e5e5b
--- /dev/null
+++ b/Assets/Scripts/3rd/mmd-for-unity-master/Editor/PhysicsManagerEditor.cs
@@ -0,0 +1,93 @@
+using UnityEngine;
+using UnityEditor;
+using System.Collections.Generic;
+using System.Linq;
+
+///
+/// 物理演算用Inspector拡張
+///
+[CustomEditor(typeof(PhysicsManager))]
+public sealed class PhysicsManagerEditor : Editor
+{
+ ///
+ /// 初回処理
+ ///
+ public void Awake()
+ {
+ PhysicsManager self = (PhysicsManager)target;
+ if (null != self.connect_bone_list) {
+ joint_list_ = self.connect_bone_list.Where(x=>(null != x.joint))
+ .Select(x=>x.joint.GetComponent())
+ .ToArray();
+ } else {
+ joint_list_ = null;
+ }
+ }
+
+ ///