Compare commits
30 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1a896a85fe | |||
| ccfd244efd | |||
| 086e61cfc2 | |||
| 2d36b4247f | |||
| 6b78b68229 | |||
| d4764e304f | |||
| 3dba350fc2 | |||
| 7f1955e57a | |||
| d600885302 | |||
| 8a2ffed689 | |||
| d31408663b | |||
| dbd841c3a0 | |||
| c8a86e9081 | |||
| b0d2ffc974 | |||
| 8fa250943a | |||
| e633c83fe0 | |||
| 5f58de3185 | |||
| 79158576cf | |||
| 0bea75fcd0 | |||
| b6c7f163da | |||
| 404865dca1 | |||
| 581cac7941 | |||
| 107da72dee | |||
| 5956672127 | |||
|
|
bea3d4a804 | ||
| bb7ed2d6dc | |||
| 984e9188c1 | |||
| 90fa689bce | |||
| 11dca464d9 | |||
| 607cedd782 |
@@ -135,4 +135,4 @@ MonoBehaviour:
|
||||
m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
version: 9
|
||||
version: 10
|
||||
|
||||
@@ -12,7 +12,7 @@ MonoBehaviour:
|
||||
m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
version: 9
|
||||
version: 10
|
||||
--- !u!21 &2100000
|
||||
Material:
|
||||
serializedVersion: 8
|
||||
|
||||
@@ -135,4 +135,4 @@ MonoBehaviour:
|
||||
m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
version: 9
|
||||
version: 10
|
||||
|
||||
@@ -12,7 +12,7 @@ MonoBehaviour:
|
||||
m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
version: 9
|
||||
version: 10
|
||||
--- !u!21 &2100000
|
||||
Material:
|
||||
serializedVersion: 8
|
||||
|
||||
@@ -12,7 +12,7 @@ MonoBehaviour:
|
||||
m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
version: 9
|
||||
version: 10
|
||||
--- !u!21 &2100000
|
||||
Material:
|
||||
serializedVersion: 8
|
||||
|
||||
@@ -12,7 +12,7 @@ MonoBehaviour:
|
||||
m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
version: 9
|
||||
version: 10
|
||||
--- !u!21 &2100000
|
||||
Material:
|
||||
serializedVersion: 8
|
||||
|
||||
@@ -135,4 +135,4 @@ MonoBehaviour:
|
||||
m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
version: 9
|
||||
version: 10
|
||||
|
||||
@@ -135,4 +135,4 @@ MonoBehaviour:
|
||||
m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
version: 9
|
||||
version: 10
|
||||
|
||||
@@ -135,4 +135,4 @@ MonoBehaviour:
|
||||
m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
version: 9
|
||||
version: 10
|
||||
|
||||
@@ -135,4 +135,4 @@ MonoBehaviour:
|
||||
m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
version: 9
|
||||
version: 10
|
||||
|
||||
@@ -12,7 +12,7 @@ MonoBehaviour:
|
||||
m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
version: 9
|
||||
version: 10
|
||||
--- !u!21 &2100000
|
||||
Material:
|
||||
serializedVersion: 8
|
||||
|
||||
@@ -135,4 +135,4 @@ MonoBehaviour:
|
||||
m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
version: 9
|
||||
version: 10
|
||||
|
||||
@@ -135,4 +135,4 @@ MonoBehaviour:
|
||||
m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
version: 9
|
||||
version: 10
|
||||
|
||||
@@ -135,4 +135,4 @@ MonoBehaviour:
|
||||
m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
version: 9
|
||||
version: 10
|
||||
|
||||
@@ -12,7 +12,7 @@ MonoBehaviour:
|
||||
m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
version: 9
|
||||
version: 10
|
||||
--- !u!21 &2100000
|
||||
Material:
|
||||
serializedVersion: 8
|
||||
|
||||
@@ -12,7 +12,7 @@ MonoBehaviour:
|
||||
m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
version: 9
|
||||
version: 10
|
||||
--- !u!21 &2100000
|
||||
Material:
|
||||
serializedVersion: 8
|
||||
|
||||
@@ -135,4 +135,4 @@ MonoBehaviour:
|
||||
m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
version: 9
|
||||
version: 10
|
||||
|
||||
@@ -12,7 +12,7 @@ MonoBehaviour:
|
||||
m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
version: 9
|
||||
version: 10
|
||||
--- !u!21 &2100000
|
||||
Material:
|
||||
serializedVersion: 8
|
||||
|
||||
@@ -135,4 +135,4 @@ MonoBehaviour:
|
||||
m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
version: 9
|
||||
version: 10
|
||||
|
||||
@@ -12,7 +12,7 @@ MonoBehaviour:
|
||||
m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
version: 9
|
||||
version: 10
|
||||
--- !u!21 &2100000
|
||||
Material:
|
||||
serializedVersion: 8
|
||||
|
||||
@@ -135,4 +135,4 @@ MonoBehaviour:
|
||||
m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
version: 9
|
||||
version: 10
|
||||
|
||||
@@ -12,7 +12,7 @@ MonoBehaviour:
|
||||
m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
version: 9
|
||||
version: 10
|
||||
--- !u!21 &2100000
|
||||
Material:
|
||||
serializedVersion: 8
|
||||
|
||||
@@ -12,7 +12,7 @@ MonoBehaviour:
|
||||
m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
version: 9
|
||||
version: 10
|
||||
--- !u!21 &2100000
|
||||
Material:
|
||||
serializedVersion: 8
|
||||
|
||||
@@ -12,7 +12,7 @@ MonoBehaviour:
|
||||
m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
version: 9
|
||||
version: 10
|
||||
--- !u!21 &2100000
|
||||
Material:
|
||||
serializedVersion: 8
|
||||
|
||||
@@ -135,4 +135,4 @@ MonoBehaviour:
|
||||
m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
version: 9
|
||||
version: 10
|
||||
|
||||
@@ -12,7 +12,7 @@ MonoBehaviour:
|
||||
m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
version: 9
|
||||
version: 10
|
||||
--- !u!21 &2100000
|
||||
Material:
|
||||
serializedVersion: 8
|
||||
|
||||
@@ -12,7 +12,7 @@ MonoBehaviour:
|
||||
m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
version: 9
|
||||
version: 10
|
||||
--- !u!21 &2100000
|
||||
Material:
|
||||
serializedVersion: 8
|
||||
|
||||
@@ -135,4 +135,4 @@ MonoBehaviour:
|
||||
m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
version: 9
|
||||
version: 10
|
||||
|
||||
9
Assets/Forklift.meta
Normal file
9
Assets/Forklift.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d021ef5fee0ee7e4da9c1106079101c4
|
||||
folderAsset: yes
|
||||
timeCreated: 1461022388
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
120
Assets/Forklift/Forklift.prefab
Normal file
120
Assets/Forklift/Forklift.prefab
Normal file
@@ -0,0 +1,120 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!1 &149852
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 436614}
|
||||
m_Layer: 0
|
||||
m_Name: Forklift
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &436614
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 149852}
|
||||
serializedVersion: 2
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 1.4617047, y: -1.3774343, z: -0.33242655}
|
||||
m_LocalScale: {x: 0.59559834, y: 0.59559846, z: 0.59559846}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children:
|
||||
- {fileID: 412728}
|
||||
m_Father: {fileID: 0}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!1 &195560
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 412728}
|
||||
- component: {fileID: 3398296}
|
||||
- component: {fileID: 2386208}
|
||||
m_Layer: 0
|
||||
m_Name: Forklift
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &412728
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 195560}
|
||||
serializedVersion: 2
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 436614}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!33 &3398296
|
||||
MeshFilter:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 195560}
|
||||
m_Mesh: {fileID: 4300000, guid: 5c636ad013889f74593ac396fce71eb6, type: 3}
|
||||
--- !u!23 &2386208
|
||||
MeshRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 195560}
|
||||
m_Enabled: 1
|
||||
m_CastShadows: 1
|
||||
m_ReceiveShadows: 1
|
||||
m_DynamicOccludee: 1
|
||||
m_StaticShadowCaster: 0
|
||||
m_MotionVectors: 1
|
||||
m_LightProbeUsage: 1
|
||||
m_ReflectionProbeUsage: 1
|
||||
m_RayTracingMode: 2
|
||||
m_RayTraceProcedural: 0
|
||||
m_RayTracingAccelStructBuildFlagsOverride: 0
|
||||
m_RayTracingAccelStructBuildFlags: 1
|
||||
m_SmallMeshCulling: 1
|
||||
m_RenderingLayerMask: 1
|
||||
m_RendererPriority: 0
|
||||
m_Materials:
|
||||
- {fileID: 2100000, guid: 285784d850f0c4b41b9b343a2a049df5, type: 2}
|
||||
m_StaticBatchInfo:
|
||||
firstSubMesh: 0
|
||||
subMeshCount: 0
|
||||
m_StaticBatchRoot: {fileID: 0}
|
||||
m_ProbeAnchor: {fileID: 0}
|
||||
m_LightProbeVolumeOverride: {fileID: 0}
|
||||
m_ScaleInLightmap: 1
|
||||
m_ReceiveGI: 1
|
||||
m_PreserveUVs: 0
|
||||
m_IgnoreNormalsForChartDetection: 0
|
||||
m_ImportantGI: 0
|
||||
m_StitchLightmapSeams: 1
|
||||
m_SelectedEditorRenderState: 3
|
||||
m_MinimumChartSize: 4
|
||||
m_AutoUVMaxDistance: 0.5
|
||||
m_AutoUVMaxAngle: 89
|
||||
m_LightmapParameters: {fileID: 0}
|
||||
m_SortingLayerID: 0
|
||||
m_SortingLayer: 0
|
||||
m_SortingOrder: 0
|
||||
m_AdditionalVertexStreams: {fileID: 0}
|
||||
15
Assets/Forklift/Forklift.prefab.meta
Normal file
15
Assets/Forklift/Forklift.prefab.meta
Normal file
@@ -0,0 +1,15 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e655f3e9a2337db428013f9166de8906
|
||||
timeCreated: 1461022445
|
||||
licenseType: Store
|
||||
NativeFormatImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 60960
|
||||
packageName: Forklift
|
||||
packageVersion: 1.0
|
||||
assetPath: Assets/Forklift/Forklift.prefab
|
||||
uploadId: 113592
|
||||
9
Assets/Forklift/Material.meta
Normal file
9
Assets/Forklift/Material.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0e4006629f6c79547a2762b18c8a2d04
|
||||
folderAsset: yes
|
||||
timeCreated: 1461022432
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
142
Assets/Forklift/Material/Forklift.mat
Normal file
142
Assets/Forklift/Material/Forklift.mat
Normal file
@@ -0,0 +1,142 @@
|
||||
%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: Forklift
|
||||
m_Shader: {fileID: 4800000, guid: 933532a4fcc9baf4fa0491de14d08ed7, type: 3}
|
||||
m_Parent: {fileID: 0}
|
||||
m_ModifiedSerializedProperties: 0
|
||||
m_ValidKeywords:
|
||||
- _EMISSION
|
||||
- _METALLICSPECGLOSSMAP
|
||||
- _NORMALMAP
|
||||
m_InvalidKeywords: []
|
||||
m_LightmapFlags: 7
|
||||
m_EnableInstancingVariants: 0
|
||||
m_DoubleSidedGI: 0
|
||||
m_CustomRenderQueue: -1
|
||||
stringTagMap:
|
||||
RenderType: Opaque
|
||||
disabledShaderPasses:
|
||||
- MOTIONVECTORS
|
||||
m_LockedProperties:
|
||||
m_SavedProperties:
|
||||
serializedVersion: 3
|
||||
m_TexEnvs:
|
||||
- _BaseMap:
|
||||
m_Texture: {fileID: 2800000, guid: e3ac8151dd071124d836f4db513bfd9e, type: 3}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _BumpMap:
|
||||
m_Texture: {fileID: 2800000, guid: ee094282bf92bad478f1aa73778505a5, type: 3}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailAlbedoMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailMask:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailNormalMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _EmissionMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _MainTex:
|
||||
m_Texture: {fileID: 2800000, guid: e3ac8151dd071124d836f4db513bfd9e, type: 3}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _MetallicGlossMap:
|
||||
m_Texture: {fileID: 2800000, guid: 12e9c1ba7abb52e4381e6ddebf256b2a, type: 3}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _OcclusionMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _ParallaxMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _SpecGlossMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- unity_Lightmaps:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- unity_LightmapsInd:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- unity_ShadowMasks:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
m_Ints: []
|
||||
m_Floats:
|
||||
- _AddPrecomputedVelocity: 0
|
||||
- _AlphaClip: 0
|
||||
- _AlphaToMask: 0
|
||||
- _Blend: 0
|
||||
- _BlendModePreserveSpecular: 1
|
||||
- _BumpScale: 1
|
||||
- _ClearCoatMask: 0
|
||||
- _ClearCoatSmoothness: 0
|
||||
- _Cull: 2
|
||||
- _Cutoff: 0.5
|
||||
- _DetailAlbedoMapScale: 1
|
||||
- _DetailNormalMapScale: 1
|
||||
- _DstBlend: 0
|
||||
- _DstBlendAlpha: 0
|
||||
- _EnvironmentReflections: 1
|
||||
- _GlossMapScale: 1
|
||||
- _Glossiness: 0.5
|
||||
- _GlossyReflections: 1
|
||||
- _Metallic: 0
|
||||
- _Mode: 0
|
||||
- _OcclusionStrength: 1
|
||||
- _Parallax: 0.02
|
||||
- _QueueOffset: 0
|
||||
- _ReceiveShadows: 1
|
||||
- _Smoothness: 0.5
|
||||
- _SmoothnessTextureChannel: 0
|
||||
- _SpecularHighlights: 1
|
||||
- _SrcBlend: 1
|
||||
- _SrcBlendAlpha: 1
|
||||
- _Surface: 0
|
||||
- _UVSec: 0
|
||||
- _WorkflowMode: 1
|
||||
- _XRMotionVectorsPass: 1
|
||||
- _ZWrite: 1
|
||||
m_Colors:
|
||||
- _BaseColor: {r: 1, g: 1, b: 1, a: 1}
|
||||
- _Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
|
||||
- _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1}
|
||||
m_BuildTextureStacks: []
|
||||
m_AllowLocking: 1
|
||||
--- !u!114 &5962928480989632590
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 11
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 0}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
version: 10
|
||||
15
Assets/Forklift/Material/Forklift.mat.meta
Normal file
15
Assets/Forklift/Material/Forklift.mat.meta
Normal file
@@ -0,0 +1,15 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 285784d850f0c4b41b9b343a2a049df5
|
||||
timeCreated: 1461022133
|
||||
licenseType: Store
|
||||
NativeFormatImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 60960
|
||||
packageName: Forklift
|
||||
packageVersion: 1.0
|
||||
assetPath: Assets/Forklift/Material/Forklift.mat
|
||||
uploadId: 113592
|
||||
9
Assets/Forklift/Model.meta
Normal file
9
Assets/Forklift/Model.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9f4b9f7c9bd2b894bb91492a51fffd95
|
||||
folderAsset: yes
|
||||
timeCreated: 1461022441
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
14
Assets/Forklift/Model/Forklift.mtl
Normal file
14
Assets/Forklift/Model/Forklift.mtl
Normal file
@@ -0,0 +1,14 @@
|
||||
# 3ds Max Wavefront OBJ Exporter v0.97b - (c)2007 guruware
|
||||
# File Created: 19.04.2016 01:37:06
|
||||
|
||||
newmtl Material__25
|
||||
Ns 0.0000
|
||||
Ni 1.5000
|
||||
d 1.0000
|
||||
Tr 0.0000
|
||||
Tf 1.0000 1.0000 1.0000
|
||||
illum 2
|
||||
Ka 0.5880 0.5880 0.5880
|
||||
Kd 0.5880 0.5880 0.5880
|
||||
Ks 0.0000 0.0000 0.0000
|
||||
Ke 0.0000 0.0000 0.0000
|
||||
15
Assets/Forklift/Model/Forklift.mtl.meta
Normal file
15
Assets/Forklift/Model/Forklift.mtl.meta
Normal file
@@ -0,0 +1,15 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b5c3c35867a2b8c42a1ebfdba9526f31
|
||||
timeCreated: 1461022630
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 60960
|
||||
packageName: Forklift
|
||||
packageVersion: 1.0
|
||||
assetPath: Assets/Forklift/Model/Forklift.mtl
|
||||
uploadId: 113592
|
||||
6260
Assets/Forklift/Model/Forklift.obj
Normal file
6260
Assets/Forklift/Model/Forklift.obj
Normal file
File diff suppressed because it is too large
Load Diff
135
Assets/Forklift/Model/Forklift.obj.meta
Normal file
135
Assets/Forklift/Model/Forklift.obj.meta
Normal file
@@ -0,0 +1,135 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5c636ad013889f74593ac396fce71eb6
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 60960
|
||||
packageName: Forklift
|
||||
packageVersion: 1.0
|
||||
assetPath: Assets/Forklift/Model/Forklift.obj
|
||||
uploadId: 113592
|
||||
ModelImporter:
|
||||
serializedVersion: 22200
|
||||
internalIDToNameTable:
|
||||
- first:
|
||||
1: 100000
|
||||
second: //RootNode
|
||||
- first:
|
||||
1: 100002
|
||||
second: Object028
|
||||
- first:
|
||||
4: 400000
|
||||
second: //RootNode
|
||||
- first:
|
||||
4: 400002
|
||||
second: Object028
|
||||
- first:
|
||||
23: 2300000
|
||||
second: Object028
|
||||
- first:
|
||||
33: 3300000
|
||||
second: Object028
|
||||
- first:
|
||||
43: 4300000
|
||||
second: Object028
|
||||
externalObjects: {}
|
||||
materials:
|
||||
materialImportMode: 1
|
||||
materialName: 0
|
||||
materialSearch: 1
|
||||
materialLocation: 0
|
||||
animations:
|
||||
legacyGenerateAnimations: 4
|
||||
bakeSimulation: 0
|
||||
resampleCurves: 1
|
||||
optimizeGameObjects: 0
|
||||
removeConstantScaleCurves: 0
|
||||
motionNodeName:
|
||||
animationImportErrors:
|
||||
animationImportWarnings:
|
||||
animationRetargetingWarnings:
|
||||
animationDoRetargetingWarnings: 0
|
||||
importAnimatedCustomProperties: 0
|
||||
importConstraints: 0
|
||||
animationCompression: 1
|
||||
animationRotationError: 0.5
|
||||
animationPositionError: 0.5
|
||||
animationScaleError: 0.5
|
||||
animationWrapMode: 0
|
||||
extraExposedTransformPaths: []
|
||||
extraUserProperties: []
|
||||
clipAnimations: []
|
||||
isReadable: 1
|
||||
meshes:
|
||||
lODScreenPercentages: []
|
||||
globalScale: 0.05955983
|
||||
meshCompression: 0
|
||||
addColliders: 0
|
||||
useSRGBMaterialColor: 1
|
||||
sortHierarchyByName: 1
|
||||
importPhysicalCameras: 0
|
||||
importVisibility: 0
|
||||
importBlendShapes: 1
|
||||
importCameras: 0
|
||||
importLights: 0
|
||||
nodeNameCollisionStrategy: 0
|
||||
fileIdsGeneration: 1
|
||||
swapUVChannels: 0
|
||||
generateSecondaryUV: 0
|
||||
useFileUnits: 1
|
||||
keepQuads: 0
|
||||
weldVertices: 1
|
||||
bakeAxisConversion: 0
|
||||
preserveHierarchy: 0
|
||||
skinWeightsMode: 0
|
||||
maxBonesPerVertex: 4
|
||||
minBoneWeight: 0.001
|
||||
optimizeBones: 1
|
||||
meshOptimizationFlags: -1
|
||||
indexFormat: 1
|
||||
secondaryUVAngleDistortion: 8
|
||||
secondaryUVAreaDistortion: 15.000001
|
||||
secondaryUVHardAngle: 88
|
||||
secondaryUVMarginMethod: 0
|
||||
secondaryUVMinLightmapResolution: 40
|
||||
secondaryUVMinObjectScale: 1
|
||||
secondaryUVPackMargin: 4
|
||||
useFileScale: 1
|
||||
strictVertexDataChecks: 0
|
||||
tangentSpace:
|
||||
normalSmoothAngle: 60
|
||||
normalImportMode: 0
|
||||
tangentImportMode: 3
|
||||
normalCalculationMode: 0
|
||||
legacyComputeAllNormalsFromSmoothingGroupsWhenMeshHasBlendShapes: 1
|
||||
blendShapeNormalImportMode: 1
|
||||
normalSmoothingSource: 0
|
||||
referencedClips: []
|
||||
importAnimation: 1
|
||||
humanDescription:
|
||||
serializedVersion: 3
|
||||
human: []
|
||||
skeleton: []
|
||||
armTwist: 0.5
|
||||
foreArmTwist: 0.5
|
||||
upperLegTwist: 0.5
|
||||
legTwist: 0.5
|
||||
armStretch: 0.05
|
||||
legStretch: 0.05
|
||||
feetSpacing: 0
|
||||
globalScale: 0.05955983
|
||||
rootMotionBoneName:
|
||||
hasTranslationDoF: 0
|
||||
hasExtraRoot: 0
|
||||
skeletonHasParents: 0
|
||||
lastHumanDescriptionAvatarSource: {instanceID: 0}
|
||||
autoGenerateAvatarMappingIfUnspecified: 1
|
||||
animationType: 0
|
||||
humanoidOversampling: 1
|
||||
avatarSetup: 0
|
||||
addHumanoidExtraRootOnlyWhenUsingAvatar: 0
|
||||
importBlendShapeDeformPercent: 0
|
||||
remapMaterialsIfMaterialImportModeIsNone: 1
|
||||
additionalBone: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
9
Assets/Forklift/Model/Materials.meta
Normal file
9
Assets/Forklift/Model/Materials.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0adb815fa81eacd42bfc71700e03224b
|
||||
folderAsset: yes
|
||||
timeCreated: 1461022631
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
85
Assets/Forklift/Model/Materials/Material__25.mat
Normal file
85
Assets/Forklift/Model/Materials/Material__25.mat
Normal file
@@ -0,0 +1,85 @@
|
||||
%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: Material__25
|
||||
m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0}
|
||||
m_Parent: {fileID: 0}
|
||||
m_ModifiedSerializedProperties: 0
|
||||
m_ValidKeywords:
|
||||
- _EMISSION
|
||||
m_InvalidKeywords: []
|
||||
m_LightmapFlags: 1
|
||||
m_EnableInstancingVariants: 0
|
||||
m_DoubleSidedGI: 0
|
||||
m_CustomRenderQueue: -1
|
||||
stringTagMap: {}
|
||||
disabledShaderPasses: []
|
||||
m_LockedProperties:
|
||||
m_SavedProperties:
|
||||
serializedVersion: 3
|
||||
m_TexEnvs:
|
||||
- _BumpMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailAlbedoMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailMask:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailNormalMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _EmissionMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _MainTex:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _MetallicGlossMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _OcclusionMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _ParallaxMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
m_Ints: []
|
||||
m_Floats:
|
||||
- _BumpScale: 1
|
||||
- _Cutoff: 0.5
|
||||
- _DetailNormalMapScale: 1
|
||||
- _DstBlend: 0
|
||||
- _GlossMapScale: 1
|
||||
- _Glossiness: 0.5
|
||||
- _GlossyReflections: 1
|
||||
- _Metallic: 0
|
||||
- _Mode: 0
|
||||
- _OcclusionStrength: 1
|
||||
- _Parallax: 0.02
|
||||
- _SmoothnessTextureChannel: 0
|
||||
- _SpecularHighlights: 1
|
||||
- _SrcBlend: 1
|
||||
- _UVSec: 0
|
||||
- _ZWrite: 1
|
||||
m_Colors:
|
||||
- _Color: {r: 0.588, g: 0.588, b: 0.588, a: 1}
|
||||
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
|
||||
m_BuildTextureStacks: []
|
||||
m_AllowLocking: 1
|
||||
15
Assets/Forklift/Model/Materials/Material__25.mat.meta
Normal file
15
Assets/Forklift/Model/Materials/Material__25.mat.meta
Normal file
@@ -0,0 +1,15 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1c4cef6784fc0df479b2890cc8a34c1c
|
||||
timeCreated: 1461022631
|
||||
licenseType: Store
|
||||
NativeFormatImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 60960
|
||||
packageName: Forklift
|
||||
packageVersion: 1.0
|
||||
assetPath: Assets/Forklift/Model/Materials/Material__25.mat
|
||||
uploadId: 113592
|
||||
9
Assets/Forklift/Textures.meta
Normal file
9
Assets/Forklift/Textures.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 542e4f06968a2444ba5d4594b2bb9938
|
||||
folderAsset: yes
|
||||
timeCreated: 1461022410
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Assets/Forklift/Textures/Lifter_A.tga
Normal file
BIN
Assets/Forklift/Textures/Lifter_A.tga
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.0 MiB |
64
Assets/Forklift/Textures/Lifter_A.tga.meta
Normal file
64
Assets/Forklift/Textures/Lifter_A.tga.meta
Normal file
@@ -0,0 +1,64 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e3ac8151dd071124d836f4db513bfd9e
|
||||
timeCreated: 1461022026
|
||||
licenseType: Store
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
serializedVersion: 2
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 1
|
||||
linearTexture: 0
|
||||
correctGamma: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 0
|
||||
cubemapConvolution: 0
|
||||
cubemapConvolutionSteps: 7
|
||||
cubemapConvolutionExponent: 1.5
|
||||
seamlessCubemap: 0
|
||||
textureFormat: -1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
filterMode: -1
|
||||
aniso: -1
|
||||
mipBias: -1
|
||||
wrapMode: -1
|
||||
nPOTScale: 1
|
||||
lightmap: 0
|
||||
rGBM: 0
|
||||
compressionQuality: 50
|
||||
allowsAlphaSplitting: 0
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spritePixelsToUnits: 100
|
||||
alphaIsTransparency: 0
|
||||
textureType: -1
|
||||
buildTargetSettings: []
|
||||
spriteSheet:
|
||||
sprites: []
|
||||
outline: []
|
||||
spritePackingTag:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 60960
|
||||
packageName: Forklift
|
||||
packageVersion: 1.0
|
||||
assetPath: Assets/Forklift/Textures/Lifter_A.tga
|
||||
uploadId: 113592
|
||||
BIN
Assets/Forklift/Textures/Lifter_M.tga
Normal file
BIN
Assets/Forklift/Textures/Lifter_M.tga
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.0 MiB |
64
Assets/Forklift/Textures/Lifter_M.tga.meta
Normal file
64
Assets/Forklift/Textures/Lifter_M.tga.meta
Normal file
@@ -0,0 +1,64 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 12e9c1ba7abb52e4381e6ddebf256b2a
|
||||
timeCreated: 1461022025
|
||||
licenseType: Store
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
serializedVersion: 2
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 1
|
||||
linearTexture: 0
|
||||
correctGamma: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 0
|
||||
cubemapConvolution: 0
|
||||
cubemapConvolutionSteps: 7
|
||||
cubemapConvolutionExponent: 1.5
|
||||
seamlessCubemap: 0
|
||||
textureFormat: -1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
filterMode: -1
|
||||
aniso: -1
|
||||
mipBias: -1
|
||||
wrapMode: -1
|
||||
nPOTScale: 1
|
||||
lightmap: 0
|
||||
rGBM: 0
|
||||
compressionQuality: 50
|
||||
allowsAlphaSplitting: 0
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spritePixelsToUnits: 100
|
||||
alphaIsTransparency: 0
|
||||
textureType: -1
|
||||
buildTargetSettings: []
|
||||
spriteSheet:
|
||||
sprites: []
|
||||
outline: []
|
||||
spritePackingTag:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 60960
|
||||
packageName: Forklift
|
||||
packageVersion: 1.0
|
||||
assetPath: Assets/Forklift/Textures/Lifter_M.tga
|
||||
uploadId: 113592
|
||||
BIN
Assets/Forklift/Textures/Lifter_N.tga
Normal file
BIN
Assets/Forklift/Textures/Lifter_N.tga
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.5 MiB |
64
Assets/Forklift/Textures/Lifter_N.tga.meta
Normal file
64
Assets/Forklift/Textures/Lifter_N.tga.meta
Normal file
@@ -0,0 +1,64 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ee094282bf92bad478f1aa73778505a5
|
||||
timeCreated: 1461022026
|
||||
licenseType: Store
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
serializedVersion: 2
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 1
|
||||
linearTexture: 1
|
||||
correctGamma: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 1
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 0
|
||||
cubemapConvolution: 0
|
||||
cubemapConvolutionSteps: 7
|
||||
cubemapConvolutionExponent: 1.5
|
||||
seamlessCubemap: 0
|
||||
textureFormat: -1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
filterMode: -1
|
||||
aniso: -1
|
||||
mipBias: -1
|
||||
wrapMode: -1
|
||||
nPOTScale: 1
|
||||
lightmap: 0
|
||||
rGBM: 0
|
||||
compressionQuality: 50
|
||||
allowsAlphaSplitting: 0
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spritePixelsToUnits: 100
|
||||
alphaIsTransparency: 0
|
||||
textureType: 1
|
||||
buildTargetSettings: []
|
||||
spriteSheet:
|
||||
sprites: []
|
||||
outline: []
|
||||
spritePackingTag:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 60960
|
||||
packageName: Forklift
|
||||
packageVersion: 1.0
|
||||
assetPath: Assets/Forklift/Textures/Lifter_N.tga
|
||||
uploadId: 113592
|
||||
@@ -12,7 +12,7 @@ MonoBehaviour:
|
||||
m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
version: 9
|
||||
version: 10
|
||||
--- !u!21 &2100000
|
||||
Material:
|
||||
serializedVersion: 8
|
||||
@@ -27,7 +27,7 @@ Material:
|
||||
m_ValidKeywords:
|
||||
- _EMISSION
|
||||
m_InvalidKeywords: []
|
||||
m_LightmapFlags: 1
|
||||
m_LightmapFlags: 7
|
||||
m_EnableInstancingVariants: 0
|
||||
m_DoubleSidedGI: 0
|
||||
m_CustomRenderQueue: -1
|
||||
@@ -129,6 +129,7 @@ Material:
|
||||
- _Surface: 0
|
||||
- _UVSec: 0
|
||||
- _WorkflowMode: 1
|
||||
- _XRMotionVectorsPass: 1
|
||||
- _ZWrite: 1
|
||||
m_Colors:
|
||||
- _BaseColor: {r: 1, g: 1, b: 1, a: 1}
|
||||
|
||||
@@ -14,7 +14,7 @@ Material:
|
||||
m_ValidKeywords:
|
||||
- _EMISSION
|
||||
m_InvalidKeywords: []
|
||||
m_LightmapFlags: 1
|
||||
m_LightmapFlags: 7
|
||||
m_EnableInstancingVariants: 0
|
||||
m_DoubleSidedGI: 0
|
||||
m_CustomRenderQueue: -1
|
||||
@@ -116,6 +116,7 @@ Material:
|
||||
- _Surface: 0
|
||||
- _UVSec: 0
|
||||
- _WorkflowMode: 1
|
||||
- _XRMotionVectorsPass: 1
|
||||
- _ZWrite: 1
|
||||
m_Colors:
|
||||
- _BaseColor: {r: 1, g: 1, b: 1, a: 1}
|
||||
@@ -136,4 +137,4 @@ MonoBehaviour:
|
||||
m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
version: 9
|
||||
version: 10
|
||||
|
||||
@@ -14,7 +14,7 @@ Material:
|
||||
m_ValidKeywords:
|
||||
- _EMISSION
|
||||
m_InvalidKeywords: []
|
||||
m_LightmapFlags: 1
|
||||
m_LightmapFlags: 7
|
||||
m_EnableInstancingVariants: 0
|
||||
m_DoubleSidedGI: 0
|
||||
m_CustomRenderQueue: -1
|
||||
@@ -116,6 +116,7 @@ Material:
|
||||
- _Surface: 0
|
||||
- _UVSec: 0
|
||||
- _WorkflowMode: 1
|
||||
- _XRMotionVectorsPass: 1
|
||||
- _ZWrite: 1
|
||||
m_Colors:
|
||||
- _BaseColor: {r: 1, g: 1, b: 1, a: 1}
|
||||
@@ -136,4 +137,4 @@ MonoBehaviour:
|
||||
m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
version: 9
|
||||
version: 10
|
||||
|
||||
@@ -14,7 +14,7 @@ Material:
|
||||
m_ValidKeywords:
|
||||
- _EMISSION
|
||||
m_InvalidKeywords: []
|
||||
m_LightmapFlags: 1
|
||||
m_LightmapFlags: 7
|
||||
m_EnableInstancingVariants: 0
|
||||
m_DoubleSidedGI: 0
|
||||
m_CustomRenderQueue: -1
|
||||
@@ -116,6 +116,7 @@ Material:
|
||||
- _Surface: 0
|
||||
- _UVSec: 0
|
||||
- _WorkflowMode: 1
|
||||
- _XRMotionVectorsPass: 1
|
||||
- _ZWrite: 1
|
||||
m_Colors:
|
||||
- _BaseColor: {r: 1, g: 1, b: 1, a: 1}
|
||||
@@ -136,4 +137,4 @@ MonoBehaviour:
|
||||
m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
version: 9
|
||||
version: 10
|
||||
|
||||
@@ -14,7 +14,7 @@ Material:
|
||||
m_ValidKeywords:
|
||||
- _EMISSION
|
||||
m_InvalidKeywords: []
|
||||
m_LightmapFlags: 1
|
||||
m_LightmapFlags: 7
|
||||
m_EnableInstancingVariants: 0
|
||||
m_DoubleSidedGI: 0
|
||||
m_CustomRenderQueue: -1
|
||||
@@ -116,6 +116,7 @@ Material:
|
||||
- _Surface: 0
|
||||
- _UVSec: 0
|
||||
- _WorkflowMode: 1
|
||||
- _XRMotionVectorsPass: 1
|
||||
- _ZWrite: 1
|
||||
m_Colors:
|
||||
- _BaseColor: {r: 1, g: 1, b: 1, a: 1}
|
||||
@@ -136,4 +137,4 @@ MonoBehaviour:
|
||||
m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
version: 9
|
||||
version: 10
|
||||
|
||||
@@ -14,7 +14,7 @@ Material:
|
||||
m_ValidKeywords:
|
||||
- _EMISSION
|
||||
m_InvalidKeywords: []
|
||||
m_LightmapFlags: 1
|
||||
m_LightmapFlags: 7
|
||||
m_EnableInstancingVariants: 0
|
||||
m_DoubleSidedGI: 0
|
||||
m_CustomRenderQueue: -1
|
||||
@@ -116,6 +116,7 @@ Material:
|
||||
- _Surface: 0
|
||||
- _UVSec: 0
|
||||
- _WorkflowMode: 1
|
||||
- _XRMotionVectorsPass: 1
|
||||
- _ZWrite: 1
|
||||
m_Colors:
|
||||
- _BaseColor: {r: 1, g: 1, b: 1, a: 1}
|
||||
@@ -136,4 +137,4 @@ MonoBehaviour:
|
||||
m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
version: 9
|
||||
version: 10
|
||||
|
||||
136
Assets/FreeForkLift/Textures/ForkLift.mat
Normal file
136
Assets/FreeForkLift/Textures/ForkLift.mat
Normal file
@@ -0,0 +1,136 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!114 &-2991290977010170569
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 11
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 0}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
version: 10
|
||||
--- !u!21 &2100000
|
||||
Material:
|
||||
serializedVersion: 8
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: ForkLift
|
||||
m_Shader: {fileID: 4800000, guid: 933532a4fcc9baf4fa0491de14d08ed7, type: 3}
|
||||
m_Parent: {fileID: 0}
|
||||
m_ModifiedSerializedProperties: 0
|
||||
m_ValidKeywords: []
|
||||
m_InvalidKeywords: []
|
||||
m_LightmapFlags: 4
|
||||
m_EnableInstancingVariants: 0
|
||||
m_DoubleSidedGI: 0
|
||||
m_CustomRenderQueue: -1
|
||||
stringTagMap:
|
||||
RenderType: Opaque
|
||||
disabledShaderPasses:
|
||||
- MOTIONVECTORS
|
||||
m_LockedProperties:
|
||||
m_SavedProperties:
|
||||
serializedVersion: 3
|
||||
m_TexEnvs:
|
||||
- _BaseMap:
|
||||
m_Texture: {fileID: 2800000, guid: 93ccb8dbd2a24ea4f818bbf753613ee1, type: 3}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _BumpMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailAlbedoMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailMask:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailNormalMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _EmissionMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _MainTex:
|
||||
m_Texture: {fileID: 2800000, guid: 93ccb8dbd2a24ea4f818bbf753613ee1, type: 3}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _MetallicGlossMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _OcclusionMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _ParallaxMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _SpecGlossMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- unity_Lightmaps:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- unity_LightmapsInd:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- unity_ShadowMasks:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
m_Ints: []
|
||||
m_Floats:
|
||||
- _AddPrecomputedVelocity: 0
|
||||
- _AlphaClip: 0
|
||||
- _AlphaToMask: 0
|
||||
- _Blend: 0
|
||||
- _BlendModePreserveSpecular: 1
|
||||
- _BumpScale: 1
|
||||
- _ClearCoatMask: 0
|
||||
- _ClearCoatSmoothness: 0
|
||||
- _Cull: 2
|
||||
- _Cutoff: 0.5
|
||||
- _DetailAlbedoMapScale: 1
|
||||
- _DetailNormalMapScale: 1
|
||||
- _DstBlend: 0
|
||||
- _DstBlendAlpha: 0
|
||||
- _EnvironmentReflections: 1
|
||||
- _GlossMapScale: 0
|
||||
- _Glossiness: 0
|
||||
- _GlossyReflections: 0
|
||||
- _Metallic: 0
|
||||
- _OcclusionStrength: 1
|
||||
- _Parallax: 0.005
|
||||
- _QueueOffset: 0
|
||||
- _ReceiveShadows: 1
|
||||
- _Smoothness: 0.5
|
||||
- _SmoothnessTextureChannel: 0
|
||||
- _SpecularHighlights: 1
|
||||
- _SrcBlend: 1
|
||||
- _SrcBlendAlpha: 1
|
||||
- _Surface: 0
|
||||
- _WorkflowMode: 1
|
||||
- _ZWrite: 1
|
||||
m_Colors:
|
||||
- _BaseColor: {r: 1, g: 1, b: 1, a: 1}
|
||||
- _Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
|
||||
- _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1}
|
||||
m_BuildTextureStacks: []
|
||||
m_AllowLocking: 1
|
||||
8
Assets/FreeForkLift/Textures/ForkLift.mat.meta
Normal file
8
Assets/FreeForkLift/Textures/ForkLift.mat.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 54c4baf90ea6e8649b4f0b8eef0d05e4
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 2100000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
136
Assets/FreeForkLift/Textures/Wheel.mat
Normal file
136
Assets/FreeForkLift/Textures/Wheel.mat
Normal file
@@ -0,0 +1,136 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!114 &-5854526223199486706
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 11
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 0}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
version: 10
|
||||
--- !u!21 &2100000
|
||||
Material:
|
||||
serializedVersion: 8
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: Wheel
|
||||
m_Shader: {fileID: 4800000, guid: 933532a4fcc9baf4fa0491de14d08ed7, type: 3}
|
||||
m_Parent: {fileID: 0}
|
||||
m_ModifiedSerializedProperties: 0
|
||||
m_ValidKeywords: []
|
||||
m_InvalidKeywords: []
|
||||
m_LightmapFlags: 4
|
||||
m_EnableInstancingVariants: 0
|
||||
m_DoubleSidedGI: 0
|
||||
m_CustomRenderQueue: -1
|
||||
stringTagMap:
|
||||
RenderType: Opaque
|
||||
disabledShaderPasses:
|
||||
- MOTIONVECTORS
|
||||
m_LockedProperties:
|
||||
m_SavedProperties:
|
||||
serializedVersion: 3
|
||||
m_TexEnvs:
|
||||
- _BaseMap:
|
||||
m_Texture: {fileID: 2800000, guid: c3e554fa15d0ecd48b241ee7d240dc19, type: 3}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _BumpMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailAlbedoMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailMask:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailNormalMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _EmissionMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _MainTex:
|
||||
m_Texture: {fileID: 2800000, guid: c3e554fa15d0ecd48b241ee7d240dc19, type: 3}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _MetallicGlossMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _OcclusionMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _ParallaxMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _SpecGlossMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- unity_Lightmaps:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- unity_LightmapsInd:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- unity_ShadowMasks:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
m_Ints: []
|
||||
m_Floats:
|
||||
- _AddPrecomputedVelocity: 0
|
||||
- _AlphaClip: 0
|
||||
- _AlphaToMask: 0
|
||||
- _Blend: 0
|
||||
- _BlendModePreserveSpecular: 1
|
||||
- _BumpScale: 1
|
||||
- _ClearCoatMask: 0
|
||||
- _ClearCoatSmoothness: 0
|
||||
- _Cull: 2
|
||||
- _Cutoff: 0.5
|
||||
- _DetailAlbedoMapScale: 1
|
||||
- _DetailNormalMapScale: 1
|
||||
- _DstBlend: 0
|
||||
- _DstBlendAlpha: 0
|
||||
- _EnvironmentReflections: 1
|
||||
- _GlossMapScale: 0
|
||||
- _Glossiness: 0
|
||||
- _GlossyReflections: 0
|
||||
- _Metallic: 0
|
||||
- _OcclusionStrength: 1
|
||||
- _Parallax: 0.005
|
||||
- _QueueOffset: 0
|
||||
- _ReceiveShadows: 1
|
||||
- _Smoothness: 0.5
|
||||
- _SmoothnessTextureChannel: 0
|
||||
- _SpecularHighlights: 1
|
||||
- _SrcBlend: 1
|
||||
- _SrcBlendAlpha: 1
|
||||
- _Surface: 0
|
||||
- _WorkflowMode: 1
|
||||
- _ZWrite: 1
|
||||
m_Colors:
|
||||
- _BaseColor: {r: 1, g: 1, b: 1, a: 1}
|
||||
- _Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
|
||||
- _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1}
|
||||
m_BuildTextureStacks: []
|
||||
m_AllowLocking: 1
|
||||
8
Assets/FreeForkLift/Textures/Wheel.mat.meta
Normal file
8
Assets/FreeForkLift/Textures/Wheel.mat.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 12ca9f15b8356184ca7a2cd3b27a88b3
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 2100000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 636a2b49a8f312743a238612e3cb0b8b
|
||||
guid: 81f481468a087c74ea3a326fd2fc33e1
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7b692852ba3f94d45990b0637d03eeb6
|
||||
guid: a2a7b4351f0a477479c2cf11d971bb3e
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4162837cd34c49f479963ff3a17e9365
|
||||
guid: fe1091a74ea67954db55dd73a0be5dab
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
223
Assets/HybridIK/Scripts/Joint Limits/DynamicJointLimit.cs
Normal file
223
Assets/HybridIK/Scripts/Joint Limits/DynamicJointLimit.cs
Normal file
@@ -0,0 +1,223 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace AshqarApps.DynamicJoint
|
||||
{
|
||||
public class DynamicJointLimit : MonoBehaviour
|
||||
{
|
||||
public bool enable = true;
|
||||
|
||||
[Header("Main")]
|
||||
public Vector3 mainAxis = Vector3.forward;
|
||||
|
||||
[HideInInspector]
|
||||
public Vector3 secondaryAxis = Vector3.up;
|
||||
[HideInInspector]
|
||||
public Vector3 crossAxis { get { return Vector3.Cross(mainAxis, secondaryAxis); } }
|
||||
|
||||
[HideInInspector] public Quaternion zeroRotation;
|
||||
public bool zeroRotationOverride { get; private set; }
|
||||
|
||||
public Vector3 limitsOffset;
|
||||
|
||||
private bool initialized;
|
||||
private bool applicationQuit;
|
||||
private bool zeroRotationSet;
|
||||
|
||||
protected bool isClampedToLimit = false;
|
||||
|
||||
/// <summary>
|
||||
/// The swing limit.
|
||||
/// </summary>
|
||||
[Range(0f, 180f)] public float limitAngle = 45;
|
||||
|
||||
public bool applyEveryFrame = false;
|
||||
|
||||
//[Header("Dynamics")]
|
||||
|
||||
[HideInInspector]
|
||||
public float bounce = 0;
|
||||
[HideInInspector]
|
||||
public float friction = 0;
|
||||
|
||||
/*
|
||||
* Applies uniform twist limit to the rotation
|
||||
* */
|
||||
protected Quaternion LimitTwist(Quaternion rotation, Vector3 axis, Vector3 orthoAxis, float twistLimit)
|
||||
{
|
||||
twistLimit = Mathf.Clamp(twistLimit, 0, 180);
|
||||
if (twistLimit >= 180) return rotation;
|
||||
|
||||
Vector3 normal = rotation * axis;
|
||||
Vector3 orthoTangent = orthoAxis;
|
||||
Vector3.OrthoNormalize(ref normal, ref orthoTangent);
|
||||
|
||||
Vector3 rotatedOrthoTangent = rotation * orthoAxis;
|
||||
Vector3.OrthoNormalize(ref normal, ref rotatedOrthoTangent);
|
||||
|
||||
Quaternion fixedRotation = Quaternion.FromToRotation(rotatedOrthoTangent, orthoTangent) * rotation;
|
||||
|
||||
if (twistLimit <= 0) return fixedRotation;
|
||||
|
||||
float twistAngle = Quaternion.Angle(fixedRotation, rotation);
|
||||
if (twistAngle >= twistLimit)
|
||||
{
|
||||
isClampedToLimit = true;
|
||||
}
|
||||
|
||||
// Rotate from zero twist to free twist by the limited angle
|
||||
return Quaternion.RotateTowards(fixedRotation, rotation, twistLimit);
|
||||
}
|
||||
|
||||
public virtual Vector3 GetStretchAxis()
|
||||
{
|
||||
return Vector3.zero;
|
||||
}
|
||||
|
||||
public virtual Vector3 GetMainAxisWorld()
|
||||
{
|
||||
return Direction(mainAxis);
|
||||
}
|
||||
|
||||
public virtual Quaternion LimitRotation(Quaternion rotation, float jointLimitStrength = 1)
|
||||
{
|
||||
return rotation;
|
||||
}
|
||||
|
||||
public virtual Vector3 GetMidVectorWorld()
|
||||
{
|
||||
return mainAxis;
|
||||
}
|
||||
|
||||
protected Vector3 Direction(Vector3 v)
|
||||
{
|
||||
if (transform.parent == null) return zeroRotation * v;
|
||||
return transform.parent.rotation * (zeroRotation * v);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the limited local rotation.
|
||||
/// </summary>
|
||||
public Quaternion GetLimitedLocalRotation(Quaternion localRotation, out bool changed, float jointLimitStrength = 1)
|
||||
{
|
||||
// Making sure the Rotation Limit is initiated
|
||||
if (!initialized) Awake();
|
||||
|
||||
// Subtracting defaultLocalRotation
|
||||
Quaternion rotation = Quaternion.Inverse(zeroRotation) * localRotation;
|
||||
|
||||
Quaternion limitedRotation = LimitRotation(rotation);
|
||||
#if UNITY_2018_3_OR_NEWER
|
||||
limitedRotation = Quaternion.Normalize(limitedRotation);
|
||||
#endif
|
||||
changed = limitedRotation != rotation;
|
||||
|
||||
if (!changed) return localRotation;
|
||||
|
||||
// Apply defaultLocalRotation back on
|
||||
return zeroRotation * limitedRotation;
|
||||
}
|
||||
|
||||
public float EvaluateSwingLimitAtOrthoAngle(float angle)
|
||||
{
|
||||
float sinAngle = Mathf.Abs(Mathf.Sin(Mathf.Deg2Rad * angle));
|
||||
//return sinAngle;
|
||||
return (sinAngle * limitAngle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Apply the rotation limit to transform.localRotation. Returns true if the limit has changed the rotation.
|
||||
/// </summary>
|
||||
public virtual bool Apply(float jointLimitStrength = 1)
|
||||
{
|
||||
isClampedToLimit = false;
|
||||
|
||||
if (jointLimitStrength == 0 || !enable)
|
||||
return false;
|
||||
|
||||
bool changed = false;
|
||||
|
||||
Quaternion targetRot = GetLimitedLocalRotation(transform.localRotation, out changed);
|
||||
|
||||
if (changed)
|
||||
{
|
||||
if (jointLimitStrength < 1)
|
||||
{
|
||||
float angle = Quaternion.Angle(transform.localRotation, targetRot);
|
||||
|
||||
Quaternion easedRotation = Quaternion.RotateTowards(transform.localRotation, targetRot, angle * jointLimitStrength);
|
||||
|
||||
transform.localRotation = easedRotation;
|
||||
}
|
||||
else
|
||||
{
|
||||
transform.localRotation = targetRot;
|
||||
}
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disable this instance making sure it is initiated. Use this if you intend to manually control the updating of this Rotation Limit.
|
||||
/// </summary>
|
||||
public void Disable()
|
||||
{
|
||||
if (initialized)
|
||||
{
|
||||
enabled = false;
|
||||
return;
|
||||
}
|
||||
|
||||
Awake();
|
||||
enabled = false;
|
||||
}
|
||||
|
||||
public void SetZeroRotation()
|
||||
{
|
||||
zeroRotation = transform.localRotation;
|
||||
zeroRotationSet = true;
|
||||
zeroRotationOverride = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Map the zero rotation point to the specified rotation.
|
||||
/// </summary>
|
||||
public void SetZeroRotation(Quaternion localRotation)
|
||||
{
|
||||
zeroRotation = localRotation;
|
||||
zeroRotationSet = true;
|
||||
zeroRotationOverride = true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the angle between two vectors on a plane with the specified normal
|
||||
* */
|
||||
public static float GetOrthogonalAngle(Vector3 v1, Vector3 v2, Vector3 normal)
|
||||
{
|
||||
Vector3.OrthoNormalize(ref normal, ref v1);
|
||||
Vector3.OrthoNormalize(ref normal, ref v2);
|
||||
return Vector3.Angle(v1, v2);
|
||||
}
|
||||
|
||||
void LateUpdate()
|
||||
{
|
||||
if (applyEveryFrame)
|
||||
Apply();
|
||||
}
|
||||
|
||||
void Awake()
|
||||
{
|
||||
// Store the local rotation to map the zero rotation point to the current rotation
|
||||
if (!zeroRotationSet) SetZeroRotation();
|
||||
|
||||
if (mainAxis == Vector3.zero)
|
||||
{
|
||||
Debug.LogError("Axis is Vector3.zero.");
|
||||
mainAxis = Vector3.forward;
|
||||
}
|
||||
initialized = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f4d18e67185065d4e871e8f6eb899138
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 174069
|
||||
packageName: Hybrid IK
|
||||
packageVersion: 1.02
|
||||
assetPath: Assets/HybridIK/Scripts/Joint Limits/DynamicJointLimit.cs
|
||||
uploadId: 532533
|
||||
100
Assets/HybridIK/Scripts/Joint Limits/DynamicJointLimitHinge.cs
Normal file
100
Assets/HybridIK/Scripts/Joint Limits/DynamicJointLimitHinge.cs
Normal file
@@ -0,0 +1,100 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace AshqarApps.DynamicJoint
|
||||
{
|
||||
public class DynamicJointLimitHinge : DynamicJointLimit
|
||||
{
|
||||
[Header("Hinge Limits")]
|
||||
[Range(0f, 360f)]
|
||||
public float hingeAngleOffset = 0;
|
||||
|
||||
public Vector3 cross = Vector3.up;
|
||||
|
||||
private Quaternion lastRotation = Quaternion.identity;
|
||||
|
||||
public override Vector3 GetMainAxisWorld()
|
||||
{
|
||||
Quaternion offsetRot = Quaternion.Euler(limitsOffset);
|
||||
Vector3 offsetSwingAxis = (offsetRot * this.mainAxis).normalized;
|
||||
return Direction(offsetSwingAxis);
|
||||
}
|
||||
|
||||
public override Vector3 GetStretchAxis()
|
||||
{
|
||||
return GetMainAxisWorld();
|
||||
}
|
||||
|
||||
public override Vector3 GetMidVectorWorld()
|
||||
{
|
||||
return GetPlaneAxisWorld();
|
||||
}
|
||||
|
||||
public Vector3 GetPlaneAxisWorld()
|
||||
{
|
||||
Quaternion offsetRot = Quaternion.Euler(limitsOffset);
|
||||
Vector3 swing = Direction(offsetRot * mainAxis.normalized);
|
||||
|
||||
Vector3 secondaryAxis = new Vector3(mainAxis.y, mainAxis.z, mainAxis.x);
|
||||
Vector3 cross = Direction(Vector3.Cross(mainAxis, secondaryAxis));
|
||||
cross = Direction(offsetRot * this.cross);
|
||||
Quaternion hingeOffset = Quaternion.AngleAxis(hingeAngleOffset, swing);
|
||||
return hingeOffset * cross;
|
||||
}
|
||||
|
||||
/*
|
||||
* Apply the hinge rotation limit
|
||||
* */
|
||||
public Quaternion LimitHinge(Quaternion rotation)
|
||||
{
|
||||
Quaternion offsetRot = Quaternion.Euler(limitsOffset);
|
||||
|
||||
Vector3 offsetSwingAxis = (offsetRot * this.mainAxis);
|
||||
Vector3 offsetSecondaryAxis = (offsetRot * this.cross);
|
||||
Vector3.OrthoNormalize(ref offsetSwingAxis, ref offsetSecondaryAxis);
|
||||
Vector3 offsetCrossAxis = Vector3.Cross(offsetSwingAxis, offsetSecondaryAxis);
|
||||
|
||||
Quaternion hingeOffset = Quaternion.AngleAxis(hingeAngleOffset, offsetSwingAxis);
|
||||
Quaternion minRotation = Quaternion.AngleAxis(-limitAngle, offsetSwingAxis) * hingeOffset;
|
||||
Quaternion maxRotation = Quaternion.AngleAxis(limitAngle, offsetSwingAxis) * hingeOffset;
|
||||
|
||||
// Get 1 degree of freedom rotation along axis
|
||||
Quaternion free1DOFTarget = Quaternion.FromToRotation(rotation * offsetSwingAxis, offsetSwingAxis) * rotation;
|
||||
|
||||
if (limitAngle >= 180)
|
||||
return free1DOFTarget;
|
||||
|
||||
float midLimit = (limitAngle >= 90f) ? 180 - limitAngle : limitAngle;
|
||||
Quaternion free1DOFMid = Quaternion.RotateTowards(minRotation, maxRotation, midLimit);
|
||||
if (limitAngle >= 90f)
|
||||
{
|
||||
Quaternion flip180 = Quaternion.AngleAxis(180, offsetSwingAxis);
|
||||
free1DOFMid *= flip180;
|
||||
}
|
||||
|
||||
Quaternion lastRotation = free1DOFTarget;
|
||||
|
||||
float angle = Quaternion.Angle(free1DOFTarget, free1DOFMid);
|
||||
Quaternion clampedFree1DOF = Quaternion.RotateTowards(free1DOFMid, free1DOFTarget, limitAngle);
|
||||
|
||||
isClampedToLimit = angle >= limitAngle;
|
||||
|
||||
return clampedFree1DOF;
|
||||
|
||||
}
|
||||
|
||||
public override Quaternion LimitRotation(Quaternion rotation, float jointLimitStrength = 1)
|
||||
{
|
||||
lastRotation = LimitHinge(rotation);
|
||||
return lastRotation;
|
||||
}
|
||||
|
||||
public override bool Apply(float jointLimitStrength = 1)
|
||||
{
|
||||
bool hasChanged = base.Apply(jointLimitStrength);
|
||||
return isClampedToLimit;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2c7a022be76393744b9f1a13d09311ca
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 174069
|
||||
packageName: Hybrid IK
|
||||
packageVersion: 1.02
|
||||
assetPath: Assets/HybridIK/Scripts/Joint Limits/DynamicJointLimitHinge.cs
|
||||
uploadId: 532533
|
||||
@@ -0,0 +1,174 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace AshqarApps.DynamicJoint
|
||||
{
|
||||
public class DynamicJointLimitSwingTwist : DynamicJointLimit
|
||||
{
|
||||
[Header("Swing Twist Limits")]
|
||||
[Range(0f, 180f)] public float twistLimit = 45;
|
||||
|
||||
[Range(0f, 1f)] public float limitWidthRatio = 1;
|
||||
[Range(0f, 1f)] public float limitHeightRatio = 1;
|
||||
|
||||
public Quaternion LimitSwing(Quaternion rotation, bool visualizeMode = false)
|
||||
{
|
||||
if (this.mainAxis == Vector3.zero) return rotation; // Ignore with zero axes
|
||||
//if (rotation == Quaternion.identity) return rotation; // Assuming initial rotation is in the reachable area
|
||||
|
||||
Quaternion offsetRot = Quaternion.Euler(limitsOffset);
|
||||
if (visualizeMode)
|
||||
{
|
||||
offsetRot = Quaternion.identity;
|
||||
}
|
||||
|
||||
Vector3 offsetSwingAxis = (offsetRot * this.mainAxis).normalized;
|
||||
Vector3 offsetSecondaryAxis = (offsetRot * this.secondaryAxis).normalized;
|
||||
Vector3.OrthoNormalize(ref offsetSwingAxis, ref offsetSecondaryAxis);
|
||||
Vector3 offsetCrossAxis = Vector3.Cross(offsetSwingAxis, offsetSecondaryAxis);
|
||||
|
||||
Vector3 targetSwing = rotation * mainAxis;
|
||||
|
||||
float angle = Vector3.SignedAngle(offsetSwingAxis, targetSwing, Vector3.Cross(offsetSwingAxis, targetSwing));
|
||||
Vector3 unlimitedTargetSwing = targetSwing;
|
||||
|
||||
float maxAngle = angle > 0 ? limitAngle : -limitAngle;
|
||||
Quaternion maxRotation = Quaternion.AngleAxis(maxAngle, Vector3.Cross(offsetSwingAxis, targetSwing));
|
||||
|
||||
Vector3 maxTargetSwing = maxRotation * offsetSwingAxis;
|
||||
|
||||
// Scale Limit Based on Width Height Ratios
|
||||
Vector3 limitCircleCenter = Vector3.ProjectOnPlane(offsetSwingAxis - maxTargetSwing, offsetSwingAxis) + maxTargetSwing;
|
||||
float circleRadius = Vector3.Distance(maxTargetSwing, limitCircleCenter);
|
||||
Debug.DrawLine(transform.position + Direction(maxTargetSwing), transform.position + Direction(maxTargetSwing));
|
||||
|
||||
Vector3 projectToCircle = (maxTargetSwing - limitCircleCenter);
|
||||
float width = circleRadius * limitWidthRatio;
|
||||
float height = circleRadius * limitHeightRatio;
|
||||
|
||||
Vector3 coneX = Vector3.Project(projectToCircle, offsetSecondaryAxis);
|
||||
Vector3 coneY = Vector3.Project(projectToCircle, offsetCrossAxis);
|
||||
|
||||
if (limitHeightRatio < 1 || limitWidthRatio < 1)
|
||||
{
|
||||
//find cartesian ellipse coordinates intersection
|
||||
Vector2 center = Vector2.zero;
|
||||
Vector2 pt = new Vector2(coneX.magnitude, coneY.magnitude);
|
||||
Vector3[] candidateProjectionPoints = FindEllipseSegmentIntersections(width, height, center, pt, true);
|
||||
|
||||
//map cartesian intersection point back to joint space
|
||||
if (candidateProjectionPoints.Length > 0)
|
||||
{
|
||||
Vector3 projectedX = coneX.normalized * candidateProjectionPoints[0].x;
|
||||
Vector3 projectedY = coneY.normalized * candidateProjectionPoints[0].y;
|
||||
maxTargetSwing = (limitCircleCenter + projectedX + projectedY).normalized;
|
||||
}
|
||||
}
|
||||
|
||||
if (Vector3.Angle(offsetSwingAxis, maxTargetSwing) < Vector3.Angle(offsetSwingAxis, targetSwing))
|
||||
{
|
||||
isClampedToLimit = true;
|
||||
targetSwing = maxTargetSwing;
|
||||
}
|
||||
|
||||
// Get the limited swing axis
|
||||
Quaternion limitedSwingRotation = Quaternion.FromToRotation(offsetSwingAxis, targetSwing);
|
||||
|
||||
// Rotation from current(illegal) swing rotation to the limited(legal) swing rotation
|
||||
Quaternion toLimits = Quaternion.FromToRotation(unlimitedTargetSwing, limitedSwingRotation * offsetSwingAxis);
|
||||
|
||||
// Subtract the illegal rotation
|
||||
return toLimits * rotation;
|
||||
|
||||
}
|
||||
|
||||
public override Vector3 GetStretchAxis()
|
||||
{
|
||||
return GetMainAxisWorld();
|
||||
}
|
||||
|
||||
public override Vector3 GetMidVectorWorld()
|
||||
{
|
||||
return GetMainAxisWorld();
|
||||
}
|
||||
|
||||
public override Vector3 GetMainAxisWorld()
|
||||
{
|
||||
Quaternion offsetRot = Quaternion.Euler(limitsOffset);
|
||||
Vector3 offsetSwingAxis = (offsetRot * this.mainAxis).normalized;
|
||||
return Direction(offsetSwingAxis);
|
||||
}
|
||||
|
||||
public override Quaternion LimitRotation(Quaternion rotation, float jointLimitStrength = 1)
|
||||
{
|
||||
Quaternion swing = LimitSwing(rotation);
|
||||
return LimitTwist(swing, mainAxis, secondaryAxis, twistLimit);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Find the points of intersection between
|
||||
// an ellipse and a line segment.
|
||||
public Vector3[] FindEllipseSegmentIntersections(
|
||||
float width, float height, Vector3 pt1, Vector3 pt2, bool segment_only)
|
||||
{
|
||||
// If the ellipse or line segment are empty, return no intersections.
|
||||
if ((width == 0) || (height == 0) ||
|
||||
((pt1.x == pt2.x) && (pt1.y == pt2.y)))
|
||||
return new Vector3[] { };
|
||||
|
||||
// Get the semimajor and semiminor axes.
|
||||
float a = width;
|
||||
float b = height;
|
||||
|
||||
// Calculate the quadratic parameters.
|
||||
float A = (pt2.x - pt1.x) * (pt2.x - pt1.x) / a / a +
|
||||
(pt2.y - pt1.y) * (pt2.y - pt1.y) / b / b;
|
||||
float B = 2 * pt1.x * (pt2.x - pt1.x) / a / a +
|
||||
2 * pt1.y * (pt2.y - pt1.y) / b / b;
|
||||
float C = pt1.x * pt1.x / a / a + pt1.y * pt1.y / b / b - 1;
|
||||
|
||||
// Make a list of t values.
|
||||
List<float> t_values = new List<float>();
|
||||
|
||||
// Calculate the discriminant.
|
||||
float discriminant = B * B - 4 * A * C;
|
||||
if (discriminant == 0)
|
||||
{
|
||||
// One real solution.
|
||||
t_values.Add(-B / 2 / A);
|
||||
}
|
||||
else if (discriminant > 0)
|
||||
{
|
||||
// Two real solutions.
|
||||
t_values.Add((float)((-B + Mathf.Sqrt(discriminant)) / 2 / A));
|
||||
t_values.Add((float)((-B - Mathf.Sqrt(discriminant)) / 2 / A));
|
||||
}
|
||||
|
||||
// Convert the t values into points.
|
||||
List<Vector3> points = new List<Vector3>();
|
||||
foreach (float t in t_values)
|
||||
{
|
||||
// If the points are on the segment (or we
|
||||
// don't care if they are), add them to the list.
|
||||
if (!segment_only || ((t >= 0f) && (t <= 1f)))
|
||||
{
|
||||
float x = pt1.x + (pt2.x - pt1.x) * t;
|
||||
float y = pt1.y + (pt2.y - pt1.y) * t;
|
||||
points.Add(new Vector3(x, y));
|
||||
}
|
||||
}
|
||||
|
||||
// Return the points.
|
||||
return points.ToArray();
|
||||
}
|
||||
|
||||
public override bool Apply(float jointLimitStrength = 1)
|
||||
{
|
||||
bool hasChanged = base.Apply(jointLimitStrength);
|
||||
return isClampedToLimit;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 59495989be03fc34f8db82a27c38e0ca
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 174069
|
||||
packageName: Hybrid IK
|
||||
packageVersion: 1.02
|
||||
assetPath: Assets/HybridIK/Scripts/Joint Limits/DynamicJointLimitSwingTwist.cs
|
||||
uploadId: 532533
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b7850ec6000d2f74bb08eb47a75dfbfb
|
||||
guid: fdbf4dac63e13c14c96f45a9bd20e412
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
@@ -0,0 +1,325 @@
|
||||
#if UNITY_EDITOR
|
||||
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
|
||||
namespace AshqarApps.DynamicJoint
|
||||
{
|
||||
[CustomEditor(typeof(DynamicJointLimitHinge))]
|
||||
[CanEditMultipleObjects]
|
||||
public class DynamicJointLimitHingeInspector : Editor
|
||||
{
|
||||
private DynamicJointLimitHinge script { get { return target as DynamicJointLimitHinge; } }
|
||||
private Vector3 lastPoint, zeroPoint;
|
||||
|
||||
float lastHingeOffset = 0;
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
GUI.changed = false;
|
||||
|
||||
base.OnInspectorGUI();
|
||||
//DrawDefaultInspector();
|
||||
|
||||
int childCount = script.transform.childCount;
|
||||
GameObject childGO = null;
|
||||
for (int i = 0; i < script.transform.childCount; ++i)
|
||||
{
|
||||
if (!script.transform.GetChild(i).tag.Contains("ExcludeFromDynamics"))
|
||||
{
|
||||
childGO = script.transform.GetChild(i).gameObject;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (childGO != null)
|
||||
{
|
||||
if (GUILayout.Button("Align To Child Twist"))
|
||||
{
|
||||
Vector3 toChild = childGO.transform.position - script.transform.position;
|
||||
script.mainAxis = script.transform.InverseTransformDirection(toChild.normalized);
|
||||
Vector3 secondaryAxis = new Vector3(script.mainAxis.y, script.mainAxis.z, script.mainAxis.x);
|
||||
script.cross = Direction(Vector3.Cross(script.mainAxis, secondaryAxis));
|
||||
}
|
||||
else if (GUILayout.Button("Align To Child X"))
|
||||
{
|
||||
Vector3 toChild = (childGO.transform.position - script.transform.position).normalized;
|
||||
script.cross = script.transform.InverseTransformDirection(toChild);
|
||||
//Vector3 secondaryAxis = new Vector3(script.cross.y, script.cross.z, script.cross.x);
|
||||
Vector3 secondaryAxis = script.transform.InverseTransformDirection(script.transform.right);
|
||||
Vector3.OrthoNormalize(ref secondaryAxis, ref script.cross);
|
||||
//Vector3 cross = Direction(Vector3.Cross(script.cross, secondaryAxis));
|
||||
script.mainAxis = secondaryAxis;
|
||||
}
|
||||
else if (GUILayout.Button("Align To Child Y"))
|
||||
{
|
||||
Vector3 toChild = (childGO.transform.position - script.transform.position).normalized;
|
||||
script.cross = script.transform.InverseTransformDirection(toChild);
|
||||
Vector3 secondaryAxis = script.transform.InverseTransformDirection(script.transform.up);
|
||||
Vector3.OrthoNormalize(ref secondaryAxis, ref script.cross);
|
||||
script.mainAxis = secondaryAxis;
|
||||
}
|
||||
else if (GUILayout.Button("Align To Child Z"))
|
||||
{
|
||||
Vector3 toChild = (childGO.transform.position - script.transform.position).normalized;
|
||||
script.cross = script.transform.InverseTransformDirection(toChild);
|
||||
Vector3 secondaryAxis = script.transform.InverseTransformDirection(script.transform.forward);
|
||||
Vector3.OrthoNormalize(ref secondaryAxis, ref script.cross);
|
||||
script.mainAxis = secondaryAxis;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (GUILayout.Button("Align To X"))
|
||||
{
|
||||
Vector3 toChild = script.transform.right;
|
||||
script.mainAxis = script.transform.InverseTransformDirection(toChild.normalized);
|
||||
Vector3 secondaryAxis = new Vector3(script.mainAxis.y, script.mainAxis.z, script.mainAxis.x);
|
||||
script.cross = Vector3.Cross(script.mainAxis, secondaryAxis);
|
||||
}
|
||||
|
||||
if (GUILayout.Button("Align To Y"))
|
||||
{
|
||||
Vector3 toChild = script.transform.up;
|
||||
script.mainAxis = script.transform.InverseTransformDirection(toChild.normalized);
|
||||
Vector3 secondaryAxis = new Vector3(script.mainAxis.y, script.mainAxis.z, script.mainAxis.x);
|
||||
script.cross = Vector3.Cross(script.mainAxis, secondaryAxis);
|
||||
}
|
||||
|
||||
if (GUILayout.Button("Align To Z"))
|
||||
{
|
||||
Vector3 toChild = script.transform.forward;
|
||||
script.mainAxis = script.transform.InverseTransformDirection(toChild.normalized);
|
||||
Vector3 secondaryAxis = new Vector3(script.mainAxis.y, script.mainAxis.z, script.mainAxis.x);
|
||||
script.cross = Vector3.Cross(script.mainAxis, secondaryAxis);
|
||||
}
|
||||
}
|
||||
|
||||
if (GUI.changed) EditorUtility.SetDirty(script);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void UpdateZeroTransform()
|
||||
{
|
||||
if (lastHingeOffset != script.hingeAngleOffset)
|
||||
{
|
||||
lastHingeOffset = script.hingeAngleOffset;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void OnSceneGUI()
|
||||
{
|
||||
if (!Application.isPlaying && !script.zeroRotationOverride) script.zeroRotation = script.transform.localRotation;
|
||||
if (script.mainAxis == Vector3.zero || script.cross == Vector3.zero) return;
|
||||
|
||||
float minBoneLength = 0.15f;
|
||||
float boneLength = minBoneLength;
|
||||
if (script.transform.childCount > 0)
|
||||
{
|
||||
boneLength = Vector3.Distance(script.transform.position, script.transform.GetChild(0).position) / 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (script.transform.parent != null)
|
||||
{
|
||||
boneLength = Vector3.Distance(script.transform.position, script.transform.parent.position) / 4;
|
||||
}
|
||||
}
|
||||
|
||||
boneLength = Mathf.Max(boneLength, minBoneLength);
|
||||
|
||||
|
||||
// Display the main axis
|
||||
DrawArrow(script.transform.position, Direction(script.mainAxis), colorDefault, "Axis", 0.02f);
|
||||
|
||||
Handles.color = Color.white;
|
||||
GUI.color = Color.white;
|
||||
|
||||
if (!Application.isPlaying)
|
||||
{
|
||||
|
||||
// Selecting points
|
||||
Handles.color = colorHandles;
|
||||
Handles.Button(script.transform.position + Direction(script.mainAxis), script.transform.rotation, 0.02f, 0.02f, Handles.DotHandleCap);
|
||||
|
||||
Vector3 selectedPoint = script.mainAxis;
|
||||
|
||||
// Store point for undo
|
||||
Vector3 oldPoint = selectedPoint;
|
||||
|
||||
// Manual input for the point position
|
||||
AddVector3(ref selectedPoint, "Point", script, GUILayout.Width(210));
|
||||
|
||||
// Moving Points
|
||||
Vector3 pointWorld = Handles.PositionHandle(script.transform.position + Direction(selectedPoint), Quaternion.identity);
|
||||
Vector3 newPoint = InverseDirection(pointWorld - script.transform.position);
|
||||
if (newPoint != selectedPoint)
|
||||
{
|
||||
if (!Application.isPlaying) Undo.RecordObject(script, "Move Limit Point");
|
||||
script.mainAxis = newPoint.normalized;
|
||||
}
|
||||
}
|
||||
|
||||
DrawHingeLimits(boneLength);
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void DrawHingeLimits(float boneLength)
|
||||
{
|
||||
Quaternion offsetRot = Quaternion.Euler(script.limitsOffset);
|
||||
|
||||
Vector3 swing = Direction(offsetRot * script.mainAxis.normalized);
|
||||
|
||||
//Vector3 secondaryAxis = new Vector3(script.mainAxis.y, script.mainAxis.z, script.mainAxis.x);
|
||||
//Vector3 cross = Direction(Vector3.Cross(script.mainAxis, secondaryAxis));
|
||||
if (script.cross.magnitude == 0) return;
|
||||
Vector3 cross = Direction(offsetRot * script.cross);
|
||||
Vector3.OrthoNormalize(ref swing, ref cross);
|
||||
Vector3 secondaryAxis = Vector3.Cross(script.mainAxis, cross);
|
||||
|
||||
Handles.CircleHandleCap(0, script.transform.position, Quaternion.LookRotation(swing, cross), boneLength, EventType.Repaint);
|
||||
|
||||
//DrawArrow(script.transform.position, cross * boneLength, colorDefault, " 0", 0.02f);
|
||||
DrawArrow(script.transform.position, cross * boneLength, colorDefault, " 0", 0.02f);
|
||||
|
||||
Quaternion hingeOffset = Quaternion.AngleAxis(script.hingeAngleOffset, swing);
|
||||
|
||||
// Arcs for the rotation limit
|
||||
Handles.color = colorDefaultTransparent;
|
||||
Handles.DrawSolidArc(script.transform.position, swing, hingeOffset * cross, -script.limitAngle, boneLength);
|
||||
Handles.DrawSolidArc(script.transform.position, swing, hingeOffset * cross, script.limitAngle, boneLength);
|
||||
|
||||
Quaternion minRotation = Quaternion.AngleAxis(-script.limitAngle, swing);
|
||||
Vector3 minHandleDir = minRotation * (hingeOffset * cross);
|
||||
Handles.DrawLine(script.transform.position, script.transform.position + minHandleDir.normalized * boneLength);
|
||||
|
||||
Quaternion maxRotation = Quaternion.AngleAxis(script.limitAngle, swing);
|
||||
Vector3 maxHandleDir = maxRotation * (hingeOffset * cross);
|
||||
Handles.DrawLine(script.transform.position, script.transform.position + maxHandleDir.normalized * boneLength);
|
||||
|
||||
Handles.color = colorHandles;
|
||||
//Draw Editable Handles
|
||||
float originalLimit = script.limitAngle;
|
||||
float limitAngleMin = script.limitAngle;
|
||||
limitAngleMin = DrawLimitHandle(limitAngleMin, script.transform.position + (minHandleDir.normalized * boneLength * 1.25f), Quaternion.identity, 0.5f, "Limit", -10);
|
||||
if (limitAngleMin != script.limitAngle)
|
||||
{
|
||||
if (!Application.isPlaying) Undo.RecordObject(script, "Min Limit");
|
||||
script.limitAngle = limitAngleMin;
|
||||
script.hingeAngleOffset -= (limitAngleMin - originalLimit);
|
||||
}
|
||||
|
||||
originalLimit = script.limitAngle;
|
||||
//Draw Editable Handles
|
||||
float limitAngleMax = script.limitAngle;
|
||||
limitAngleMax = DrawLimitHandle(limitAngleMax, script.transform.position + (maxHandleDir.normalized * boneLength * 1.25f), Quaternion.identity, 0.5f, "Limit", 10);
|
||||
if (limitAngleMax != script.limitAngle)
|
||||
{
|
||||
if (!Application.isPlaying) Undo.RecordObject(script, "Max Limit");
|
||||
script.limitAngle = limitAngleMax;
|
||||
script.hingeAngleOffset += (limitAngleMax - originalLimit);
|
||||
}
|
||||
|
||||
// clamp limits
|
||||
script.limitAngle = Mathf.Clamp(script.limitAngle, 0, 180f);
|
||||
if (script.hingeAngleOffset < 0) script.hingeAngleOffset += 360;
|
||||
if (script.hingeAngleOffset > 360) script.hingeAngleOffset -= 360;
|
||||
|
||||
}
|
||||
|
||||
private Vector3 Direction(Vector3 v)
|
||||
{
|
||||
if (script.transform.parent == null) return script.zeroRotation * v;
|
||||
return script.transform.parent.rotation * (script.zeroRotation * v);
|
||||
}
|
||||
|
||||
private Vector3 InverseDirection(Vector3 v)
|
||||
{
|
||||
if (script.transform.parent == null) return Quaternion.Inverse(script.zeroRotation) * v;
|
||||
|
||||
return Quaternion.Inverse(script.zeroRotation) * Quaternion.Inverse(script.transform.parent.rotation) * v;
|
||||
}
|
||||
|
||||
// Universal color pallettes
|
||||
public static Color colorDefault { get { return new Color(0.0f, 0.0f, 1.0f, 1.0f); } }
|
||||
|
||||
public static Color colorDefaultTransparent
|
||||
{
|
||||
get
|
||||
{
|
||||
Color d = colorDefault;
|
||||
return new Color(d.r, d.g, d.b, 0.2f);
|
||||
}
|
||||
}
|
||||
|
||||
public static Color colorHandles { get { return new Color(1.0f, 0.5f, 0.25f, 1.0f); } }
|
||||
public static Color colorRotationSphere { get { return new Color(1.0f, 1.0f, 1.0f, 0.1f); } }
|
||||
public static Color colorInvalid { get { return new Color(1.0f, 0.3f, 0.3f, 1.0f); } }
|
||||
public static Color colorValid { get { return new Color(0.2f, 1.0f, 0.2f, 1.0f); } }
|
||||
|
||||
/*
|
||||
* Draws a custom arrow to the scene
|
||||
* */
|
||||
public static void DrawArrow(Vector3 position, Vector3 direction, Color color, string label = "", float size = 0.01f)
|
||||
{
|
||||
Handles.color = color;
|
||||
Handles.DrawLine(position, position + direction);
|
||||
Handles.SphereHandleCap(0, position + direction, Quaternion.identity, size, EventType.Repaint);
|
||||
Handles.color = Color.white;
|
||||
|
||||
if (label != "")
|
||||
{
|
||||
GUI.color = color;
|
||||
Handles.Label(position + direction, label);
|
||||
GUI.color = Color.white;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Draws a handle for adjusting rotation limits in the scene
|
||||
* */
|
||||
public static float DrawLimitHandle(float limit, Vector3 position, Quaternion rotation, float radius, string label, float openingValue, bool reverseScaleDirection = false)
|
||||
{
|
||||
float scaleFactor = reverseScaleDirection ? -1 : 1;
|
||||
|
||||
limit = scaleFactor * Handles.ScaleValueHandle(limit, position, rotation, radius, Handles.SphereHandleCap, 1);
|
||||
|
||||
string labelInfo = label + ": " + limit.ToString();
|
||||
|
||||
// If value is 0, draw a button to 'open' the value, because we cant scale 0
|
||||
if (limit == 0)
|
||||
{
|
||||
labelInfo = "Open " + label;
|
||||
|
||||
if (Handles.Button(position, rotation, radius * 0.2f, radius * 0.07f, Handles.SphereHandleCap))
|
||||
{
|
||||
limit = openingValue;
|
||||
}
|
||||
}
|
||||
|
||||
Handles.Label(position, labelInfo);
|
||||
|
||||
return limit;
|
||||
}
|
||||
|
||||
|
||||
public static void AddVector3(ref Vector3 input, string name, Object undoObject, params GUILayoutOption[] options)
|
||||
{
|
||||
Vector3 newValue = EditorGUILayout.Vector3Field(name, input, options);
|
||||
|
||||
if (newValue != input && !Application.isPlaying)
|
||||
{
|
||||
Undo.RecordObject(undoObject, name);
|
||||
}
|
||||
|
||||
input = newValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: be8d162414d22194399e23501b403f03
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 174069
|
||||
packageName: Hybrid IK
|
||||
packageVersion: 1.02
|
||||
assetPath: Assets/HybridIK/Scripts/Joint Limits/Editor/DynamicJointLimitHingeInspector.cs
|
||||
uploadId: 532533
|
||||
@@ -0,0 +1,248 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
|
||||
namespace AshqarApps.DynamicJoint
|
||||
{
|
||||
[CustomEditor(typeof(DynamicJointLimitSwingTwist))]
|
||||
[CanEditMultipleObjects]
|
||||
public class DynamicJointLimitSwingTwistInspector : Editor
|
||||
{
|
||||
private DynamicJointLimitSwingTwist script { get { return target as DynamicJointLimitSwingTwist; } }
|
||||
private int axisComponentSelected = 0;
|
||||
private Vector3 lastPoint, zeroPoint;
|
||||
private int selectedChild = 0;
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
base.OnInspectorGUI();
|
||||
|
||||
int childCount = script.transform.childCount;
|
||||
|
||||
if (childCount == 1 && GUILayout.Button("Align To Child"))
|
||||
{
|
||||
Vector3 toChild = script.transform.GetChild(0).position - script.transform.position;
|
||||
script.mainAxis = script.transform.InverseTransformDirection(toChild.normalized);
|
||||
if (GUI.changed) EditorUtility.SetDirty(script);
|
||||
}
|
||||
else if (childCount > 1)
|
||||
{
|
||||
List<string> childGOs = new List<string>();
|
||||
|
||||
//if (childGOs == null)
|
||||
{
|
||||
for (int i = 0; i < script.transform.childCount; ++i)
|
||||
{
|
||||
childGOs.Add(script.transform.GetChild(i).name);
|
||||
}
|
||||
}
|
||||
|
||||
selectedChild = EditorGUILayout.Popup("Selected Child", selectedChild, childGOs.ToArray());
|
||||
|
||||
//int selectedChild = 0;
|
||||
if (GUILayout.Button("Align To Selected Child"))
|
||||
{
|
||||
GameObject childGO = script.transform.GetChild(selectedChild).gameObject;
|
||||
|
||||
if (childGO.transform.childCount > 0)
|
||||
{
|
||||
childGO = childGO.transform.GetChild(0).gameObject;
|
||||
|
||||
Vector3 toChild = childGO.transform.position - script.transform.position;
|
||||
script.mainAxis = script.transform.InverseTransformDirection(toChild.normalized);
|
||||
if (GUI.changed) EditorUtility.SetDirty(script);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OnSceneGUI()
|
||||
{
|
||||
// Set defaultLocalRotation so that the initial local rotation will be the zero point for the rotation limit
|
||||
if (!Application.isPlaying && !script.zeroRotationOverride) script.zeroRotation = script.transform.localRotation;
|
||||
if (script.mainAxis == Vector3.zero) return;
|
||||
|
||||
//DrawRotationSphere(script.transform.position);
|
||||
|
||||
Handles.color = Color.white;
|
||||
GUI.color = Color.white;
|
||||
|
||||
float minBoneLength = 0.15f;
|
||||
float boneLength = minBoneLength;
|
||||
if (script.transform.childCount > 0)
|
||||
{
|
||||
boneLength = Vector3.Distance(script.transform.position, script.transform.GetChild(0).position) / 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (script.transform.parent != null)
|
||||
{
|
||||
boneLength = Vector3.Distance(script.transform.position, script.transform.parent.position) / 4;
|
||||
}
|
||||
}
|
||||
boneLength = Mathf.Max(boneLength, minBoneLength);
|
||||
|
||||
// Display the main axis
|
||||
DrawArrow(script.transform.position, Direction(script.mainAxis).normalized * boneLength, colorDefault, "Axis", 0.02f);
|
||||
DrawArrow(script.transform.position, Direction(script.secondaryAxis) * boneLength, colorDefault, "Secondary Axis", 0.02f);
|
||||
|
||||
if (!Application.isPlaying)
|
||||
{
|
||||
// Selecting points
|
||||
Handles.color = colorHandles;
|
||||
if (Handles.Button(script.transform.position + Direction(script.mainAxis.normalized) * boneLength * 1.25f, script.transform.rotation, 0.02f, 0.02f, Handles.DotHandleCap))
|
||||
{
|
||||
axisComponentSelected = 0;
|
||||
}
|
||||
else if (Handles.Button(script.transform.position + Direction(script.secondaryAxis.normalized) * boneLength * 1.25f, script.transform.rotation, 0.02f, 0.02f, Handles.DotHandleCap))
|
||||
{
|
||||
axisComponentSelected = 1;
|
||||
}
|
||||
|
||||
Vector3 selectedPoint = axisComponentSelected == 0 ? script.mainAxis : script.secondaryAxis;
|
||||
|
||||
// Store point for undo
|
||||
Vector3 oldPoint = selectedPoint;
|
||||
|
||||
// Manual input for the point position
|
||||
AddVector3(ref selectedPoint, "Point", script, GUILayout.Width(210));
|
||||
//EditorGUILayout.Space();
|
||||
|
||||
// Moving Points
|
||||
Vector3 pointWorld = Handles.PositionHandle(script.transform.position + (Direction(selectedPoint.normalized) * boneLength * 1.25f), Quaternion.identity);
|
||||
Vector3 newPoint = InverseDirection(pointWorld - script.transform.position);
|
||||
if (newPoint != selectedPoint)
|
||||
{
|
||||
if (!Application.isPlaying) Undo.RecordObject(script, "Move Limit Point");
|
||||
if (axisComponentSelected == 0)
|
||||
script.mainAxis = newPoint;
|
||||
else
|
||||
script.secondaryAxis = newPoint;
|
||||
}
|
||||
}
|
||||
|
||||
Vector3.OrthoNormalize(ref script.mainAxis, ref script.secondaryAxis);
|
||||
|
||||
DrawSwingTwistLimits(boneLength);
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void DrawSwingTwistLimits(float boneLength)
|
||||
{
|
||||
Vector3 swing = script.mainAxis.normalized;
|
||||
Vector3 secondaryAxis = script.secondaryAxis.normalized; //new Vector3(swing.y, swing.z, swing.x);
|
||||
Vector3.OrthoNormalize(ref swing, ref secondaryAxis);
|
||||
Vector3 cross = Vector3.Cross(swing, secondaryAxis);
|
||||
|
||||
// DRAW TWIST
|
||||
Quaternion offsetRot = Quaternion.Euler(script.limitsOffset);
|
||||
Handles.color = colorTwistLimit;
|
||||
Handles.DrawSolidArc(script.transform.position, Direction(offsetRot * swing), Direction(offsetRot * cross), script.twistLimit, boneLength);
|
||||
Handles.DrawSolidArc(script.transform.position, Direction(offsetRot * swing), Direction(offsetRot * cross), -script.twistLimit, boneLength);
|
||||
|
||||
// Display limits
|
||||
lastPoint = script.transform.position;
|
||||
|
||||
for (int i = 0; i < 360; i += 2)
|
||||
{
|
||||
//float evaluatedLimit = script.EvaluateSwingLimitAtOrthoAngle((float)(i));
|
||||
//float evaluatedLimit = script.curveX.Evaluate(Mathf.Abs(Mathf.Sin()));
|
||||
|
||||
Quaternion offset = Quaternion.AngleAxis(i, swing);
|
||||
Quaternion evaluatedRotation = Quaternion.AngleAxis(script.limitAngle, offset * (cross));
|
||||
|
||||
Color color = colorDefaultTransparent;
|
||||
|
||||
Vector3 swingAxis = script.LimitSwing(evaluatedRotation, visualizeMode: true) * swing;
|
||||
swingAxis = offsetRot * swingAxis;
|
||||
|
||||
Vector3 limitPoint = script.transform.position + Direction(swingAxis).normalized * boneLength;
|
||||
Handles.DrawLine(script.transform.position, script.transform.position + Direction(swingAxis).normalized * boneLength);
|
||||
|
||||
Handles.color = color;
|
||||
if (i == 0) zeroPoint = limitPoint;
|
||||
|
||||
if (i > 0)
|
||||
{
|
||||
Handles.color = colorDefault;
|
||||
Handles.DrawLine(limitPoint, lastPoint);
|
||||
if (i == 358) Handles.DrawLine(limitPoint, zeroPoint);
|
||||
}
|
||||
|
||||
lastPoint = limitPoint;
|
||||
}
|
||||
}
|
||||
|
||||
private Vector3 Direction(Vector3 v)
|
||||
{
|
||||
if (script.transform.parent == null) return script.zeroRotation * v;
|
||||
return script.transform.parent.rotation * (script.zeroRotation * v);
|
||||
}
|
||||
|
||||
private Vector3 InverseDirection(Vector3 v)
|
||||
{
|
||||
if (script.transform.parent == null) return Quaternion.Inverse(script.zeroRotation) * v;
|
||||
|
||||
return Quaternion.Inverse(script.zeroRotation) * Quaternion.Inverse(script.transform.parent.rotation) * v;
|
||||
}
|
||||
|
||||
public static Color colorDefault { get { return new Color(0.0f, 1.0f, 1.0f, 0.5f); } }
|
||||
public static Color colorDefaultTransparent
|
||||
{
|
||||
get
|
||||
{
|
||||
Color d = colorDefault;
|
||||
return new Color(d.r, d.g, d.b, 0.2f);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static Color colorHandles { get { return new Color(1.0f, 0.5f, 0.25f, 1.0f); } }
|
||||
public static Color colorRotationSphere { get { return new Color(1.0f, 1.0f, 1.0f, 0.1f); } }
|
||||
public static Color colorTwistLimit { get { return new Color(1.0f, 1.0f, 0.0f, 0.1f); } }
|
||||
public static Color colorInvalid { get { return new Color(1.0f, 0.3f, 0.3f, 1.0f); } }
|
||||
public static Color colorValid { get { return new Color(0.2f, 1.0f, 0.2f, 1.0f); } }
|
||||
|
||||
/*
|
||||
* Draws the default rotation limit sphere to the scene
|
||||
* */
|
||||
public static void DrawRotationSphere(Vector3 position, float radius)
|
||||
{
|
||||
Handles.color = colorRotationSphere;
|
||||
Handles.SphereHandleCap(0, position, Quaternion.identity, radius, EventType.Repaint);
|
||||
Handles.color = Color.white;
|
||||
}
|
||||
|
||||
/*
|
||||
* Draws a custom arrow to the scene
|
||||
* */
|
||||
public static void DrawArrow(Vector3 position, Vector3 direction, Color color, string label = "", float size = 0.01f)
|
||||
{
|
||||
Handles.color = color;
|
||||
Handles.DrawLine(position, position + direction);
|
||||
Handles.SphereHandleCap(0, position + direction, Quaternion.identity, size, EventType.Repaint);
|
||||
Handles.color = Color.white;
|
||||
|
||||
if (label != "")
|
||||
{
|
||||
GUI.color = color;
|
||||
Handles.Label(position + direction, label);
|
||||
GUI.color = Color.white;
|
||||
}
|
||||
}
|
||||
|
||||
public static void AddVector3(ref Vector3 input, string name, Object undoObject, params GUILayoutOption[] options)
|
||||
{
|
||||
Vector3 newValue = EditorGUILayout.Vector3Field(name, input, options);
|
||||
|
||||
if (newValue != input && !Application.isPlaying)
|
||||
{
|
||||
Undo.RecordObject(undoObject, name);
|
||||
}
|
||||
|
||||
input = newValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 64e32b8cc7ffc8545adde630370be74d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 174069
|
||||
packageName: Hybrid IK
|
||||
packageVersion: 1.02
|
||||
assetPath: Assets/HybridIK/Scripts/Joint Limits/Editor/DynamicJointLimitSwingTwistInspector.cs
|
||||
uploadId: 532533
|
||||
8
Assets/HybridIK/Scripts/Main.meta
Normal file
8
Assets/HybridIK/Scripts/Main.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0b57a501956808744a6f4c77d47aa9ac
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/HybridIK/Scripts/Main/Editor.meta
Normal file
8
Assets/HybridIK/Scripts/Main/Editor.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 85bff82fc19c984458a58f9f4d097ed8
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
312
Assets/HybridIK/Scripts/Main/Editor/HybridIKNodeInspector.cs
Normal file
312
Assets/HybridIK/Scripts/Main/Editor/HybridIKNodeInspector.cs
Normal file
@@ -0,0 +1,312 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
|
||||
[CustomEditor(typeof(HybridInverseKinematicsNode))]
|
||||
public class HybridIKNodeInspector : Editor
|
||||
{
|
||||
private HybridInverseKinematicsNode hybridIKNode { get { return target as HybridInverseKinematicsNode; } }
|
||||
List<string> boneHierarchy = new List<string>();
|
||||
|
||||
private int selectedIKNodeIndex = -1;
|
||||
|
||||
private int selectedIKKeyframe = -1;
|
||||
|
||||
public void DeletePoseKeyframe(int selectedPose)
|
||||
{
|
||||
foreach (HybridIKConstraint c in hybridIKNode.constraints)
|
||||
{
|
||||
if (c.positionKeys.Count > 0)
|
||||
{
|
||||
c.positionKeys.RemoveAt(selectedPose);
|
||||
}
|
||||
}
|
||||
foreach (HybridIKJoint node in hybridIKNode.nodes)
|
||||
{
|
||||
node.keyedPositions.RemoveAt(selectedPose);
|
||||
node.keyedLocalPositions.RemoveAt(selectedPose);
|
||||
node.keyedRotations.RemoveAt(selectedPose);
|
||||
}
|
||||
|
||||
selectedIKKeyframe = -1;
|
||||
hybridIKNode.ResetToZeroPose();
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
if (selectedIKKeyframe >= 0)
|
||||
{
|
||||
if (GUILayout.Button("Select Full Chain"))
|
||||
{
|
||||
selectedIKKeyframe = -1;
|
||||
}
|
||||
|
||||
if (selectedIKKeyframe >= 0)
|
||||
{
|
||||
GUILayout.Label("IK Keyframe " + selectedIKKeyframe.ToString() + " selected");
|
||||
if (GUILayout.Button("Delete Pose Keyframe"))
|
||||
{
|
||||
DeletePoseKeyframe(selectedIKKeyframe);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (selectedIKNodeIndex >= 0)
|
||||
{
|
||||
HybridIKJoint selectedNode = hybridIKNode.nodes[selectedIKNodeIndex];
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
if (selectedNode.jointTransform != null)
|
||||
{
|
||||
if (GUILayout.Button("Select Joint GameObject"))
|
||||
{
|
||||
Selection.activeGameObject = selectedNode.jointTransform.gameObject;
|
||||
}
|
||||
}
|
||||
if (GUILayout.Button("Select Full Chain"))
|
||||
{
|
||||
selectedIKNodeIndex = -1;
|
||||
}
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
if (selectedIKNodeIndex >= 0)
|
||||
{
|
||||
GUILayout.Label("IK Node " + selectedIKNodeIndex.ToString() + " selected");
|
||||
selectedNode.jointRadius = EditorGUILayout.FloatField("Node Radius", selectedNode.jointRadius);
|
||||
var oldColor = GUI.backgroundColor;
|
||||
GUILayout.Label("CONSTRAINTS MODE");
|
||||
GUILayout.BeginHorizontal();
|
||||
if (selectedNode.enableKeyframeConstraints && !selectedNode.overrideConstraint) GUI.backgroundColor = Color.green;
|
||||
if (GUILayout.Button("KEYFRAMED"))
|
||||
{
|
||||
selectedNode.enableKeyframeConstraints = true;
|
||||
selectedNode.overrideConstraint = false;
|
||||
hybridIKNode.ReprocessJoints();
|
||||
}
|
||||
GUI.backgroundColor = oldColor;
|
||||
if (selectedNode.overrideConstraint) GUI.backgroundColor = Color.green;
|
||||
if (GUILayout.Button("MANUAL CONSTRAINT"))
|
||||
{
|
||||
selectedNode.enableKeyframeConstraints = false;
|
||||
selectedNode.overrideConstraint = true;
|
||||
hybridIKNode.ReprocessJoints();
|
||||
}
|
||||
GUI.backgroundColor = oldColor;
|
||||
if (!selectedNode.enableKeyframeConstraints && !selectedNode.overrideConstraint) GUI.backgroundColor = Color.green;
|
||||
if (GUILayout.Button("NONE"))
|
||||
{
|
||||
selectedNode.enableKeyframeConstraints = false;
|
||||
selectedNode.overrideConstraint = false;
|
||||
hybridIKNode.ReprocessJoints();
|
||||
}
|
||||
GUILayout.EndHorizontal();
|
||||
GUI.backgroundColor = oldColor;
|
||||
|
||||
if (selectedNode.overrideConstraint)
|
||||
{
|
||||
//n.position = EditorGUILayout.Vector3Field("Target Position", node.position);
|
||||
selectedNode.constraint.jointTransform = selectedNode.jointTransform;
|
||||
selectedNode.constraint.targetTransform = EditorGUILayout.ObjectField("Target Transform", selectedNode.constraint.targetTransform, typeof(Transform), true) as Transform;
|
||||
|
||||
selectedNode.constraint.constrainPosition = EditorGUILayout.Toggle("Constrain Position", selectedNode.constraint.constrainPosition);
|
||||
selectedNode.constraint.constrainRotation = EditorGUILayout.Toggle("Constrain Orientation", selectedNode.constraint.constrainRotation);
|
||||
}
|
||||
|
||||
selectedNode.enableStretch = EditorGUILayout.Toggle("Enable Stretch", selectedNode.enableStretch);
|
||||
if (selectedNode.enableStretch)
|
||||
{
|
||||
if (selectedNode.stretchLimits == null)
|
||||
{
|
||||
selectedNode.stretchLimits = new HybridIKNodeStretchLimits();
|
||||
}
|
||||
|
||||
selectedNode.stretchLimits.targetSpace = EditorGUILayout.ObjectField("Target Transform", selectedNode.stretchLimits.targetSpace, typeof(Transform), true) as Transform;
|
||||
|
||||
selectedNode.stretchLimits.minStretchLimits = EditorGUILayout.Vector3Field("Min Stretch Limits", selectedNode.stretchLimits.minStretchLimits);
|
||||
selectedNode.stretchLimits.maxStretchLimits = EditorGUILayout.Vector3Field("Max Stretch Limits", selectedNode.stretchLimits.maxStretchLimits);
|
||||
}
|
||||
|
||||
if (GUI.changed) EditorUtility.SetDirty(hybridIKNode);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (GUILayout.Button("Process IK Joint Chain"))
|
||||
{
|
||||
hybridIKNode.ResetAll();
|
||||
hybridIKNode.ProcessChain();
|
||||
}
|
||||
if (hybridIKNode.nodes != null)
|
||||
{
|
||||
if (GUILayout.Button("Set Zero Rotations to Current Pose"))
|
||||
{
|
||||
foreach (HybridIKJoint node in hybridIKNode.nodes)
|
||||
{
|
||||
node.zeroRotation = node.jointTransform.localRotation;
|
||||
node.zeroPosition = node.jointTransform.localPosition;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
base.OnInspectorGUI();
|
||||
if (hybridIKNode.nodes == null) return;
|
||||
|
||||
if (hybridIKNode.constraints == null || hybridIKNode.constraints.Count == 0)
|
||||
{
|
||||
hybridIKNode.constraints = new List<HybridIKConstraint>();
|
||||
foreach (HybridIKJoint node in hybridIKNode.nodes)
|
||||
{
|
||||
node.keyedLocalPositions = new List<Vector3>();
|
||||
node.keyedPositions = new List<Vector3>();
|
||||
node.keyedRotations = new List<Quaternion>();
|
||||
}
|
||||
}
|
||||
|
||||
if (hybridIKNode.constraints != null)// && hybridIKNode.constraints.Count > 0)
|
||||
{
|
||||
//EditorGUILayout.LabelField("Keyframe Constraints", EditorStyles.boldLabel);
|
||||
if (GUILayout.Button("Add Joints Pose Keyframe"))
|
||||
{
|
||||
List<int> keyframeState = new List<int>();
|
||||
foreach(HybridIKJoint j in hybridIKNode.nodes)
|
||||
{
|
||||
keyframeState.Add(j.enableKeyframeConstraints ? 0 : j.overrideConstraint ? 1 : 2);
|
||||
j.enableKeyframeConstraints = true; j.overrideConstraint = false;
|
||||
}
|
||||
|
||||
hybridIKNode.ReprocessJoints();
|
||||
|
||||
HybridIKJoint root = hybridIKNode.nodes[0];
|
||||
Transform parent = root.jointTransform.parent;
|
||||
|
||||
foreach (HybridIKJoint node in hybridIKNode.nodes)
|
||||
{
|
||||
// encode rotation
|
||||
if (node.keyedRotations == null)
|
||||
node.keyedRotations = new List<Quaternion>();
|
||||
node.keyedRotations.Add(node.jointTransform.localRotation);
|
||||
|
||||
//encode local positions used for stretch
|
||||
if (node.keyedLocalPositions == null)
|
||||
node.keyedLocalPositions = new List<Vector3>();
|
||||
node.keyedLocalPositions.Add(node.jointTransform.localPosition);
|
||||
|
||||
// encode position in parent space
|
||||
if (node.keyedPositions == null)
|
||||
node.keyedPositions = new List<Vector3>();
|
||||
node.keyedPositions.Add(parent != null ? parent.InverseTransformPoint(node.GetCurrentPositionWorld()) : node.GetCurrentPositionWorld());
|
||||
|
||||
HybridIKConstraint constraint = hybridIKNode.constraints.Find(c => c.jointTransform == node.jointTransform);
|
||||
if (constraint == null)
|
||||
{
|
||||
constraint = new HybridIKConstraint();
|
||||
constraint.jointTransform = node.jointTransform;
|
||||
constraint.constrainPosition = true;
|
||||
hybridIKNode.constraints.Add(constraint);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (HybridIKConstraint c in hybridIKNode.constraints)
|
||||
{
|
||||
ConstraintPositionKey key = new ConstraintPositionKey();
|
||||
if (c.positionKeys == null) c.positionKeys = new List<ConstraintPositionKey>();
|
||||
key.constraintPositionValue = c.jointTransform.position;
|
||||
|
||||
Vector3 endPos = parent != null ? parent.InverseTransformPoint(hybridIKNode.endNode.position) : hybridIKNode.endNode.position;
|
||||
key.SetEndTargetPosition(hybridIKNode.endNode.position, parent);
|
||||
c.positionKeys.Add(key);
|
||||
}
|
||||
hybridIKNode.ResetToZeroPose();
|
||||
}
|
||||
|
||||
if (hybridIKNode.nodes != null && hybridIKNode.nodes.Count > 0 && hybridIKNode.nodes[0] != null && hybridIKNode.nodes[0].keyedPositions != null)
|
||||
{
|
||||
for (int p = 0; p < hybridIKNode.nodes[0].keyedPositions.Count; ++p)
|
||||
{
|
||||
GUILayout.BeginHorizontal();
|
||||
GUILayout.Label("Key Pose " + (p + 1).ToString());
|
||||
if (GUILayout.Button("Select"))
|
||||
{
|
||||
//selectedIKKeyframe = p;
|
||||
hybridIKNode.PoseToKeyframe(p);
|
||||
Repaint();
|
||||
}
|
||||
if (GUILayout.Button("Delete Key"))
|
||||
{
|
||||
DeletePoseKeyframe(p);
|
||||
}
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (GUI.changed) EditorUtility.SetDirty(hybridIKNode);
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
if (!Application.isPlaying)
|
||||
hybridIKNode.ResetToZeroPose();
|
||||
}
|
||||
|
||||
public void OnSceneGUI()
|
||||
{
|
||||
if (hybridIKNode.nodes == null || hybridIKNode.nodes.Count == 0) return;
|
||||
|
||||
Color originalColor = Handles.color;
|
||||
if (hybridIKNode.IsInitialized())
|
||||
{
|
||||
for (int i = 0; i < hybridIKNode.nodes.Count; ++i)
|
||||
//foreach (SweepIKNode n in hybridIKNode.nodes)
|
||||
{
|
||||
HybridIKJoint n = hybridIKNode.nodes[i];
|
||||
Color c = n.enableKeyframeConstraints ? Color.blue : n.overrideConstraint ? Color.cyan : originalColor;
|
||||
Handles.color = selectedIKNodeIndex == i ? Color.green : c;
|
||||
float nRadius = Mathf.Max(n.jointRadius, 0.05f, n.jointRadius);
|
||||
if (Handles.Button(n.GetCurrentPositionWorld(), Quaternion.identity, nRadius, nRadius,Handles.SphereHandleCap))
|
||||
{
|
||||
selectedIKNodeIndex = i;
|
||||
selectedIKKeyframe = -1;
|
||||
if (!Application.isPlaying)
|
||||
hybridIKNode.ResetToZeroPose();
|
||||
Repaint();
|
||||
}
|
||||
}
|
||||
|
||||
HybridIKJoint root = hybridIKNode.GetRootIKNode();
|
||||
HybridIKJoint endIKNode = hybridIKNode.GetEndIKNode();
|
||||
|
||||
Transform parentSpace = root.jointTransform.parent;
|
||||
|
||||
foreach (HybridIKConstraint c in hybridIKNode.constraints)
|
||||
{
|
||||
if (c.positionKeys.Count > 0)
|
||||
{
|
||||
for (int i = 0; i < c.positionKeys.Count; ++i)
|
||||
{
|
||||
ConstraintPositionKey k = c.positionKeys[i];
|
||||
Handles.color = selectedIKKeyframe == i ? Color.green : originalColor;
|
||||
if (i % 4 == 0) Handles.color = Color.green;
|
||||
if (i % 4 == 1) Handles.color = Color.blue;
|
||||
if (i % 4 == 2) Handles.color = Color.yellow;
|
||||
if (i % 4 == 3) Handles.color = Color.magenta;
|
||||
|
||||
Vector3 buttonPos = k.GetEndTargetPosition(endIKNode.targetIKSpace != null ? endIKNode.targetIKSpace : parentSpace);
|
||||
|
||||
if (Handles.Button(buttonPos, Quaternion.identity, endIKNode.jointRadius, endIKNode.jointRadius, Handles.SphereHandleCap))
|
||||
{
|
||||
selectedIKKeyframe = i;
|
||||
selectedIKNodeIndex = -1;
|
||||
|
||||
hybridIKNode.PoseToKeyframe(selectedIKKeyframe);
|
||||
Repaint();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Handles.color = originalColor;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4d33a09095add3f4cb5e399c4bc4b2d1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 174069
|
||||
packageName: Hybrid IK
|
||||
packageVersion: 1.02
|
||||
assetPath: Assets/HybridIK/Scripts/Main/Editor/HybridIKNodeInspector.cs
|
||||
uploadId: 532533
|
||||
85
Assets/HybridIK/Scripts/Main/HybridIKConstraint.cs
Normal file
85
Assets/HybridIK/Scripts/Main/HybridIKConstraint.cs
Normal file
@@ -0,0 +1,85 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
[System.Serializable]
|
||||
public class HybridIKConstraint
|
||||
{
|
||||
public Transform jointTransform;
|
||||
public Transform targetTransform;
|
||||
|
||||
public Vector3 targetPosition;
|
||||
public Vector3 targetLocalPosition; //used for stretch constraints
|
||||
public Quaternion targetRotation = Quaternion.identity;
|
||||
|
||||
public bool constrainPosition = true;
|
||||
public bool constrainRotation = false;
|
||||
|
||||
public Vector3 GetPosition()
|
||||
{
|
||||
if (targetTransform != null)
|
||||
return targetTransform.position;
|
||||
return targetPosition;
|
||||
}
|
||||
|
||||
public Vector3 GetLocalPosition()
|
||||
{
|
||||
//if (targetTransform != null)
|
||||
// return targetTransform.position;
|
||||
return targetLocalPosition;
|
||||
}
|
||||
|
||||
public Quaternion GetRotation()
|
||||
{
|
||||
if (targetTransform != null)
|
||||
return targetTransform.rotation;
|
||||
return targetRotation;
|
||||
}
|
||||
|
||||
public List<ConstraintPositionKey> positionKeys;
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
public class ConstraintPositionKey
|
||||
{
|
||||
public Transform endTargetKeyTransform;
|
||||
public Transform constraintKeyTransform;
|
||||
|
||||
[HideInInspector]
|
||||
public Vector3 endTargetPositionKey;
|
||||
[HideInInspector]
|
||||
public Vector3 constraintPositionValue;
|
||||
|
||||
[HideInInspector]
|
||||
public Quaternion constraintRotationValue;
|
||||
[HideInInspector]
|
||||
public float cachedWeight = 0;
|
||||
[HideInInspector]
|
||||
public float cachedFade = 0;
|
||||
|
||||
public Transform targetSpace = null;
|
||||
|
||||
public Vector3 GetEndTargetPosition(Transform rootSpace = null)
|
||||
{
|
||||
return endTargetKeyTransform != null ? endTargetKeyTransform.position :
|
||||
(rootSpace != null ? rootSpace.TransformPoint(endTargetPositionKey) : endTargetPositionKey);
|
||||
}
|
||||
|
||||
public void SetEndTargetPosition(Vector3 newPos, Transform rootSpace = null)
|
||||
{
|
||||
endTargetPositionKey = rootSpace != null ? rootSpace.InverseTransformPoint(newPos) : newPos;
|
||||
targetSpace = rootSpace;
|
||||
}
|
||||
|
||||
public Vector3 GetConstraintKeyPosition()
|
||||
{
|
||||
return constraintKeyTransform != null ? constraintKeyTransform.position : constraintPositionValue;
|
||||
}
|
||||
|
||||
public Quaternion GetConstraintKeyRotation()
|
||||
{
|
||||
return constraintKeyTransform != null ? constraintKeyTransform.rotation : constraintRotationValue;
|
||||
}
|
||||
|
||||
}
|
||||
18
Assets/HybridIK/Scripts/Main/HybridIKConstraint.cs.meta
Normal file
18
Assets/HybridIK/Scripts/Main/HybridIKConstraint.cs.meta
Normal file
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 945cb199022265a4d879826f1cf92986
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 174069
|
||||
packageName: Hybrid IK
|
||||
packageVersion: 1.02
|
||||
assetPath: Assets/HybridIK/Scripts/Main/HybridIKConstraint.cs
|
||||
uploadId: 532533
|
||||
181
Assets/HybridIK/Scripts/Main/HybridIKJoint.cs
Normal file
181
Assets/HybridIK/Scripts/Main/HybridIKJoint.cs
Normal file
@@ -0,0 +1,181 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using AshqarApps.DynamicJoint;
|
||||
|
||||
[System.Serializable]
|
||||
public class HybridIKJoint
|
||||
{
|
||||
public Transform jointTransform;
|
||||
public Quaternion initialRotation;
|
||||
public Vector3 initialPosition;
|
||||
public Vector3 initialPositionWorld;
|
||||
public Vector3 previousPositionWorld;
|
||||
|
||||
public Quaternion cachedInitialRotation;
|
||||
public Vector3 cachedLocalPosition;
|
||||
|
||||
|
||||
public Vector3 targetPosition;
|
||||
public Vector3 targetLocalPosition;
|
||||
public Vector3 stretchedTargetPosition;
|
||||
public bool isStretchNode;
|
||||
|
||||
private Vector3 ikTargetPosition;
|
||||
|
||||
public bool IsEndNode = false;
|
||||
|
||||
public HybridIKJoint child = null;
|
||||
public HybridIKJoint parent = null;
|
||||
|
||||
[HideInInspector]
|
||||
public int childIndex = -1;
|
||||
[HideInInspector]
|
||||
public int parentIndex = -1;
|
||||
|
||||
public float boneLength;
|
||||
public Vector3 toParent;
|
||||
|
||||
public bool oldVecInitialized;
|
||||
public Vector3 oldVec;
|
||||
public Quaternion rotationIK;
|
||||
|
||||
public float jointRadius;
|
||||
|
||||
public DynamicJointLimit jointLimit;
|
||||
|
||||
public bool isPositionConstrained = false;
|
||||
public bool isRotationConstrained = false;
|
||||
|
||||
public bool overrideConstraint;
|
||||
public HybridIKConstraint constraint;
|
||||
public Transform targetIKSpace = null;
|
||||
|
||||
public bool enableKeyframeConstraints = true;
|
||||
|
||||
public Vector3 cachedPosition = Vector3.zero;
|
||||
public Quaternion cachedRotation = Quaternion.identity;
|
||||
public Quaternion targetRotation = Quaternion.identity;
|
||||
public List<Quaternion> keyedRotations;
|
||||
public List<Vector3> keyedPositions;
|
||||
public List<Vector3> keyedLocalPositions;
|
||||
|
||||
public Quaternion zeroRotation = Quaternion.identity;
|
||||
public Vector3 zeroPosition = Vector3.zero;
|
||||
|
||||
public Quaternion lastFrameRotation = Quaternion.identity;
|
||||
public Vector3 lastFramePosition = Vector3.zero;
|
||||
public float currentAngularVelocity = 0;
|
||||
public float currentStretchVelocity = 0;
|
||||
|
||||
public bool enableStretch = false;
|
||||
public float inwardsStretch = 0;
|
||||
public float outwardsStretch = 0;
|
||||
public Vector3 stretchAxis = Vector3.forward;
|
||||
public HybridIKNodeStretchLimits stretchLimits;
|
||||
|
||||
// Angular Motion
|
||||
public bool overrideAngularMotion = false;
|
||||
public float maxAngularMotionVelocity = 30f;
|
||||
public float angularMotionAcceleration = 5f;
|
||||
|
||||
public void ResetToZeroTransforms()
|
||||
{
|
||||
if (parent != null)
|
||||
parent.jointTransform.localRotation = parent.zeroRotation;
|
||||
this.jointTransform.localPosition = zeroPosition;
|
||||
}
|
||||
|
||||
public bool HasIKConstraint()
|
||||
{
|
||||
return ((enableKeyframeConstraints || overrideConstraint)) && constraint != null && constraint.jointTransform != null && (constraint.constrainPosition || constraint.constrainRotation);
|
||||
}
|
||||
|
||||
public bool HasPositionConstraint()
|
||||
{
|
||||
return (enableKeyframeConstraints || overrideConstraint) && constraint != null && constraint.jointTransform != null && constraint.constrainPosition;
|
||||
}
|
||||
|
||||
public bool HasRotationConstraint()
|
||||
{
|
||||
return (enableKeyframeConstraints || overrideConstraint) && constraint != null && constraint.jointTransform != null && constraint.constrainRotation;
|
||||
}
|
||||
|
||||
public HybridIKJoint(Transform t, HybridIKJoint child, float radius = 0.1f)
|
||||
{
|
||||
if (child != null)
|
||||
{
|
||||
child.boneLength = (t.position - child.jointTransform.position).magnitude;
|
||||
child.parent = this;
|
||||
this.child = child;
|
||||
}
|
||||
|
||||
lastFrameRotation = t.localRotation;
|
||||
initialPosition = t.localPosition;
|
||||
initialRotation = t.localRotation;
|
||||
initialPositionWorld = t.position;
|
||||
targetPosition = t.position;
|
||||
|
||||
previousPositionWorld = initialPositionWorld;
|
||||
|
||||
jointTransform = t;
|
||||
|
||||
jointRadius = radius;
|
||||
|
||||
oldVec = Vector3.up;
|
||||
|
||||
keyedRotations = new List<Quaternion>();
|
||||
keyedPositions = new List<Vector3>();
|
||||
keyedLocalPositions = new List<Vector3>();
|
||||
|
||||
this.jointLimit = t.gameObject.GetComponent<DynamicJointLimit>();
|
||||
}
|
||||
|
||||
public Vector3 GetCurrentPositionWorld()
|
||||
{
|
||||
return jointTransform.position;
|
||||
}
|
||||
|
||||
public Vector3 GetInitialPositionWorld()
|
||||
{
|
||||
return initialPositionWorld;
|
||||
}
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
public class HybridIKNodeStretchLimits
|
||||
{
|
||||
public Transform targetSpace;
|
||||
|
||||
public Vector3 minStretchLimits;
|
||||
public Vector3 maxStretchLimits;
|
||||
|
||||
public float maxForward = 0;
|
||||
public float maxBackward = 0;
|
||||
|
||||
public float maxLeft = 0;
|
||||
public float maxRight = 0;
|
||||
|
||||
public float maxDown = 0;
|
||||
public float maxUp = 0;
|
||||
|
||||
public Vector3 ApplyStretchLimit(Vector3 targetVec, Vector3 localOrigin)
|
||||
{
|
||||
if (targetSpace == null)
|
||||
return Vector3.zero;
|
||||
|
||||
Vector3 currentPos = targetSpace.position;
|
||||
targetSpace.localPosition = localOrigin;
|
||||
Vector3 diff = currentPos - targetSpace.position;
|
||||
targetVec += diff;
|
||||
|
||||
Vector3 vec = targetSpace.InverseTransformDirection(targetVec);
|
||||
vec.x = Mathf.Clamp(vec.x, minStretchLimits.x, maxStretchLimits.x);
|
||||
vec.y = Mathf.Clamp(vec.y, minStretchLimits.y, maxStretchLimits.y);
|
||||
vec.z = Mathf.Clamp(vec.z, minStretchLimits.z, maxStretchLimits.z);
|
||||
|
||||
vec = targetSpace.TransformDirection(vec);
|
||||
|
||||
return vec;
|
||||
}
|
||||
}
|
||||
18
Assets/HybridIK/Scripts/Main/HybridIKJoint.cs.meta
Normal file
18
Assets/HybridIK/Scripts/Main/HybridIKJoint.cs.meta
Normal file
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2022210cf5df74d4dbdb63767a36f578
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 174069
|
||||
packageName: Hybrid IK
|
||||
packageVersion: 1.02
|
||||
assetPath: Assets/HybridIK/Scripts/Main/HybridIKJoint.cs
|
||||
uploadId: 532533
|
||||
8
Assets/HybridIK/Scripts/Main/HybridIKStretchJunction.cs
Normal file
8
Assets/HybridIK/Scripts/Main/HybridIKStretchJunction.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class HybridIKStretchJunction : MonoBehaviour
|
||||
{
|
||||
|
||||
}
|
||||
18
Assets/HybridIK/Scripts/Main/HybridIKStretchJunction.cs.meta
Normal file
18
Assets/HybridIK/Scripts/Main/HybridIKStretchJunction.cs.meta
Normal file
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b8a651a183a8c1443a30fc1d5487ea05
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 174069
|
||||
packageName: Hybrid IK
|
||||
packageVersion: 1.02
|
||||
assetPath: Assets/HybridIK/Scripts/Main/HybridIKStretchJunction.cs
|
||||
uploadId: 532533
|
||||
1157
Assets/HybridIK/Scripts/Main/HybridInverseKinematicsNode.cs
Normal file
1157
Assets/HybridIK/Scripts/Main/HybridInverseKinematicsNode.cs
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ec18f272cdf3e704196131d48566ee83
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 174069
|
||||
packageName: Hybrid IK
|
||||
packageVersion: 1.02
|
||||
assetPath: Assets/HybridIK/Scripts/Main/HybridInverseKinematicsNode.cs
|
||||
uploadId: 532533
|
||||
144
Assets/HybridIK/Scripts/Main/RobotController.cs
Normal file
144
Assets/HybridIK/Scripts/Main/RobotController.cs
Normal file
@@ -0,0 +1,144 @@
|
||||
using NUnit.Framework;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Sockets;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
public class RobotController : MonoBehaviour
|
||||
{
|
||||
[Header("IK")]
|
||||
[SerializeField] private HybridInverseKinematicsNode kinematicsNode;
|
||||
|
||||
[Header("Motor State")]
|
||||
[SerializeField] private GameObject motorStatusIndicator1;
|
||||
[SerializeField] private GameObject motorStatusIndicator2;
|
||||
|
||||
[SerializeField] private Material indicatorMaterial1; // 기본색(회색)
|
||||
[SerializeField] private Material indicatorMaterial2; // 초록
|
||||
|
||||
[SerializeField] public GameObject toolEndpoint;
|
||||
[SerializeField] public Material toolEndpointHighlight;
|
||||
[SerializeField] public Material toolEndpointErrorHighlight;
|
||||
[SerializeField] public Material toolEndpointOriginal;
|
||||
|
||||
[SerializeField] public GameObject testSphere; // 타겟 위치에 표시할 오브젝트
|
||||
|
||||
public event Action OnPoseUpdateRequest;
|
||||
public event Action OnPoseUpdateReceive;
|
||||
|
||||
public Vector3 movementPosition;
|
||||
private Quaternion movementRotation;
|
||||
|
||||
private bool isMotorOn;
|
||||
public bool IsMovementRunning = false;
|
||||
|
||||
void Start()
|
||||
{
|
||||
if (motorStatusIndicator1 != null)
|
||||
{
|
||||
motorStatusIndicator1.GetComponent<MeshRenderer>().material = indicatorMaterial1;
|
||||
}
|
||||
if (motorStatusIndicator2 != null)
|
||||
{
|
||||
motorStatusIndicator2.GetComponent<MeshRenderer>().material = indicatorMaterial1;
|
||||
}
|
||||
}
|
||||
|
||||
private void FixedUpdate()
|
||||
{
|
||||
OnPoseUpdateRequest?.Invoke();
|
||||
}
|
||||
|
||||
private void LateUpdate()
|
||||
{
|
||||
if (kinematicsNode != null && kinematicsNode.enabled == false)
|
||||
{
|
||||
UpdateHandleToEndPoint();
|
||||
}
|
||||
}
|
||||
|
||||
public void SetMotorState(bool isOn)
|
||||
{
|
||||
isMotorOn = isOn;
|
||||
|
||||
|
||||
if (isMotorOn)
|
||||
{
|
||||
if (indicatorMaterial2 != null)
|
||||
{
|
||||
motorStatusIndicator1.GetComponent<MeshRenderer>().material = indicatorMaterial2;
|
||||
motorStatusIndicator2.GetComponent<MeshRenderer>().material = indicatorMaterial2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (indicatorMaterial1 != null)
|
||||
{
|
||||
motorStatusIndicator1.GetComponent<MeshRenderer>().material = indicatorMaterial1;
|
||||
motorStatusIndicator2.GetComponent<MeshRenderer>().material = indicatorMaterial1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void EnableIK()
|
||||
{
|
||||
if (kinematicsNode != null) kinematicsNode.enabled = true;
|
||||
}
|
||||
|
||||
public void DisableIK()
|
||||
{
|
||||
if (kinematicsNode != null) kinematicsNode.enabled = false;
|
||||
}
|
||||
|
||||
/*
|
||||
public void SetRobotPosition(RobotData robotData) // 가상 로봇 위치 업데이트
|
||||
{
|
||||
// x, y, z, rx, ry, rz => endpoint값
|
||||
// j1, ..., j6 => 6개 축의 회전값
|
||||
if (robotData == null)
|
||||
{
|
||||
return; // 데이터가 없으면 아무것도 하지 않음
|
||||
}
|
||||
|
||||
List<Quaternion> list_jAngle = new List<Quaternion>();
|
||||
|
||||
list_jAngle.Add(Quaternion.AngleAxis(-1 * robotData.j1, Vector3.forward));
|
||||
list_jAngle.Add(Quaternion.AngleAxis((robotData.j2 - 90), Vector3.up));
|
||||
list_jAngle.Add(Quaternion.AngleAxis(robotData.j3, Vector3.up));
|
||||
list_jAngle.Add(Quaternion.AngleAxis(robotData.j4, Vector3.right));
|
||||
list_jAngle.Add(Quaternion.AngleAxis(robotData.j5, Vector3.up));
|
||||
list_jAngle.Add(Quaternion.AngleAxis(robotData.j6, Vector3.right));
|
||||
|
||||
kinematicsNode.SetJointTargetRotations(list_jAngle);
|
||||
}
|
||||
*/
|
||||
|
||||
private void UpdateHandleToEndPoint()
|
||||
{
|
||||
if (kinematicsNode == null || kinematicsNode.targetTransform == null ||
|
||||
kinematicsNode.nodes == null || kinematicsNode.nodes.Count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Transform endPoint = kinematicsNode.nodes[kinematicsNode.nodes.Count - 1].jointTransform;
|
||||
if (endPoint == null) return;
|
||||
|
||||
kinematicsNode.targetTransform.position = endPoint.position;
|
||||
kinematicsNode.targetTransform.rotation = endPoint.rotation;
|
||||
}
|
||||
|
||||
public Transform GetEndPoint()
|
||||
{
|
||||
Transform endPoint = kinematicsNode.nodes[kinematicsNode.nodes.Count - 1].jointTransform;
|
||||
return endPoint;
|
||||
}
|
||||
|
||||
void OnDestroy()
|
||||
{
|
||||
IsMovementRunning = false;
|
||||
}
|
||||
}
|
||||
2
Assets/HybridIK/Scripts/Main/RobotController.cs.meta
Normal file
2
Assets/HybridIK/Scripts/Main/RobotController.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c12f4ab377ddfdc46820089b240eaf27
|
||||
43
Assets/HybridIK/Scripts/Main/TargetRangeLimiter.cs
Normal file
43
Assets/HybridIK/Scripts/Main/TargetRangeLimiter.cs
Normal file
@@ -0,0 +1,43 @@
|
||||
using UnityEngine;
|
||||
|
||||
/// 이 Transform의 위치를 지정된 중심점으로부터 최대 거리를 벗어나지 않도록 제한
|
||||
public class TargetRangeLimiter : MonoBehaviour
|
||||
{
|
||||
[Header("Range Limit")]
|
||||
[SerializeField] private Transform centerPoint;
|
||||
|
||||
[SerializeField] private float maxDistance = 2.0f;
|
||||
|
||||
// LateUpdate를 사용하여 다른 스크립트에 의해 위치가 변경된 후 최종적으로 위치 보정
|
||||
private void LateUpdate()
|
||||
{
|
||||
if (centerPoint == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// 1. 중심점에서 현재 핸들 위치까지의 벡터와 거리를 계산
|
||||
Vector3 directionFromCenter = transform.position - centerPoint.position;
|
||||
float currentDistance = directionFromCenter.magnitude;
|
||||
|
||||
// 2. 현재 거리가 최대 거리를 초과했는지 확인
|
||||
if (currentDistance > maxDistance)
|
||||
{
|
||||
// 3. 방향은 유지한 채, 거리를 최대 거리로 제한하는 새로운 위치 계산
|
||||
Vector3 newPosition = centerPoint.position + directionFromCenter.normalized * maxDistance;
|
||||
|
||||
// 4. 핸들의 위치를 계산된 새 위치로 강제 설정
|
||||
transform.position = newPosition;
|
||||
}
|
||||
}
|
||||
|
||||
//// 기즈모를 그려서 작업 범위를 시각적으로 보여줌 (에디터 전용)
|
||||
//private void OnDrawGizmosSelected()
|
||||
//{
|
||||
// if (centerPoint != null)
|
||||
// {
|
||||
// Gizmos.color = Color.green;
|
||||
// Gizmos.DrawWireSphere(centerPoint.position, maxDistance);
|
||||
// }
|
||||
//}
|
||||
}
|
||||
2
Assets/HybridIK/Scripts/Main/TargetRangeLimiter.cs.meta
Normal file
2
Assets/HybridIK/Scripts/Main/TargetRangeLimiter.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e6dac70e0e196a043852640887710f7b
|
||||
8
Assets/HybridIK/Scripts/Utils.meta
Normal file
8
Assets/HybridIK/Scripts/Utils.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b509378e1379bb54cbbbb7ce530a5fe9
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
727
Assets/HybridIK/Scripts/Utils/GeometryMathHelperUtils.cs
Normal file
727
Assets/HybridIK/Scripts/Utils/GeometryMathHelperUtils.cs
Normal file
@@ -0,0 +1,727 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class GeometryMathHelperUtils
|
||||
{
|
||||
//Find the line of intersection between two planes. The planes are defined by a normal and a point on that plane.
|
||||
//The outputs are a point on the line and a vector which indicates it's direction. If the planes are not parallel,
|
||||
//the function outputs true, otherwise false.
|
||||
public static bool PlanePlaneIntersection(out Vector3 linePoint, out Vector3 lineVec, Vector3 plane1Normal, Vector3 plane1Position, Vector3 plane2Normal, Vector3 plane2Position)
|
||||
{
|
||||
|
||||
linePoint = Vector3.zero;
|
||||
lineVec = Vector3.zero;
|
||||
|
||||
//We can get the direction of the line of intersection of the two planes by calculating the
|
||||
//cross product of the normals of the two planes. Note that this is just a direction and the line
|
||||
//is not fixed in space yet. We need a point for that to go with the line vector.
|
||||
lineVec = Vector3.Cross(plane1Normal, plane2Normal);
|
||||
|
||||
//Next is to calculate a point on the line to fix it's position in space. This is done by finding a vector from
|
||||
//the plane2 location, moving parallel to it's plane, and intersecting plane1. To prevent rounding
|
||||
//errors, this vector also has to be perpendicular to lineDirection. To get this vector, calculate
|
||||
//the cross product of the normal of plane2 and the lineDirection.
|
||||
Vector3 ldir = Vector3.Cross(plane2Normal, lineVec);
|
||||
|
||||
float denominator = Vector3.Dot(plane1Normal, ldir);
|
||||
|
||||
//Prevent divide by zero and rounding errors by requiring about 5 degrees angle between the planes.
|
||||
if (Mathf.Abs(denominator) > 0.006f)
|
||||
{
|
||||
|
||||
Vector3 plane1ToPlane2 = plane1Position - plane2Position;
|
||||
float t = Vector3.Dot(plane1Normal, plane1ToPlane2) / denominator;
|
||||
linePoint = plane2Position + t * ldir;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//output not valid
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//create a vector of direction "vector" with length "size"
|
||||
public static Vector3 SetVectorLength(Vector3 vector, float size)
|
||||
{
|
||||
|
||||
//normalize the vector
|
||||
Vector3 vectorNormalized = Vector3.Normalize(vector);
|
||||
|
||||
//scale the vector
|
||||
return vectorNormalized *= size;
|
||||
}
|
||||
|
||||
//Get the intersection between a line and a plane.
|
||||
//If the line and plane are not parallel, the function outputs true, otherwise false.
|
||||
public static bool LinePlaneIntersection(out Vector3 intersection, Vector3 linePoint, Vector3 lineVec, Vector3 planeNormal, Vector3 planePoint)
|
||||
{
|
||||
|
||||
float length;
|
||||
float dotNumerator;
|
||||
float dotDenominator;
|
||||
Vector3 vector;
|
||||
intersection = Vector3.zero;
|
||||
|
||||
//calculate the distance between the linePoint and the line-plane intersection point
|
||||
dotNumerator = Vector3.Dot((planePoint - linePoint), planeNormal);
|
||||
dotDenominator = Vector3.Dot(lineVec, planeNormal);
|
||||
|
||||
//line and plane are not parallel
|
||||
if (dotDenominator != 0.0f)
|
||||
{
|
||||
length = dotNumerator / dotDenominator;
|
||||
|
||||
//create a vector from the linePoint to the intersection point
|
||||
vector = SetVectorLength(lineVec, length);
|
||||
|
||||
//get the coordinates of the line-plane intersection point
|
||||
intersection = linePoint + vector;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//output not valid
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//Calculate the intersection point of two lines. Returns true if lines intersect, otherwise false.
|
||||
//Note that in 3d, two lines do not intersect most of the time. So if the two lines are not in the
|
||||
//same plane, use ClosestPointsOnTwoLines() instead.
|
||||
public static bool LineLineIntersection(out Vector3 intersection, Vector3 linePoint1, Vector3 lineVec1, Vector3 linePoint2, Vector3 lineVec2)
|
||||
{
|
||||
|
||||
Vector3 lineVec3 = linePoint2 - linePoint1;
|
||||
Vector3 crossVec1and2 = Vector3.Cross(lineVec1, lineVec2);
|
||||
Vector3 crossVec3and2 = Vector3.Cross(lineVec3, lineVec2);
|
||||
|
||||
float planarFactor = Vector3.Dot(lineVec3, crossVec1and2);
|
||||
|
||||
//is coplanar, and not parrallel
|
||||
if (Mathf.Abs(planarFactor) < 0.0001f && crossVec1and2.sqrMagnitude > 0.0001f)
|
||||
{
|
||||
float s = Vector3.Dot(crossVec3and2, crossVec1and2) / crossVec1and2.sqrMagnitude;
|
||||
intersection = linePoint1 + (lineVec1 * s);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
intersection = Vector3.zero;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//Two non-parallel lines which may or may not touch each other have a point on each line which are closest
|
||||
//to each other. This function finds those two points. If the lines are not parallel, the function
|
||||
//outputs true, otherwise false.
|
||||
public static bool ClosestPointsOnTwoLines(out Vector3 closestPointLine1, out Vector3 closestPointLine2, Vector3 linePoint1, Vector3 lineVec1, Vector3 linePoint2, Vector3 lineVec2)
|
||||
{
|
||||
|
||||
closestPointLine1 = Vector3.zero;
|
||||
closestPointLine2 = Vector3.zero;
|
||||
|
||||
float a = Vector3.Dot(lineVec1, lineVec1);
|
||||
float b = Vector3.Dot(lineVec1, lineVec2);
|
||||
float e = Vector3.Dot(lineVec2, lineVec2);
|
||||
|
||||
float d = a * e - b * b;
|
||||
|
||||
//lines are not parallel
|
||||
if (d != 0.0f)
|
||||
{
|
||||
|
||||
Vector3 r = linePoint1 - linePoint2;
|
||||
float c = Vector3.Dot(lineVec1, r);
|
||||
float f = Vector3.Dot(lineVec2, r);
|
||||
|
||||
float s = (b * f - c * e) / d;
|
||||
float t = (a * f - c * b) / d;
|
||||
|
||||
closestPointLine1 = linePoint1 + lineVec1 * s;
|
||||
closestPointLine2 = linePoint2 + lineVec2 * t;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//This function returns a point which is a projection from a point to a line.
|
||||
//The line is regarded infinite. If the line is finite, use ProjectPointOnLineSegment() instead.
|
||||
public static Vector3 ProjectPointOnLine(Vector3 linePoint, Vector3 lineVec, Vector3 point)
|
||||
{
|
||||
|
||||
//get vector from point on line to point in space
|
||||
Vector3 linePointToPoint = point - linePoint;
|
||||
|
||||
float t = Vector3.Dot(linePointToPoint, lineVec);
|
||||
|
||||
return linePoint + lineVec * t;
|
||||
}
|
||||
|
||||
//This function returns a point which is a projection from a point to a line segment.
|
||||
//If the projected point lies outside of the line segment, the projected point will
|
||||
//be clamped to the appropriate line edge.
|
||||
//If the line is infinite instead of a segment, use ProjectPointOnLine() instead.
|
||||
public static Vector3 ProjectPointOnLineSegment(Vector3 linePoint1, Vector3 linePoint2, Vector3 point)
|
||||
{
|
||||
Vector3 projectedP = Vector3.Project(point - linePoint1, linePoint2 - linePoint1) + linePoint1;
|
||||
|
||||
float lineD = Vector3.Distance(linePoint1, linePoint2);
|
||||
float d1 = Vector3.Distance(linePoint1, projectedP);
|
||||
float d2 = Vector3.Distance(linePoint2, projectedP);
|
||||
|
||||
// On the segment
|
||||
if (d1 < lineD && d2 < lineD)
|
||||
return projectedP;
|
||||
|
||||
// not on segment, evaluate against points instead
|
||||
if (Vector3.Distance(point, linePoint1) < Vector3.Distance(point, linePoint2))
|
||||
return linePoint1;
|
||||
else
|
||||
return linePoint2;
|
||||
}
|
||||
|
||||
//This function finds out on which side of a line segment the point is located.
|
||||
//The point is assumed to be on a line created by linePoint1 and linePoint2. If the point is not on
|
||||
//the line segment, project it on the line using ProjectPointOnLine() first.
|
||||
//Returns 0 if point is on the line segment.
|
||||
//Returns 1 if point is outside of the line segment and located on the side of linePoint1.
|
||||
//Returns 2 if point is outside of the line segment and located on the side of linePoint2.
|
||||
public static int PointOnWhichSideOfLineSegment(Vector3 linePoint1, Vector3 linePoint2, Vector3 point)
|
||||
{
|
||||
|
||||
Vector3 lineVec = linePoint2 - linePoint1;
|
||||
Vector3 pointVec = point - linePoint1;
|
||||
|
||||
float dot = Vector3.Dot(pointVec, lineVec);
|
||||
|
||||
//point is on side of linePoint2, compared to linePoint1
|
||||
if (dot > 0)
|
||||
{
|
||||
|
||||
//point is on the line segment
|
||||
if (pointVec.magnitude <= lineVec.magnitude)
|
||||
{
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//point is not on the line segment and it is on the side of linePoint2
|
||||
else
|
||||
{
|
||||
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
//Point is not on side of linePoint2, compared to linePoint1.
|
||||
//Point is not on the line segment and it is on the side of linePoint1.
|
||||
else
|
||||
{
|
||||
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
public static Vector3 ProjectPointOnTriangle (Vector3 A, Vector3 B, Vector3 C, Vector3 sourceP)
|
||||
{
|
||||
// Compute vectors
|
||||
Vector3 v0 = C - A;
|
||||
Vector3 v1 = B - A;
|
||||
|
||||
Vector3 projectedP = Vector3.ProjectOnPlane(sourceP - A, Vector3.Cross(v0.normalized, v1.normalized)) + A;
|
||||
Vector3 v2 = projectedP - A;
|
||||
|
||||
// Compute dot products
|
||||
float dot00 = Vector3.Dot(v0, v0);
|
||||
float dot01 = Vector3.Dot(v0, v1);
|
||||
float dot02 = Vector3.Dot(v0, v2);
|
||||
float dot11 = Vector3.Dot(v1, v1);
|
||||
float dot12 = Vector3.Dot(v1, v2);
|
||||
|
||||
// Compute barycentric coordinates
|
||||
float invDenom = 1 / (dot00 * dot11 - dot01 * dot01);
|
||||
float u = (dot11 * dot02 - dot01 * dot12) * invDenom;
|
||||
float v = (dot00 * dot12 - dot01 * dot02) * invDenom;
|
||||
|
||||
// Check if point is in triangle
|
||||
if ((u >= 0) && (v >= 0) && (u + v < 1))
|
||||
{
|
||||
return A + (u * v0) + (v * v1);
|
||||
}
|
||||
|
||||
// Evaluate closest point to triangle linesegments
|
||||
Vector3 p1 = ProjectPointOnLineSegment(A, B, projectedP);
|
||||
Vector3 p2 = ProjectPointOnLineSegment(A, C, projectedP);
|
||||
Vector3 p3 = ProjectPointOnLineSegment(C, B, projectedP);
|
||||
|
||||
float d1 = Vector3.Distance(projectedP, p1);
|
||||
float d2 = Vector3.Distance(projectedP, p2);
|
||||
float d3 = Vector3.Distance(projectedP, p3);
|
||||
|
||||
if (d1 <= d2 && d1 <= d3) return p1;
|
||||
if (d2 <= d1 && d2 <= d3) return p2;
|
||||
if (d3 <= d2 && d3 <= d1) return p3;
|
||||
|
||||
return projectedP;
|
||||
}
|
||||
|
||||
public static Vector3 FindAveragePoint(List<Vector3> points)
|
||||
{
|
||||
Vector3 avgPoint = Vector3.zero;
|
||||
foreach (Vector3 p in points)
|
||||
{
|
||||
avgPoint += p;
|
||||
}
|
||||
avgPoint /= points.Count;
|
||||
|
||||
return avgPoint;
|
||||
}
|
||||
|
||||
public static Vector3 FindClosestPointToConvexHull(List<Vector3> hullPoints, List<int> hullTris, Vector3 targetPoint)
|
||||
{
|
||||
if (hullPoints == null || hullPoints.Count < 3 || hullTris == null || hullTris.Count < 2)
|
||||
return targetPoint;
|
||||
|
||||
float closestD = Mathf.Infinity;
|
||||
Vector3 closestProjection = targetPoint;
|
||||
|
||||
for(int t = 0; t < hullTris.Count; t += 3)
|
||||
{
|
||||
Vector3 v1 = hullPoints[hullTris[t]];
|
||||
Vector3 v2 = hullPoints[hullTris[t + 1]];
|
||||
Vector3 v3 = hullPoints[hullTris[t + 2]];
|
||||
|
||||
Vector3 projectedP = ProjectPointOnTriangle(v1, v2, v3, targetPoint);
|
||||
float d = Vector3.Distance(projectedP, targetPoint);
|
||||
if (Vector3.Distance(projectedP, targetPoint) < closestD)
|
||||
{
|
||||
d = closestD;
|
||||
closestProjection = projectedP;
|
||||
}
|
||||
}
|
||||
|
||||
return closestProjection;
|
||||
}
|
||||
|
||||
public static Vector3 ProjectPointOnConvexHull(List<Vector3> hullPoints, List<int> hullTris, Vector3 targetPoint, out bool isInside)
|
||||
{
|
||||
isInside = false;
|
||||
if (hullPoints == null || hullPoints.Count < 3 || hullTris == null || hullTris.Count < 2)
|
||||
return targetPoint;
|
||||
|
||||
Vector3 origin = FindAveragePoint(hullPoints);
|
||||
Vector3 dir = targetPoint - origin;
|
||||
Ray ray = new Ray(origin, dir);
|
||||
|
||||
Vector3 intersectionPoint;
|
||||
|
||||
for (int t = 0; t < hullTris.Count; t += 3)
|
||||
{
|
||||
Vector3 v1 = hullPoints[hullTris[t]];
|
||||
Vector3 v2 = hullPoints[hullTris[t + 1]];
|
||||
Vector3 v3 = hullPoints[hullTris[t + 2]];
|
||||
|
||||
if (RayTriangleIntersection(v1, v2, v3, ray, out intersectionPoint))
|
||||
{
|
||||
//Debug.DrawLine(origin, intersectionPoint);
|
||||
if (Vector3.Distance(origin, intersectionPoint) < Vector3.Distance(origin, targetPoint))
|
||||
{
|
||||
return intersectionPoint;
|
||||
}
|
||||
else
|
||||
{
|
||||
isInside = true;
|
||||
return targetPoint;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return targetPoint;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the specified ray hits the triagnlge descibed by p1, p2 and p3.
|
||||
/// Möller–Trumbore ray-triangle intersection algorithm implementation.
|
||||
/// </summary>
|
||||
/// <param name="p1">Vertex 1 of the triangle.</param>
|
||||
/// <param name="p2">Vertex 2 of the triangle.</param>
|
||||
/// <param name="p3">Vertex 3 of the triangle.</param>
|
||||
/// <param name="ray">The ray to test hit for.</param>
|
||||
/// <returns><c>true</c> when the ray hits the triangle, otherwise <c>false</c></returns>
|
||||
public static bool RayTriangleIntersection(Vector3 p1, Vector3 p2, Vector3 p3, Ray ray, out Vector3 intersectionPoint)
|
||||
{
|
||||
intersectionPoint = ray.origin;
|
||||
|
||||
// Vectors from p1 to p2/p3 (edges)
|
||||
Vector3 e1, e2;
|
||||
|
||||
Vector3 p, q, t;
|
||||
float det, invDet, u, v;
|
||||
|
||||
|
||||
//Find vectors for two edges sharing vertex/point p1
|
||||
e1 = p2 - p1;
|
||||
e2 = p3 - p1;
|
||||
|
||||
// calculating determinant
|
||||
p = Vector3.Cross(ray.direction, e2);
|
||||
|
||||
//Calculate determinat
|
||||
det = Vector3.Dot(e1, p);
|
||||
|
||||
//if determinant is near zero, ray lies in plane of triangle otherwise not
|
||||
if (det > - Mathf.Epsilon && det < Mathf.Epsilon) { return false; }
|
||||
invDet = 1.0f / det;
|
||||
|
||||
//calculate distance from p1 to ray origin
|
||||
t = ray.origin - p1;
|
||||
|
||||
//Calculate u parameter
|
||||
u = Vector3.Dot(t, p) * invDet;
|
||||
|
||||
//Check for ray hit
|
||||
if (u < 0 || u > 1) { return false; }
|
||||
|
||||
//Prepare to test v parameter
|
||||
q = Vector3.Cross(t, e1);
|
||||
|
||||
//Calculate v parameter
|
||||
v = Vector3.Dot(ray.direction, q) * invDet;
|
||||
|
||||
//Check for ray hit
|
||||
if (v < 0 || u + v > 1) { return false; }
|
||||
|
||||
if ((Vector3.Dot(e2, q) * invDet) > Mathf.Epsilon)
|
||||
{
|
||||
intersectionPoint = p1 + (u * e1) + (v * e2);
|
||||
//ray does intersect
|
||||
return true;
|
||||
}
|
||||
|
||||
// No hit at all
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private static void Sort(Vector2 v)
|
||||
{
|
||||
if (v.x > v.y)
|
||||
{
|
||||
float c;
|
||||
c = v.x;
|
||||
v.x = v.y;
|
||||
v.y = c;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This edge to edge test is based on Franlin Antonio's gem: "Faster Line Segment Intersection", in Graphics Gems III, pp. 199-202
|
||||
/// </summary>
|
||||
private static bool EdgeEdgeTest(Vector3 v0, Vector3 v1, Vector3 u0, Vector3 u1, int i0, int i1)
|
||||
{
|
||||
float Ax, Ay, Bx, By, Cx, Cy, e, d, f;
|
||||
Ax = v1[i0] - v0[i0];
|
||||
Ay = v1[i1] - v0[i1];
|
||||
|
||||
Bx = u0[i0] - u1[i0];
|
||||
By = u0[i1] - u1[i1];
|
||||
Cx = v0[i0] - u0[i0];
|
||||
Cy = v0[i1] - u0[i1];
|
||||
f = Ay * Bx - Ax * By;
|
||||
d = By * Cx - Bx * Cy;
|
||||
if ((f > 0 && d >= 0 && d <= f) || (f < 0 && d <= 0 && d >= f))
|
||||
{
|
||||
e = Ax * Cy - Ay * Cx;
|
||||
if (f > 0)
|
||||
{
|
||||
if (e >= 0 && e <= f) { return true; }
|
||||
}
|
||||
else
|
||||
{
|
||||
if (e <= 0 && e >= f) { return true; }
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static bool EdgeAgainstTriEdges(Vector3 v0, Vector3 v1, Vector3 u0, Vector3 u1, Vector3 u2, short i0, short i1)
|
||||
{
|
||||
// test edge u0,u1 against v0,v1
|
||||
if (EdgeEdgeTest(v0, v1, u0, u1, i0, i1)) { return true; }
|
||||
|
||||
// test edge u1,u2 against v0,v1
|
||||
if (EdgeEdgeTest(v0, v1, u1, u2, i0, i1)) { return true; }
|
||||
|
||||
// test edge u2,u1 against v0,v1
|
||||
if (EdgeEdgeTest(v0, v1, u2, u0, i0, i1)) { return true; }
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static bool PointInTri(Vector3 v0, Vector3 u0, Vector3 u1, Vector3 u2, short i0, short i1)
|
||||
{
|
||||
float a, b, c, d0, d1, d2;
|
||||
|
||||
// is T1 completly inside T2?
|
||||
// check if v0 is inside tri(u0,u1,u2)
|
||||
a = u1[i1] - u0[i1];
|
||||
b = -(u1[i0] - u0[i0]);
|
||||
c = -a * u0[i0] - b * u0[i1];
|
||||
d0 = a * v0[i0] + b * v0[i1] + c;
|
||||
|
||||
a = u2[i1] - u1[i1];
|
||||
b = -(u2[i0] - u1[i0]);
|
||||
c = -a * u1[i0] - b * u1[i1];
|
||||
d1 = a * v0[i0] + b * v0[i1] + c;
|
||||
|
||||
a = u0[i1] - u2[i1];
|
||||
b = -(u0[i0] - u2[i0]);
|
||||
c = -a * u2[i0] - b * u2[i1];
|
||||
d2 = a * v0[i0] + b * v0[i1] + c;
|
||||
|
||||
if (d0 * d1 > 0.0f)
|
||||
{
|
||||
if (d0 * d2 > 0.0f) { return true; }
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static bool TriTriCoplanar(Vector3 N, Vector3 v0, Vector3 v1, Vector3 v2, Vector3 u0, Vector3 u1, Vector3 u2)
|
||||
{
|
||||
float[] A = new float[3];
|
||||
short i0, i1;
|
||||
|
||||
// first project onto an axis-aligned plane, that maximizes the area
|
||||
// of the triangles, compute indices: i0,i1.
|
||||
A[0] = Mathf.Abs(N[0]);
|
||||
A[1] = Mathf.Abs(N[1]);
|
||||
A[2] = Mathf.Abs(N[2]);
|
||||
if (A[0] > A[1])
|
||||
{
|
||||
if (A[0] > A[2])
|
||||
{
|
||||
// A[0] is greatest
|
||||
i0 = 1;
|
||||
i1 = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
// A[2] is greatest
|
||||
i0 = 0;
|
||||
i1 = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (A[2] > A[1])
|
||||
{
|
||||
// A[2] is greatest
|
||||
i0 = 0;
|
||||
i1 = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// A[1] is greatest
|
||||
i0 = 0;
|
||||
i1 = 2;
|
||||
}
|
||||
}
|
||||
|
||||
// test all edges of triangle 1 against the edges of triangle 2
|
||||
if (EdgeAgainstTriEdges(v0, v1, u0, u1, u2, i0, i1)) { return true; }
|
||||
if (EdgeAgainstTriEdges(v1, v2, u0, u1, u2, i0, i1)) { return true; }
|
||||
if (EdgeAgainstTriEdges(v2, v0, u0, u1, u2, i0, i1)) { return true; }
|
||||
|
||||
// finally, test if tri1 is totally contained in tri2 or vice versa
|
||||
if (PointInTri(v0, u0, u1, u2, i0, i1)) { return true; }
|
||||
if (PointInTri(u0, v0, v1, v2, i0, i1)) { return true; }
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private static bool ComputeIntervals(float VV0, float VV1, float VV2,
|
||||
float D0, float D1, float D2, float D0D1, float D0D2,
|
||||
ref float A, ref float B, ref float C, ref float X0, ref float X1)
|
||||
{
|
||||
if (D0D1 > 0.0f)
|
||||
{
|
||||
// here we know that D0D2<=0.0
|
||||
// that is D0, D1 are on the same side, D2 on the other or on the plane
|
||||
A = VV2; B = (VV0 - VV2) * D2; C = (VV1 - VV2) * D2; X0 = D2 - D0; X1 = D2 - D1;
|
||||
}
|
||||
else if (D0D2 > 0.0f)
|
||||
{
|
||||
// here we know that d0d1<=0.0
|
||||
A = VV1; B = (VV0 - VV1) * D1; C = (VV2 - VV1) * D1; X0 = D1 - D0; X1 = D1 - D2;
|
||||
}
|
||||
else if (D1 * D2 > 0.0f || D0 != 0.0f)
|
||||
{
|
||||
// here we know that d0d1<=0.0 or that D0!=0.0
|
||||
A = VV0; B = (VV1 - VV0) * D0; C = (VV2 - VV0) * D0; X0 = D0 - D1; X1 = D0 - D2;
|
||||
}
|
||||
else if (D1 != 0.0f)
|
||||
{
|
||||
A = VV1; B = (VV0 - VV1) * D1; C = (VV2 - VV1) * D1; X0 = D1 - D0; X1 = D1 - D2;
|
||||
}
|
||||
else if (D2 != 0.0f)
|
||||
{
|
||||
A = VV2; B = (VV0 - VV2) * D2; C = (VV1 - VV2) * D2; X0 = D2 - D0; X1 = D2 - D1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the triangle V(v0, v1, v2) intersects the triangle U(u0, u1, u2).
|
||||
/// </summary>
|
||||
/// <param name="v0">Vertex 0 of V</param>
|
||||
/// <param name="v1">Vertex 1 of V</param>
|
||||
/// <param name="v2">Vertex 2 of V</param>
|
||||
/// <param name="u0">Vertex 0 of U</param>
|
||||
/// <param name="u1">Vertex 1 of U</param>
|
||||
/// <param name="u2">Vertex 2 of U</param>
|
||||
/// <returns>Returns <c>true</c> if V intersects U, otherwise <c>false</c></returns>
|
||||
public static bool TriTriIntersect(Vector3 v0, Vector3 v1, Vector3 v2, Vector3 u0, Vector3 u1, Vector3 u2)
|
||||
{
|
||||
Vector3 e1, e2;
|
||||
Vector3 n1, n2;
|
||||
Vector3 dd;
|
||||
Vector2 isect1 = Vector2.zero, isect2 = Vector2.zero;
|
||||
|
||||
float du0, du1, du2, dv0, dv1, dv2, d1, d2;
|
||||
float du0du1, du0du2, dv0dv1, dv0dv2;
|
||||
float vp0, vp1, vp2;
|
||||
float up0, up1, up2;
|
||||
float bb, cc, max;
|
||||
|
||||
short index;
|
||||
|
||||
// compute plane equation of triangle(v0,v1,v2)
|
||||
e1 = v1 - v0;
|
||||
e2 = v2 - v0;
|
||||
n1 = Vector3.Cross(e1, e2);
|
||||
d1 = -Vector3.Dot(n1, v0);
|
||||
// plane equation 1: N1.X+d1=0 */
|
||||
|
||||
// put u0,u1,u2 into plane equation 1 to compute signed distances to the plane
|
||||
du0 = Vector3.Dot(n1, u0) + d1;
|
||||
du1 = Vector3.Dot(n1, u1) + d1;
|
||||
du2 = Vector3.Dot(n1, u2) + d1;
|
||||
|
||||
// coplanarity robustness check
|
||||
if (Mathf.Abs(du0) < Mathf.Epsilon) { du0 = 0.0f; }
|
||||
if (Mathf.Abs(du1) < Mathf.Epsilon) { du1 = 0.0f; }
|
||||
if (Mathf.Abs(du2) < Mathf.Epsilon) { du2 = 0.0f; }
|
||||
|
||||
du0du1 = du0 * du1;
|
||||
du0du2 = du0 * du2;
|
||||
|
||||
// same sign on all of them + not equal 0 ?
|
||||
if (du0du1 > 0.0f && du0du2 > 0.0f)
|
||||
{
|
||||
// no intersection occurs
|
||||
return false;
|
||||
}
|
||||
|
||||
// compute plane of triangle (u0,u1,u2)
|
||||
e1 = u1 - u0;
|
||||
e2 = u2 - u0;
|
||||
n2 = Vector3.Cross(e1, e2);
|
||||
d2 = -Vector3.Dot(n2, u0);
|
||||
|
||||
// plane equation 2: N2.X+d2=0
|
||||
// put v0,v1,v2 into plane equation 2
|
||||
dv0 = Vector3.Dot(n2, v0) + d2;
|
||||
dv1 = Vector3.Dot(n2, v1) + d2;
|
||||
dv2 = Vector3.Dot(n2, v2) + d2;
|
||||
|
||||
if (Mathf.Abs(dv0) < Mathf.Epsilon) { dv0 = 0.0f; }
|
||||
if (Mathf.Abs(dv1) < Mathf.Epsilon) { dv1 = 0.0f; }
|
||||
if (Mathf.Abs(dv2) < Mathf.Epsilon) { dv2 = 0.0f; }
|
||||
|
||||
|
||||
dv0dv1 = dv0 * dv1;
|
||||
dv0dv2 = dv0 * dv2;
|
||||
|
||||
// same sign on all of them + not equal 0 ?
|
||||
if (dv0dv1 > 0.0f && dv0dv2 > 0.0f)
|
||||
{
|
||||
// no intersection occurs
|
||||
return false;
|
||||
}
|
||||
|
||||
// compute direction of intersection line
|
||||
dd = Vector3.Cross(n1, n2);
|
||||
|
||||
// compute and index to the largest component of D
|
||||
max = (float)Mathf.Abs(dd[0]);
|
||||
index = 0;
|
||||
bb = (float)Mathf.Abs(dd[1]);
|
||||
cc = (float)Mathf.Abs(dd[2]);
|
||||
if (bb > max) { max = bb; index = 1; }
|
||||
if (cc > max) { max = cc; index = 2; }
|
||||
|
||||
// this is the simplified projection onto L
|
||||
vp0 = v0[index];
|
||||
vp1 = v1[index];
|
||||
vp2 = v2[index];
|
||||
|
||||
up0 = u0[index];
|
||||
up1 = u1[index];
|
||||
up2 = u2[index];
|
||||
|
||||
// compute interval for triangle 1
|
||||
float a = 0, b = 0, c = 0, x0 = 0, x1 = 0;
|
||||
if (ComputeIntervals(vp0, vp1, vp2, dv0, dv1, dv2, dv0dv1, dv0dv2, ref a, ref b, ref c, ref x0, ref x1))
|
||||
{
|
||||
return TriTriCoplanar(n1, v0, v1, v2, u0, u1, u2);
|
||||
}
|
||||
|
||||
// compute interval for triangle 2
|
||||
float d = 0, e = 0, f = 0, y0 = 0, y1 = 0;
|
||||
if (ComputeIntervals(up0, up1, up2, du0, du1, du2, du0du1, du0du2, ref d, ref e, ref f, ref y0, ref y1))
|
||||
{
|
||||
return TriTriCoplanar(n1, v0, v1, v2, u0, u1, u2);
|
||||
}
|
||||
|
||||
float xx, yy, xxyy, tmp;
|
||||
xx = x0 * x1;
|
||||
yy = y0 * y1;
|
||||
xxyy = xx * yy;
|
||||
|
||||
tmp = a * xxyy;
|
||||
isect1[0] = tmp + b * x1 * yy;
|
||||
isect1[1] = tmp + c * x0 * yy;
|
||||
|
||||
tmp = d * xxyy;
|
||||
isect2[0] = tmp + e * xx * y1;
|
||||
isect2[1] = tmp + f * xx * y0;
|
||||
|
||||
Sort(isect1);
|
||||
Sort(isect2);
|
||||
|
||||
return !(isect1[1] < isect2[0] || isect2[1] < isect1[0]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 128a79f08e4a2d8418595cce65d7e047
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 174069
|
||||
packageName: Hybrid IK
|
||||
packageVersion: 1.02
|
||||
assetPath: Assets/HybridIK/Scripts/Utils/GeometryMathHelperUtils.cs
|
||||
uploadId: 532533
|
||||
8
Assets/New Folder.meta
Normal file
8
Assets/New Folder.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a76be24aeab6a4a49849326c5f66ea91
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
132
Assets/New Folder/AGV.prefab
Normal file
132
Assets/New Folder/AGV.prefab
Normal file
@@ -0,0 +1,132 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!1 &8841392116461521711
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 2548167011785565681}
|
||||
m_Layer: 0
|
||||
m_Name: EntitySocket
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &2548167011785565681
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 8841392116461521711}
|
||||
serializedVersion: 2
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0.835}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 2873669240030755518}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!1001 &2336219834142072149
|
||||
PrefabInstance:
|
||||
m_ObjectHideFlags: 0
|
||||
serializedVersion: 2
|
||||
m_Modification:
|
||||
serializedVersion: 3
|
||||
m_TransformParent: {fileID: 0}
|
||||
m_Modifications:
|
||||
- target: {fileID: -8679921383154817045, guid: ac07caa4b4d257f41bd9347e89607864, type: 3}
|
||||
propertyPath: m_LocalPosition.x
|
||||
value: -0.000000014901161
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -8679921383154817045, guid: ac07caa4b4d257f41bd9347e89607864, type: 3}
|
||||
propertyPath: m_LocalPosition.y
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -8679921383154817045, guid: ac07caa4b4d257f41bd9347e89607864, type: 3}
|
||||
propertyPath: m_LocalPosition.z
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -8679921383154817045, guid: ac07caa4b4d257f41bd9347e89607864, type: 3}
|
||||
propertyPath: m_LocalRotation.w
|
||||
value: 0.7071068
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -8679921383154817045, guid: ac07caa4b4d257f41bd9347e89607864, type: 3}
|
||||
propertyPath: m_LocalRotation.x
|
||||
value: -0.7071068
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -8679921383154817045, guid: ac07caa4b4d257f41bd9347e89607864, type: 3}
|
||||
propertyPath: m_LocalRotation.y
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -8679921383154817045, guid: ac07caa4b4d257f41bd9347e89607864, type: 3}
|
||||
propertyPath: m_LocalRotation.z
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -8679921383154817045, guid: ac07caa4b4d257f41bd9347e89607864, type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.x
|
||||
value: -90
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -8679921383154817045, guid: ac07caa4b4d257f41bd9347e89607864, type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.y
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -8679921383154817045, guid: ac07caa4b4d257f41bd9347e89607864, type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.z
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 919132149155446097, guid: ac07caa4b4d257f41bd9347e89607864, type: 3}
|
||||
propertyPath: m_Name
|
||||
value: AGV
|
||||
objectReference: {fileID: 0}
|
||||
m_RemovedComponents: []
|
||||
m_RemovedGameObjects: []
|
||||
m_AddedGameObjects:
|
||||
- targetCorrespondingSourceObject: {fileID: -8679921383154817045, guid: ac07caa4b4d257f41bd9347e89607864, type: 3}
|
||||
insertIndex: -1
|
||||
addedObject: {fileID: 2548167011785565681}
|
||||
m_AddedComponents:
|
||||
- targetCorrespondingSourceObject: {fileID: 919132149155446097, guid: ac07caa4b4d257f41bd9347e89607864, type: 3}
|
||||
insertIndex: -1
|
||||
addedObject: {fileID: 3627778761544267393}
|
||||
m_SourcePrefab: {fileID: 100100000, guid: ac07caa4b4d257f41bd9347e89607864, type: 3}
|
||||
--- !u!4 &2873669240030755518 stripped
|
||||
Transform:
|
||||
m_CorrespondingSourceObject: {fileID: -8679921383154817045, guid: ac07caa4b4d257f41bd9347e89607864, type: 3}
|
||||
m_PrefabInstance: {fileID: 2336219834142072149}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
--- !u!1 &3218528225413013508 stripped
|
||||
GameObject:
|
||||
m_CorrespondingSourceObject: {fileID: 919132149155446097, guid: ac07caa4b4d257f41bd9347e89607864, type: 3}
|
||||
m_PrefabInstance: {fileID: 2336219834142072149}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
--- !u!114 &3627778761544267393
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3218528225413013508}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: c84839a87b39b2a40aad67c2327e5c19, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
componentType: 0
|
||||
entitySocket: {fileID: 8841392116461521711}
|
||||
possessEntities: []
|
||||
data:
|
||||
name:
|
||||
label:
|
||||
initial_node:
|
||||
max_load_capacity: 0
|
||||
loading_time_policy:
|
||||
type:
|
||||
value: 0
|
||||
unloading_time_policy:
|
||||
type:
|
||||
value: 0
|
||||
7
Assets/New Folder/AGV.prefab.meta
Normal file
7
Assets/New Folder/AGV.prefab.meta
Normal file
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8b07b364350e4a34381fa078ca13dc6c
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/New Folder/Bench.meta
Normal file
8
Assets/New Folder/Bench.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5bcda20882d01c248bc632fb1c5fd1f3
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Assets/New Folder/Bench/Banch_mat_AO.png
Normal file
BIN
Assets/New Folder/Bench/Banch_mat_AO.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.2 MiB |
130
Assets/New Folder/Bench/Banch_mat_AO.png.meta
Normal file
130
Assets/New Folder/Bench/Banch_mat_AO.png.meta
Normal file
@@ -0,0 +1,130 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ae3b86f556310c940a4466bd4413d737
|
||||
TextureImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 13
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 1
|
||||
sRGBTexture: 1
|
||||
linearTexture: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapsPreserveCoverage: 0
|
||||
alphaTestReferenceValue: 0.5
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
flipGreenChannel: 0
|
||||
isReadable: 0
|
||||
streamingMipmaps: 0
|
||||
streamingMipmapsPriority: 0
|
||||
vTOnly: 0
|
||||
ignoreMipmapLimit: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: 1
|
||||
aniso: 1
|
||||
mipBias: 0
|
||||
wrapU: 0
|
||||
wrapV: 0
|
||||
wrapW: 0
|
||||
nPOTScale: 1
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spritePixelsToUnits: 100
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spriteGenerateFallbackPhysicsShape: 1
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 0
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 0
|
||||
textureShape: 1
|
||||
singleChannelComponent: 0
|
||||
flipbookRows: 1
|
||||
flipbookColumns: 1
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
ignorePngGamma: 0
|
||||
applyGammaDecoding: 0
|
||||
swizzle: 50462976
|
||||
cookieLightType: 0
|
||||
platformSettings:
|
||||
- serializedVersion: 4
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
ignorePlatformSupport: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 4
|
||||
buildTarget: Standalone
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
ignorePlatformSupport: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 4
|
||||
buildTarget: WebGL
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
ignorePlatformSupport: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
customData:
|
||||
physicsShape: []
|
||||
bones: []
|
||||
spriteID:
|
||||
internalID: 0
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
secondaryTextures: []
|
||||
spriteCustomMetadata:
|
||||
entries: []
|
||||
nameFileIdTable: {}
|
||||
mipmapLimitGroupName:
|
||||
pSDRemoveMatte: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Assets/New Folder/Bench/Banch_mat_Base_color.png
Normal file
BIN
Assets/New Folder/Bench/Banch_mat_Base_color.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.3 MiB |
130
Assets/New Folder/Bench/Banch_mat_Base_color.png.meta
Normal file
130
Assets/New Folder/Bench/Banch_mat_Base_color.png.meta
Normal file
@@ -0,0 +1,130 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2a7d7b2b427372942a22814142ab29fb
|
||||
TextureImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 13
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 1
|
||||
sRGBTexture: 1
|
||||
linearTexture: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapsPreserveCoverage: 0
|
||||
alphaTestReferenceValue: 0.5
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
flipGreenChannel: 0
|
||||
isReadable: 0
|
||||
streamingMipmaps: 0
|
||||
streamingMipmapsPriority: 0
|
||||
vTOnly: 0
|
||||
ignoreMipmapLimit: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: 1
|
||||
aniso: 1
|
||||
mipBias: 0
|
||||
wrapU: 0
|
||||
wrapV: 0
|
||||
wrapW: 0
|
||||
nPOTScale: 1
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spritePixelsToUnits: 100
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spriteGenerateFallbackPhysicsShape: 1
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 0
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 0
|
||||
textureShape: 1
|
||||
singleChannelComponent: 0
|
||||
flipbookRows: 1
|
||||
flipbookColumns: 1
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
ignorePngGamma: 0
|
||||
applyGammaDecoding: 0
|
||||
swizzle: 50462976
|
||||
cookieLightType: 0
|
||||
platformSettings:
|
||||
- serializedVersion: 4
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
ignorePlatformSupport: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 4
|
||||
buildTarget: Standalone
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
ignorePlatformSupport: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 4
|
||||
buildTarget: WebGL
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
ignorePlatformSupport: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
customData:
|
||||
physicsShape: []
|
||||
bones: []
|
||||
spriteID:
|
||||
internalID: 0
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
secondaryTextures: []
|
||||
spriteCustomMetadata:
|
||||
entries: []
|
||||
nameFileIdTable: {}
|
||||
mipmapLimitGroupName:
|
||||
pSDRemoveMatte: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user