Initial commit

This commit is contained in:
Thorbjoern
2025-05-26 00:46:28 +02:00
commit e5bca03433
3896 changed files with 1434297 additions and 0 deletions
+10
View File
@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: e9e109fb49381c540b4a5108479c269e
folderAsset: yes
timeCreated: 1626271522
licenseType: Store
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:f159de6e672ca3a96214f5959b2764b767b47e5f995ff7e3f424a11877a33454
size 82978
@@ -0,0 +1,16 @@
fileFormatVersion: 2
guid: 078b33d3bbdbd3f478bca270510b58aa
timeCreated: 1626290549
licenseType: Store
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 67880
packageName: Easy Collider Editor
packageVersion: 6.18.1
assetPath: Assets/EasyColliderEditor/DOTS/EasyDOTSDocumentation.pdf
uploadId: 749371
@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 28e4c31123bcd614b910d5cfe5c82e2e
folderAsset: yes
timeCreated: 1626290231
licenseType: Store
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,18 @@
#if (UNITY_EDITOR)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace ECE
{
// This is just the empty class that get's overwritten to add DOTS support.
// This make it much simpler for future updates to also work with DOTS as
// the only thing it does is convert the colliders through the UI Button.
// by having the same class with required method, we don't need to adjust
// other scripts each update.
public class EasyColliderDOTS
{
public void OnInspectorGUI(EasyColliderEditor Editor) { }
}
}
#endif
@@ -0,0 +1,20 @@
fileFormatVersion: 2
guid: e230396c964eb92469ecb21529e1f10b
timeCreated: 1626271532
licenseType: Store
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 67880
packageName: Easy Collider Editor
packageVersion: 6.18.1
assetPath: Assets/EasyColliderEditor/DOTS/Scripts/EasyColliderDOTS.cs
uploadId: 749371
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:f44f5c64593ec847df61fe06426abd4f2e3c1bb3800c0f28700289d04885c61e
size 4941277
@@ -0,0 +1,14 @@
fileFormatVersion: 2
guid: b04cc4b7e03f58f46a6bd2a7b3fe4498
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 67880
packageName: Easy Collider Editor
packageVersion: 6.18.1
assetPath: Assets/EasyColliderEditor/EasyColliderEditorDocumentation.pdf
uploadId: 749371
+8
View File
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 723d55ae3f9555c42bcd3edb401a4613
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:f84a2424e992091f841f148dbf9f7698e17a4aec587d2265b88ef209f4517dc5
size 19184
@@ -0,0 +1,106 @@
fileFormatVersion: 2
guid: e998347e00b1629449691174d6ce75de
TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 9
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: -1
aniso: -1
mipBias: -100
wrapU: 1
wrapV: 1
wrapW: -1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
platformSettings:
- serializedVersion: 2
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
- serializedVersion: 2
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID: 82ac149ea221fb545a0fb56f2203b797
vertices: []
indices:
edges: []
weights: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 67880
packageName: Easy Collider Editor
packageVersion: 6.18.1
assetPath: Assets/EasyColliderEditor/Icons/ECEUIBox32.png
uploadId: 749371
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:8539e0fa41b5f5edc6152068e5e48bee6180100821c1f18f558e58076bd9788f
size 21792
@@ -0,0 +1,106 @@
fileFormatVersion: 2
guid: 480816d7d5b863f42984e0a47484f216
TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 9
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: -1
aniso: -1
mipBias: -100
wrapU: 1
wrapV: 1
wrapW: -1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
platformSettings:
- serializedVersion: 2
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
- serializedVersion: 2
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID: e7eeee5780c59014ea4b310dbd384852
vertices: []
indices:
edges: []
weights: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 67880
packageName: Easy Collider Editor
packageVersion: 6.18.1
assetPath: Assets/EasyColliderEditor/Icons/ECEUIBox32Merge.png
uploadId: 749371
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:58a6ed72e8a8e4135aa282d07ad765a7cbb4cd76943a76829cbbf4d7851d1dce
size 19527
@@ -0,0 +1,106 @@
fileFormatVersion: 2
guid: 1b9402ac744555345b9f6111ff8c4b8a
TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 9
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: -1
aniso: -1
mipBias: -100
wrapU: 1
wrapV: 1
wrapW: -1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
platformSettings:
- serializedVersion: 2
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
- serializedVersion: 2
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID: ec9b94295078e8e4989339a3c3f2c388
vertices: []
indices:
edges: []
weights: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 67880
packageName: Easy Collider Editor
packageVersion: 6.18.1
assetPath: Assets/EasyColliderEditor/Icons/ECEUICapsule32.png
uploadId: 749371
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:f1e162b48c7b9c635bc380831306f1fd42ae78e23f4ce97e16ecb5464a4ee104
size 20242
@@ -0,0 +1,106 @@
fileFormatVersion: 2
guid: 0ad3709299b6f5e44a2db34afc52ccd4
TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 9
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: -1
aniso: -1
mipBias: -100
wrapU: 1
wrapV: 1
wrapW: -1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
platformSettings:
- serializedVersion: 2
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
- serializedVersion: 2
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID: f27b277bd5d034d4097d222005f63399
vertices: []
indices:
edges: []
weights: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 67880
packageName: Easy Collider Editor
packageVersion: 6.18.1
assetPath: Assets/EasyColliderEditor/Icons/ECEUICapsule32Merge.png
uploadId: 749371
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:6a6643dffa6fa560129473eda461a5929a2bacdfe03ef64bca8c802bcd2117a8
size 19797
@@ -0,0 +1,106 @@
fileFormatVersion: 2
guid: 53b9b7a941c40804b8179b13ecf40b09
TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 9
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: -1
aniso: -1
mipBias: -100
wrapU: 1
wrapV: 1
wrapW: -1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
platformSettings:
- serializedVersion: 2
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
- serializedVersion: 2
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID: eaf3439ed7ce6624ca3aba5a5563f408
vertices: []
indices:
edges: []
weights: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 67880
packageName: Easy Collider Editor
packageVersion: 6.18.1
assetPath: Assets/EasyColliderEditor/Icons/ECEUIConvexMesh32.png
uploadId: 749371
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:133ea62a996ccaf73b32d279d2df1f7da7453689c33a34ce26111d7b92cc8aca
size 20493
@@ -0,0 +1,106 @@
fileFormatVersion: 2
guid: b0c31ecbc9bd28e4e8ac1e5e43ba307e
TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 9
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: -1
aniso: -1
mipBias: -100
wrapU: 1
wrapV: 1
wrapW: -1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
platformSettings:
- serializedVersion: 2
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
- serializedVersion: 2
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID: 15c81a624ef7f0a46ac5c566730ebca8
vertices: []
indices:
edges: []
weights: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 67880
packageName: Easy Collider Editor
packageVersion: 6.18.1
assetPath: Assets/EasyColliderEditor/Icons/ECEUIConvexMesh32Merge.png
uploadId: 749371
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:786212f9fe7987fae57797492635321c61a962ffb6506806edcc8bbe1fe6bb03
size 21906
@@ -0,0 +1,106 @@
fileFormatVersion: 2
guid: ccbaf976cae4b064f9a918823e8f6552
TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 9
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: -1
aniso: -1
mipBias: -100
wrapU: 1
wrapV: 1
wrapW: -1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
platformSettings:
- serializedVersion: 2
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
- serializedVersion: 2
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID: 4674b33d58a9a5d45b39418124f53ac9
vertices: []
indices:
edges: []
weights: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 67880
packageName: Easy Collider Editor
packageVersion: 6.18.1
assetPath: Assets/EasyColliderEditor/Icons/ECEUICylinder32.png
uploadId: 749371
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:8020279a429e85ecc71b90c3d7e2aeea1987937bab3060469b3460668a10f18d
size 21879
@@ -0,0 +1,106 @@
fileFormatVersion: 2
guid: 2d782a0c73983ee4b95417abf7be42ef
TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 9
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: -1
aniso: -1
mipBias: -100
wrapU: 1
wrapV: 1
wrapW: -1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
platformSettings:
- serializedVersion: 2
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
- serializedVersion: 2
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID: 6d9f9948f75eff44b8243fe5f1bc1a83
vertices: []
indices:
edges: []
weights: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 67880
packageName: Easy Collider Editor
packageVersion: 6.18.1
assetPath: Assets/EasyColliderEditor/Icons/ECEUICylinder32Merge.png
uploadId: 749371
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:8f632e058d1d654ca617cb5ecb7fb59c5a9a041f674169df61d417884bcb259a
size 20028
@@ -0,0 +1,106 @@
fileFormatVersion: 2
guid: 06f5537b1554be7429d39076a339a6e9
TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 9
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: -1
aniso: -1
mipBias: -100
wrapU: 1
wrapV: 1
wrapW: -1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
platformSettings:
- serializedVersion: 2
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
- serializedVersion: 2
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID: 43dba5d881a539c46b514427a4041b89
vertices: []
indices:
edges: []
weights: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 67880
packageName: Easy Collider Editor
packageVersion: 6.18.1
assetPath: Assets/EasyColliderEditor/Icons/ECEUIRotatedBox32.png
uploadId: 749371
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:caa8932a3a5f62bd8519c88964d100e45f6077cc7d7d2dd487f317ae3de9fc47
size 22812
@@ -0,0 +1,106 @@
fileFormatVersion: 2
guid: 9759e644c16116c46ad7d928f57b00be
TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 9
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: -1
aniso: -1
mipBias: -100
wrapU: 1
wrapV: 1
wrapW: -1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
platformSettings:
- serializedVersion: 2
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
- serializedVersion: 2
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID: 1fbf28e7ef18a624b882903ec37cf195
vertices: []
indices:
edges: []
weights: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 67880
packageName: Easy Collider Editor
packageVersion: 6.18.1
assetPath: Assets/EasyColliderEditor/Icons/ECEUIRotatedBox32Merge.png
uploadId: 749371
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:204dd2f0c8ddd7de4c6ff94cb5428d6d2b94d901e60e40b140e5cbf677664a74
size 19846
@@ -0,0 +1,106 @@
fileFormatVersion: 2
guid: b909a7c899938ca4d8c9705a045fe410
TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 9
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: -1
aniso: -1
mipBias: -100
wrapU: 1
wrapV: 1
wrapW: -1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
platformSettings:
- serializedVersion: 2
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
- serializedVersion: 2
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID: b586c269269556a418cca90db1e955c1
vertices: []
indices:
edges: []
weights: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 67880
packageName: Easy Collider Editor
packageVersion: 6.18.1
assetPath: Assets/EasyColliderEditor/Icons/ECEUIRotatedCapsule32.png
uploadId: 749371
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:be44f82fc5000d44c7ded1a85b683e425d36096bf65a6bb8e58b40eebd0343e6
size 22709
@@ -0,0 +1,106 @@
fileFormatVersion: 2
guid: 764a526c991bd194cbfc2f4319b1d8dc
TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 9
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: -1
aniso: -1
mipBias: -100
wrapU: 1
wrapV: 1
wrapW: -1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
platformSettings:
- serializedVersion: 2
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
- serializedVersion: 2
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID: fa24b5ba62ace4d47990cefe71a46da7
vertices: []
indices:
edges: []
weights: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 67880
packageName: Easy Collider Editor
packageVersion: 6.18.1
assetPath: Assets/EasyColliderEditor/Icons/ECEUIRotatedCapsule32Merge.png
uploadId: 749371
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:324c2f03ab47ac8a532112d1fea317f7c194ba46459d0d2803980d138af14533
size 19835
@@ -0,0 +1,106 @@
fileFormatVersion: 2
guid: e01e5ee2b0ff2214196190f59f373bac
TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 9
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: -1
aniso: -1
mipBias: -100
wrapU: 1
wrapV: 1
wrapW: -1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
platformSettings:
- serializedVersion: 2
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
- serializedVersion: 2
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID: 50086ebfa2f74a447b9f73bcb4ebf480
vertices: []
indices:
edges: []
weights: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 67880
packageName: Easy Collider Editor
packageVersion: 6.18.1
assetPath: Assets/EasyColliderEditor/Icons/ECEUISphere32.png
uploadId: 749371
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:88412a0728ab18ac35e99662c22c74915988850697786a092bf5eec4181f9088
size 20552
@@ -0,0 +1,106 @@
fileFormatVersion: 2
guid: 950da02c7c566da49bd0785d2f903f0f
TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 9
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: -1
aniso: -1
mipBias: -100
wrapU: 1
wrapV: 1
wrapW: -1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
platformSettings:
- serializedVersion: 2
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
- serializedVersion: 2
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID: 76f0a0b7288f5c940b9cd55cb702ba24
vertices: []
indices:
edges: []
weights: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 67880
packageName: Easy Collider Editor
packageVersion: 6.18.1
assetPath: Assets/EasyColliderEditor/Icons/ECEUISphereMerge32.png
uploadId: 749371
+8
View File
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: e652979cf9e1eac4e90f77a15a69ff0c
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,20 @@
fileFormatVersion: 2
guid: 45eb3a409ea753b44ab3bb6b8585be07
timeCreated: 1591641873
licenseType: Store
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 67880
packageName: Easy Collider Editor
packageVersion: 6.18.1
assetPath: Assets/EasyColliderEditor/Scripts/EasyColliderAutoSkinned.cs
uploadId: 749371
@@ -0,0 +1,97 @@
using System.Collections.Generic;
using UnityEngine;
namespace ECE
{
[System.Serializable]
/// <summary>
/// Class to hold data for a skinned meshes' bones
/// Used because the bones transform array can be empty in cases where optimize gameobjects is used on import
/// The bindbose index of a bone, is the same as a bone's boneindex, so boneweight's can still be used.
/// </summary>
public class EasyColliderAutoSkinnedBone
{
public SkinnedMeshRenderer renderer;
/// <summary>
/// Create a collider for this bone?
/// </summary>
public bool Enabled = true;
/// <summary>
/// What kind of collider to create.
/// </summary>
public SKINNED_MESH_COLLIDER_TYPE ColliderType = SKINNED_MESH_COLLIDER_TYPE.Box;
/// <summary>
/// Minimum skinning bone weight to include a vertex in the bone's collider calculations.
/// </summary>
public float BoneWeight = 0.5f;
/// <summary>
/// Bone's display name (transform.name)
/// </summary>
public string BoneName = "Default";
/// <summary>
/// Is this bone paired with another bone?
/// </summary>
public bool IsPaired = false;
/// <summary>
/// If this bone is paired, is this the bone that is displayed in the UI?
/// </summary>
public bool IsPairDisplayBone = false;
/// <summary>
/// Is this bone valid? (Has at least 1 vertex that meets it's boneWeight)
/// </summary>
public bool IsValid = false;
public EasyColliderAutoSkinnedBone(Matrix4x4 bp, int index, Transform t)
{
BoneIndex = index;
BindPose = bp;
Transform = t;
}
/// <summary>
/// Local to world matrix of the bone's transform.
/// </summary>
public Matrix4x4 Matrix;
/// <summary>
/// Bind pose of the bone
/// </summary>
public Matrix4x4 BindPose;
/// <summary>
/// Bind pose index is the bone index as well.
/// </summary>
public int BoneIndex;
/// <summary>
/// Transform of the bone
/// </summary>
public Transform Transform;
/// <summary>
/// List of vertices in world space for this bo
/// </summary>
/// <typeparam name="Vector3"></typeparam>
/// <returns></returns>
public List<Vector3> WorldSpaceVertices = new List<Vector3>();
[SerializeField]
/// <summary>
/// List of other bone's index's in the BoneList that this bone is paired with.
/// </summary>
/// <typeparam name="int"></typeparam>
/// <returns></returns>
public List<int> PairedBones = new List<int>();
/// <summary>
/// Collider for this bone.
/// </summary>
public Collider Collider;
/// <summary>
/// Indent level of this bone when displaying in UI.
/// </summary>
public int IndentLevel = -1;
}
}
@@ -0,0 +1,20 @@
fileFormatVersion: 2
guid: 22d8868ad24ea0c43828e22314004216
timeCreated: 1625687084
licenseType: Store
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 67880
packageName: Easy Collider Editor
packageVersion: 6.18.1
assetPath: Assets/EasyColliderEditor/Scripts/EasyColliderAutoSkinnedBone.cs
uploadId: 749371
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 241873a664ee81d418528c165ef0dd12
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 67880
packageName: Easy Collider Editor
packageVersion: 6.18.1
assetPath: Assets/EasyColliderEditor/Scripts/EasyColliderCreator.cs
uploadId: 749371
@@ -0,0 +1,125 @@
using UnityEngine;
namespace ECE
{
/// <summary>
/// Data holder for collider calculations.
/// </summary>
public class EasyColliderData
{
/// <summary>
/// Type of collider data
/// </summary>
public CREATE_COLLIDER_TYPE ColliderType;
/// <summary>
/// Did the collider calculation complete
/// </summary>
public bool IsValid = false;
/// <summary>
/// TRS matrix of the attach to object, or TRS matrix of what the rotated collider will have
/// </summary>
public Matrix4x4 Matrix;
public void Clone(EasyColliderData data)
{
this.ColliderType = data.ColliderType;
this.IsValid = data.IsValid;
this.Matrix = data.Matrix;
}
}
/// <summary>
/// Data for creating a sphere collider
/// </summary>
public class SphereColliderData : EasyColliderData
{
/// <summary>
/// Radius of the collider
/// </summary>
public float Radius;
/// <summary>
/// Center of the collider
/// </summary>
public Vector3 Center;
public void Clone(SphereColliderData data)
{
base.Clone(data);
this.Radius = data.Radius;
this.Center = data.Center;
}
}
/// <summary>
/// Data for creating a capsule collider
/// </summary>
public class CapsuleColliderData : SphereColliderData
{
/// <summary>
/// Direction of the capsule collider
/// </summary>
public int Direction;
/// <summary>
/// Height of the capsule collider
/// </summary>
public float Height;
public void Clone(CapsuleColliderData data)
{
base.Clone(data);
this.Direction = data.Direction;
this.Height = data.Height;
}
}
/// <summary>
/// Data for creating a box collider
/// </summary>
public class BoxColliderData : EasyColliderData
{
/// <summary>
/// Center of the box collider
/// </summary>
public Vector3 Center;
/// <summary>
/// Size of the box collider
/// </summary>
public Vector3 Size;
public void Clone(BoxColliderData data)
{
base.Clone(data);
this.Center = data.Center;
this.Size = data.Size;
this.Matrix = data.Matrix;
}
public override string ToString()
{
return "Rotated box collider. Center:" + Center.ToString() + " Size:" + Size.ToString();
}
}
/// <summary>
/// Data for creating a mesh collider
/// </summary>
public class MeshColliderData : EasyColliderData
{
/// <summary>
/// Mesh of the convex mesh collider
/// </summary>
public Mesh ConvexMesh;
public void Clone(MeshColliderData data)
{
base.Clone(data);
this.ConvexMesh = data.ConvexMesh;
}
}
}
@@ -0,0 +1,20 @@
fileFormatVersion: 2
guid: f703485b98da54c489209f1fd7ad2db9
timeCreated: 1593006697
licenseType: Store
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 67880
packageName: Easy Collider Editor
packageVersion: 6.18.1
assetPath: Assets/EasyColliderEditor/Scripts/EasyColliderData.cs
uploadId: 749371
@@ -0,0 +1,160 @@
#if (UNITY_EDITOR)
using UnityEngine;
using UnityEditor;
namespace ECE
{
public static class EasyColliderDraw
{
/// <summary>
/// Draws a box
/// </summary>
/// <param name="transform">Transform of the box</param>
/// <param name="center">Center of the box in local space</param>
/// <param name="halfSize">Half the size of the box</param>
/// <param name="color">Color of lines used to draw the box</param>
private static void DrawBox(Transform transform, Vector3 center, Vector3 halfSize, Color color)
{
Vector3 p1 = transform.TransformPoint(center + halfSize);
Vector3 p2 = transform.TransformPoint(center - halfSize);
Vector3 p3 = transform.TransformPoint(center + new Vector3(halfSize.x, halfSize.y, -halfSize.z));
Vector3 p4 = transform.TransformPoint(center + new Vector3(halfSize.x, -halfSize.y, halfSize.z));
Vector3 p5 = transform.TransformPoint(center + new Vector3(halfSize.x, -halfSize.y, -halfSize.z));
Vector3 p6 = transform.TransformPoint(center + new Vector3(-halfSize.x, halfSize.y, halfSize.z));
Vector3 p7 = transform.TransformPoint(center + new Vector3(-halfSize.x, -halfSize.y, halfSize.z));
Vector3 p8 = transform.TransformPoint(center + new Vector3(-halfSize.x, halfSize.y, -halfSize.z));
Handles.color = color;
Handles.DrawLine(p1, p3);
Handles.DrawLine(p1, p4);
Handles.DrawLine(p1, p6);
Handles.DrawLine(p8, p3);
Handles.DrawLine(p8, p6);
Handles.DrawLine(p8, p2);
Handles.DrawLine(p7, p6);
Handles.DrawLine(p7, p2);
Handles.DrawLine(p7, p4);
Handles.DrawLine(p5, p4);
Handles.DrawLine(p5, p2);
Handles.DrawLine(p5, p3);
}
/// <summary>
/// Draws a box collider
/// </summary>
/// <param name="boxCollider">Box collider to draw</param>
/// <param name="color">Color of lines used to draw</param>
private static void DrawBoxCollider(BoxCollider boxCollider, Color color)
{
DrawBox(boxCollider.transform, boxCollider.center, boxCollider.size / 2, color);
}
private static EasyColliderPreviewer previewer;
public static EasyColliderPreviewer Previewer
{
get
{
if (previewer == null)
{
previewer = ScriptableObject.CreateInstance<EasyColliderPreviewer>();
}
return previewer;
}
}
/// <summary>
/// Draws a capsule collider
/// </summary>
/// <param name="capsuleCollider">Capsule collider to draw</param>
/// <param name="color">Color of lines to draw</param>
private static void DrawCapsuleCollider(CapsuleCollider capsuleCollider, Color color)
{
CapsuleColliderData data = new CapsuleColliderData();
data.ColliderType = CREATE_COLLIDER_TYPE.CAPSULE;
data.Height = capsuleCollider.height;
data.Radius = capsuleCollider.radius;
data.Center = capsuleCollider.center;
data.Direction = capsuleCollider.direction;
data.Matrix = capsuleCollider.transform.localToWorldMatrix;
Previewer.DrawCapsuleCollider(data, color);
return;
}
/// <summary>
/// Draws a primitive collider (box, sphere, capsule) using lines.
/// </summary>
/// <param name="collider">Collider to draw</param>
/// <param name="color">Color of lines to draw with</param>
public static void DrawCollider(Collider collider, Color color)
{
if (collider == null) return;
if (collider is BoxCollider)
{
DrawBoxCollider(collider as BoxCollider, color);
}
else if (collider is SphereCollider)
{
DrawSphereCollider(collider as SphereCollider, color);
}
else if (collider is CapsuleCollider)
{
DrawCapsuleCollider(collider as CapsuleCollider, color);
}
else if (collider is MeshCollider)
{
DrawMeshCollider(collider as MeshCollider, color);
}
}
/// <summary>
/// Shader used to draw mesh colliders.
/// </summary>
static Shader MeshColliderShader;
/// <summary>
/// Draws a mesh collider by drawing lines connecting it's meshs vertices.
/// </summary>
/// <param name="collider">Mesh Collider</param>
/// <param name="color">Color to draw lines with</param>
private static void DrawMeshCollider(MeshCollider collider, Color color)
{
// try to find mesh collider.
if (MeshColliderShader == null)
{
MeshColliderShader = Shader.Find("Custom/EasyColliderMeshColliderPreview");
}
// if we have the shader, draw it using the wireframe and the color
if (MeshColliderShader != null && collider != null && collider.sharedMesh != null)
{
Material wireMat = new Material(MeshColliderShader);
wireMat.SetColor("_Color", color);
wireMat.SetPass(0);
GL.wireframe = true;
Graphics.DrawMeshNow(collider.sharedMesh, collider.transform.localToWorldMatrix);
GL.wireframe = false;
}
else
{
// no shader? fall back to old draw box method.
DrawBox(collider.transform, collider.transform.InverseTransformPoint(collider.bounds.center), collider.transform.InverseTransformVector(collider.bounds.extents), color);
}
}
// Draws a sphere collider, taken from previous version
/// <summary>
/// Draws a sphere collider.
/// </summary>
/// <param name="sphereCollider">Sphere collider to draw</param>
/// <param name="color">Color of lines used to draw</param>
private static void DrawSphereCollider(SphereCollider sphereCollider, Color color)
{
SphereColliderData data = new SphereColliderData();
data.ColliderType = CREATE_COLLIDER_TYPE.SPHERE;
data.Center = sphereCollider.center;
data.Radius = sphereCollider.radius;
data.Matrix = sphereCollider.transform.localToWorldMatrix;
Previewer.DrawSphereCollider(data, color);
}
}
}
#endif
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 3c95b61c7ebb7b14e9688b95552cef80
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 67880
packageName: Easy Collider Editor
packageVersion: 6.18.1
assetPath: Assets/EasyColliderEditor/Scripts/EasyColliderDraw.cs
uploadId: 749371
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 8765d9c9fa7824d4da8e37f5cc1913fa
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 67880
packageName: Easy Collider Editor
packageVersion: 6.18.1
assetPath: Assets/EasyColliderEditor/Scripts/EasyColliderEditor.cs
uploadId: 749371
@@ -0,0 +1,158 @@
namespace ECE
{
public enum NORMAL_OFFSET
{
Out,
In,
Both,
}
/// <summary>
/// Capsule method to use when creating a capsule
/// </summary>
public enum CAPSULE_COLLIDER_METHOD
{
BestFit,
MinMax,
MinMaxPlusRadius,
MinMaxPlusDiameter,
}
/// <summary>
/// Type of collider to create
/// </summary>
public enum CREATE_COLLIDER_TYPE
{
BOX,
ROTATED_BOX,
SPHERE,
CAPSULE,
ROTATED_CAPSULE,
CONVEX_MESH,
CYLINDER,
}
/// <summary>
/// Orientation of collider
/// </summary>
public enum COLLIDER_ORIENTATION
{
NORMAL,
ROTATED,
}
public enum CYLINDER_ORIENTATION
{
Automatic,
LocalX,
LocalY,
LocalZ
}
/// <summary>
/// Enum for spheres ot cubes when drawing gizmos
/// </summary>
public enum GIZMO_TYPE
{
CUBE,
SPHERE,
}
/// <summary>
/// enum for Shaders or Gizmos to draw vertices with.
/// </summary>
public enum RENDER_POINT_TYPE
{
SHADER,
GIZMOS,
}
/// <summary>
/// Collider type to use when automatically generating colliders along a bone chain for a skinned mesh renderer.
/// </summary>
public enum SKINNED_MESH_COLLIDER_TYPE
{
Box,
Capsule,
Sphere,
Convex_Mesh,
}
public enum SKINNED_MESH_DEPENETRATE_ORDER
{
InOrder,
Reverse,
InsideOut,
OutsideIn,
}
/// <summary>
/// Sphere method to use when creating a sphere
/// </summary>
public enum SPHERE_COLLIDER_METHOD
{
BestFit,
Distance,
MinMax,
}
public enum VHACD_CONVERSION
{
None,
Boxes,
Spheres,
Capsules,
}
public enum MESH_COLLIDER_METHOD
{
QuickHull,
MessyHull
}
public enum VERTEX_SNAP_METHOD
{
Add,
Remove,
Both,
}
/// <summary>
/// Method used to attach mesh colliders to the attach to object.
/// </summary>
public enum VHACD_RESULT_METHOD
{
AttachTo,
ChildObject,
IndividualChildObjects
}
/// <summary>
/// Current window tab selected in the editor window.
/// </summary>
public enum ECE_WINDOW_TAB
{
None = -1,
Creation = 0,
Editing = 1,
VHACD = 2,
AutoSkinned = 3,
}
public enum COLLIDER_HOLDER
{
Default,
Once,
Always
}
public enum CONVEX_HULL_SAVE_METHOD
{
Prefab,
Mesh,
PrefabMesh,
MeshPrefab,
Folder,
}
}
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: d3013554ca157424db48970772ea240c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 67880
packageName: Easy Collider Editor
packageVersion: 6.18.1
assetPath: Assets/EasyColliderEditor/Scripts/EasyColliderEnums.cs
uploadId: 749371
@@ -0,0 +1,185 @@
#if (UNITY_EDITOR)
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
namespace ECE
{
/// <summary>
/// Used to draw gizmos for selected / hovered vertices
/// Gizmos draw significantly faster than handles.
/// </summary>
[System.Serializable]
public class EasyColliderGizmos : MonoBehaviour, ISerializationCallbackReceiver
{
#region preference settings
private EasyColliderPreferences ECEPreferences
{
get { return EasyColliderPreferences.Preferences; }
}
public float CommonScale { get { return ECEPreferences.CommonScalingMultiplier; } }
public float DefaultScale { get { return ECEPreferences.DefaultScale; } }
public bool DisplayAllVertices { get { return ECEPreferences.DisplayAllVertices; } }
public Color DisplayVertexColor { get { return ECEPreferences.DisplayVerticesColour; } }
public GIZMO_TYPE GizmoType { get { return ECEPreferences.GizmoType; } }
public Color HoveredVertexColor { get { return ECEPreferences.HoverVertColour; } }
public Color OverlapVertexColor { get { return ECEPreferences.OverlapSelectedVertColour; } }
public Color SelectedVertexColor { get { return ECEPreferences.SelectedVertColour; } }
public bool UseFixedGizmoScale { get { return ECEPreferences.UseFixedGizmoScale; } }
#endregion
/// <summary>
/// calculated density scale if use density scale is enabled.
/// </summary>
public float DensityScale = 0.0f;
/// <summary>
/// List of all valid vertex positions in world space
/// </summary>
public HashSet<Vector3> DisplayVertexPositions = new HashSet<Vector3>();
/// <summary>
/// Should gizmos be drawn
/// </summary>
public bool DrawGizmos = true;
/// <summary>
/// Set of hovered vertices in world space
/// </summary>
public HashSet<Vector3> HoveredVertexPositions = new HashSet<Vector3>();
/// <summary>
/// Set of selected vertices in world space
/// </summary>
public HashSet<Vector3> SelectedVertexPositions = new HashSet<Vector3>();
float GetScale()
{
// *10 makes it more equivalent to how the shader is drawn.
float scale = DefaultScale * CommonScale * 10;
if (scale <= 0.0f)
{
scale = ECEPreferences.DefaultScale * 10;
}
return scale;
}
void OnDrawGizmos()
{
if (DrawGizmos)
{
// Keep track of gizmos color to reset at end
Color original = Gizmos.color;
// Selected vertices.
// scale for spheres.
float scale = GetScale();
// size for cubes
Vector3 size = Vector3.one * scale;
// default scaling of 1.0f
float handleSize = 1.0f;
// Display all vertices.
if (DisplayAllVertices)
{
Gizmos.color = DisplayVertexColor;
foreach (Vector3 vert in DisplayVertexPositions)
{
if (UseFixedGizmoScale)
{
handleSize = HandleUtility.GetHandleSize(vert);
}
DrawAGizmo(vert, size * handleSize, scale * handleSize, GizmoType);
}
}
// Selected vertices
Gizmos.color = SelectedVertexColor;
foreach (Vector3 vert in SelectedVertexPositions)
{
if (UseFixedGizmoScale)
{
handleSize = HandleUtility.GetHandleSize(vert);
}
DrawAGizmo(vert, size * handleSize, scale * handleSize, GizmoType);
}
// Hover vertices.
Gizmos.color = HoveredVertexColor;
foreach (Vector3 vert in HoveredVertexPositions)
{
if (SelectedVertexPositions.Contains(vert))
{
if (UseFixedGizmoScale)
{
handleSize = HandleUtility.GetHandleSize(vert);
}
Gizmos.color = OverlapVertexColor;
DrawAGizmo(vert, size * handleSize, scale * handleSize, GizmoType);
}
else
{
if (UseFixedGizmoScale)
{
handleSize = HandleUtility.GetHandleSize(vert);
}
Gizmos.color = HoveredVertexColor;
DrawAGizmo(vert, size * handleSize, scale * handleSize, GizmoType);
}
}
Gizmos.color = original;
}
}
/// <summary>
/// Draws a gizmo of type at position at size or scale.
/// </summary>
/// <param name="position">World position to draw at</param>
/// <param name="size">Size of cube to draw</param>
/// <param name="scale">Radius of sphere to draw</param>
/// <param name="gizmoType">Sphere or Cubes?</param>
private void DrawAGizmo(Vector3 position, Vector3 size, float scale, GIZMO_TYPE gizmoType)
{
switch (gizmoType)
{
case GIZMO_TYPE.SPHERE:
Gizmos.DrawSphere(position, scale / 2);
break;
case GIZMO_TYPE.CUBE:
Gizmos.DrawCube(position, size);
break;
}
}
/// <summary>
/// Sets the set of selected vertices from a list of selected world vertices
/// </summary>
/// <param name="worldVertices">List of world vertex positions that are selected</param>
public void SetSelectedVertices(List<Vector3> worldVertices)
{
SelectedVertexPositions.Clear();
SelectedVertexPositions.UnionWith(worldVertices);
}
public List<Vector3> SerializedDisplayVertexPositions = new List<Vector3>();
public List<Vector3> SerializedHoveredVertexPositions = new List<Vector3>();
public List<Vector3> SerializedSelectedVertexPositions = new List<Vector3>();
public void OnBeforeSerialize()
{
SerializedDisplayVertexPositions.AddRange(DisplayVertexPositions);
SerializedHoveredVertexPositions.AddRange(HoveredVertexPositions);
SerializedSelectedVertexPositions.AddRange(SelectedVertexPositions);
}
public void OnAfterDeserialize()
{
DisplayVertexPositions.UnionWith(SerializedDisplayVertexPositions);
HoveredVertexPositions.UnionWith(SerializedHoveredVertexPositions);
SelectedVertexPositions.UnionWith(SerializedSelectedVertexPositions);
}
}
}
#endif
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 7302dd3862f934949a13c03008aba827
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 67880
packageName: Easy Collider Editor
packageVersion: 6.18.1
assetPath: Assets/EasyColliderEditor/Scripts/EasyColliderGizmos.cs
uploadId: 749371
@@ -0,0 +1,55 @@
using UnityEngine;
namespace ECE
{
public class EasyColliderPostProccessor : IEasyColliderPostProcessor
{
// The default implementation does nothing.
// Can be used to add your own code if you want to do something specifically to each type of collider.
// If you're creating colliders at runtime with EasyColliderCreator, you can also set the post processor through code,
// if you don't it will by default use this implementation
// NOTE: this happens for every single collider created in this asset / created by EasyColliderCreator
// Vertex selected created colliders, merged colliders, auto skinned colliders, vhacd colliders all go through these methods.
/// <summary>
/// post processes a box collider, properties orientation indiciates if it's a rotated collider.
/// </summary>
/// <param name="box"></param>
/// <param name="properties"></param>
public void PostProcessCollider(BoxCollider boxCollider, EasyColliderProperties properties)
{
// in here you'll get passed a completely generated box collider, and can do whatever you want with it.
}
/// <summary>
/// post processes a capsule collider, properties orientation indiciates if it's a rotated collider.
/// </summary>
/// <param name="box"></param>
/// <param name="properties"></param>
public void PostProcessCollider(CapsuleCollider capsuleCollider, EasyColliderProperties properties)
{
// in here you'll get passed a completely generated capsule collider, and can do whatever you want with it.
}
/// <summary>
/// post processes a sphere collider
/// </summary>
/// <param name="box"></param>
/// <param name="properties"></param>
public void PostProcessCollider(SphereCollider sphereCollider, EasyColliderProperties properties)
{
// in here you'll get passed a completely generated sphere collider, and can do whatever you want with it.
}
/// <summary>
/// post processes a mesh collider. cylinder colliders are mesh colliders as well.
/// </summary>
/// <param name="box"></param>
/// <param name="properties"></param>
public void PostProcessCollider(MeshCollider meshCollider, EasyColliderProperties properties)
{
// in here you'll get passed a completely generated mesh collider, and can do whatever you want with it.
}
}
}
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: c4635610932a87342a4bf2e41e9ab050
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 67880
packageName: Easy Collider Editor
packageVersion: 6.18.1
assetPath: Assets/EasyColliderEditor/Scripts/EasyColliderPostProccessor.cs
uploadId: 749371
@@ -0,0 +1,99 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: fb5e4193615d8464a82ea935f90494a0, type: 3}
m_Name: EasyColliderPreferences
m_EditorClassIdentifier:
VHACDResFloat: 13.287712
AllowBackgroundSelection: 0
AllowSavingConvexHullsInPackages: 0
AutoSelectOnPrefabOpen: 0
AutoIncludeChildSkinnedMeshes: 1
AutoSkinnedForce256Triangles: 1
AutoSkinnedMinBoneWeight: 0.5
AutoSkinnedMinRealignAngle: 2.4
AutoSkinnedAllowRealign: 1
AutoSkinnedColliderType: 0
AutoSkinnedDepenetrate: 0
AutoSkinnedIndents: 1
AutoSkinnedIterativeDepenetrationCount: 15
AutoSkinnedPairing: 1
AutoSkinnedPerBoneSettings: 1
AutoSkinnedShrinkAmount: 0.5
AutoSkinnedUseDistanceDeltaPairing: 1
AutoSkinnedPairedDistanceDelta: 0.01
AutoSkinnedDepenetrateOrder: 3
BoxSelectPlusKey: 97
BoxSelectMinusKey: 115
CapsuleColliderMethod: 1
CombinedVHACDColliders: 1
CommonScalingMultiplier: 1
ConvexMeshReadWriteEnabled: 1
DefaultScale: 0.01
HoveredScaleMult: 1
DisplayAllScaleMult: 1
OverlapScaleMult: 1
SelectedScaleMult: 1
ColliderHolder: 0
CreateFromPreviewKey: 96
CylinderAsCapsuleOrientation: 0
CylinderNumberOfSides: 16
CylinderOrientation: 0
CylinderRotationOffset: 0
DisplayTips: 1
DisplayAllVertices: 0
DisplayVerticesColour: {r: 0, g: 0, b: 1, a: 1}
EnableVertexToolsShortcuts: 1
GizmoType: 1
HoverVertColour: {r: 0, g: 1, b: 1, a: 1}
MergeCollidersRoundnessAccuracy: 10
MeshColliderMethod: 0
OverlapSelectedVertColour: {r: 1, g: 0, b: 0, a: 1}
PointSelectKeyCode: 98
PopupDialogOnFinish: 0
PreviewColliderType: 0
PreviewDrawColor: {r: 0, g: 1, b: 1, a: 1}
PreviewEnabled: 1
RaycastDelayTime: 0.1
RenderPointType: 0
RemoveMergedColliders: 1
CopyParentObjectLayer: 1
RotatedColliderPivotAtCenter: 0
rotatedDupeSettings:
enabled: 0
axis: 0
NumberOfDuplications: 4
StartRotation: 0
EndRotation: 360
pivot: {fileID: 0}
attachTo: {fileID: 0}
SaveConvexHullAsAsset: 1
ConvexHullSaveMethod: 2
SaveConvexHullPath: Assets/EasyColliderEditor/Convex Hulls/
SaveConvexHullSubFolder:
SaveConvexHullSuffix: _ConvexHull_
SelectedVertColour: {r: 0, g: 1, b: 0, a: 1}
ShortcutInvert: 105
ShortcutGrow: 103
ShortcutGrowLast: 108
ShortcutClear: 99
ShortcutRing: 114
ShowSelectedVertexCount: 0
SphereColliderMethod: 2
UseFixedGizmoScale: 1
UseMouseClickSelection: 1
VertexNormalOffsetType: 2
VertexNormalOffset: 0
VertexNormalInset: 0
VertexSnapMethod: 2
VertSelectKeyCode: 118
VHACDPreview: 1
CurrentWindowTab: 0
@@ -0,0 +1,15 @@
fileFormatVersion: 2
guid: 99d3a08e9dc280246aa61e99c233b0c0
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 67880
packageName: Easy Collider Editor
packageVersion: 6.18.1
assetPath: Assets/EasyColliderEditor/Scripts/EasyColliderPreferences.asset
uploadId: 749371
@@ -0,0 +1,617 @@
#if (UNITY_EDITOR)
using UnityEngine;
using UnityEditor;
using System.IO;
namespace ECE
{
[System.Serializable]
public class EasyColliderPreferences : ScriptableObject
{
#if (!UNITY_EDITOR_LINUX)
/// <summary>
/// Currently set vhacd parameters.
/// </summary>
private VHACDParameters _VHACDParameters;
[SerializeField]
public VHACDParameters VHACDParameters
{
get
{
if (_VHACDParameters == null)
{
_VHACDParameters = new VHACDParameters();
}
return _VHACDParameters;
}
set { _VHACDParameters = value; }
}
/// <summary>
/// Float to convert to vhacd parameters resolution using 2^Value for UI Slider when advanced parameters is expanded
/// </summary>
[SerializeField] public float VHACDResFloat = 12.97f;
/// <summary>
/// Resets vhacd parameters to default.
/// </summary>
public void VHACDSetDefaultParameters()
{
VHACDParameters = new VHACDParameters();
}
#endif
/// <summary>
/// When enabled, selecting objects in the background of the scene view can be done with a single click even when an object is currently selected for collider creation.
/// </summary>
[SerializeField] public bool AllowBackgroundSelection;
/// <summary>
/// when enabled, allows convex hulls used in mesh colliders to be saved in Packages folder.
/// THESE FILES ARE NOT SHARED WITH JUST THE PROJECT. MUST BE HANDLED BY YOUR TEAM. MUST ALSO SHARE SOURCE PACKAGES FOLDERS
/// </summary>
[SerializeField] public bool AllowSavingConvexHullsInPackages;
/// <summary>
/// When entering prefab mode, should we automatically select the root object?
/// </summary>
[SerializeField] public bool AutoSelectOnPrefabOpen;
/// <summary>
/// Auto include child skinned meshes
/// </summary>
[SerializeField] public bool AutoIncludeChildSkinnedMeshes;
/// <summary>
/// Should we try to reduce the number of vertices in auto-skinned calculations for convex mesh colliders if the result ends up trying to create a collider that has >=256 triangles.
/// </summary>
[SerializeField] public bool AutoSkinnedForce256Triangles;
/// <summary>
/// The minimum weight for a vertex to be included in a bone's calculations.
/// </summary>
[SerializeField] public float AutoSkinnedMinBoneWeight;
/// <summary>
/// The angle of mis-alignedment above which we should create a better aligned child transform to hold colliders for skinned meshes.
/// </summary>
[SerializeField] public float AutoSkinnedMinRealignAngle;
/// <summary>
/// Should we allow transforms to be created that would better align the collider with the mesh than a mis-aligned bone?
/// </summary>
[SerializeField] public bool AutoSkinnedAllowRealign;
/// <summary>
/// Type of collider to use when auto generating skinned mesh colliders along a bone chain.
/// </summary>
[SerializeField] public SKINNED_MESH_COLLIDER_TYPE AutoSkinnedColliderType = SKINNED_MESH_COLLIDER_TYPE.Box;
/// <summary>
/// Should we be attempting to compute penetration and depenetrate the colliders on the skinned mesh?
/// </summary>
[SerializeField] public bool AutoSkinnedDepenetrate;
/// <summary>
/// Are we displaying with indentation?
/// </summary>
[SerializeField] public bool AutoSkinnedIndents = true;
/// <summary>
/// number of times to run depenetration methods before stopping.
/// </summary>
[SerializeField] public int AutoSkinnedIterativeDepenetrationCount = 15;
/// <summary>
/// Are we displaying with paired bones?
/// </summary>
[SerializeField] public bool AutoSkinnedPairing = true;
/// <summary>
/// Are we using per-bone settings
/// </summary>
[SerializeField] public bool AutoSkinnedPerBoneSettings;
/// <summary>
/// Amount of collider shrinking (along the various shift's) to do before trying to shift depenetrate.
/// </summary>
[SerializeField] public float AutoSkinnedShrinkAmount = 0.5f;
[Tooltip("Enables using bone position distances during pairing of bones. (AutoSkinnedPairedDistanceDelta controls the distance when enabled.")]
[SerializeField] public bool AutoSkinnedUseDistanceDeltaPairing = true;
[Tooltip("Max distance difference between possible bone pairs to still be considered as a pair. Checked along with length of child bone-chain.")]
[SerializeField] public float AutoSkinnedPairedDistanceDelta = 0.01f;
/// <summary>
/// The way we should sort the bone list in auto-skinned.
/// </summary>
[SerializeField] public SKINNED_MESH_DEPENETRATE_ORDER AutoSkinnedDepenetrateOrder;
/// <summary>
/// Key to hold before box selection to only add vertices in the box.
/// </summary>
[SerializeField] public KeyCode BoxSelectPlusKey;
/// <summary>
/// Key to hold before box selection to only remove vertices in the box.
/// </summary>
[SerializeField] public KeyCode BoxSelectMinusKey;
/// <summary>
/// Capsule collider generation method to use when creating a capsule collider.
/// </summary>
[SerializeField] public CAPSULE_COLLIDER_METHOD CapsuleColliderMethod;
/// <summary>
/// when enabled, when generating multiple convex mesh colliders with vhacd, they are all combined and stored in a single asset file.
/// </summary>
[SerializeField] public bool CombinedVHACDColliders;
/// <summary>
/// A helpful common multiplier for all scales when using any scaling method.
/// </summary>
[SerializeField] public float CommonScalingMultiplier = 1.0f;
/// <summary>
/// should created meshes used in convex mesh colliders be read/write enabled
/// </summary>
[SerializeField] public bool ConvexMeshReadWriteEnabled = true;
[Tooltip("Default scale of the displayed boxes / gizmos around vertices. Combined with common scaling multiplier.")]
/// <summary>
/// Default scale of displayed vertices used along with the common scaling multiplier.
/// </summary>
[SerializeField] public float DefaultScale = 0.01f;
/// <summary>
/// scale for vertices that are hovered / will be added to the selected vertices
/// </summary>
[SerializeField] public float HoveredScaleMult = 1.0f;
/// <summary>
/// scale multiplier for vertices when using display all vertices
/// </summary>
[SerializeField] public float DisplayAllScaleMult = 1.0f;
/// <summary>
/// scale multiplier for vertices that will be removed from the selected vertices
/// </summary>
[SerializeField] public float OverlapScaleMult = 1.0f;
/// <summary>
/// scale multiplier for vertices that are currently selected.
/// </summary>
[SerializeField] public float SelectedScaleMult = 1.0f;
/// <summary>
/// The method to use when creating a collider: if and how a gameobject should be made to hold the collider.
/// </summary>
[SerializeField] public COLLIDER_HOLDER ColliderHolder = COLLIDER_HOLDER.Default;
/// <summary>
/// key to press to create from the current preview.
/// </summary>
[SerializeField] public KeyCode CreateFromPreviewKey;
/// <summary>
/// Should cylinder orientation field apply to capsules as well.
/// </summary>
[SerializeField] public bool CylinderAsCapsuleOrientation = false;
/// <summary>
/// number of sides when creating a cylinder collider.
/// </summary>
[SerializeField] public int CylinderNumberOfSides = 16;
/// <summary>
/// Method to use to decide which axis a cylinder should be oriented on.
/// </summary>
[SerializeField] public CYLINDER_ORIENTATION CylinderOrientation;
/// <summary>
/// Offset in degrees when creating a cylinder.
/// </summary>
[SerializeField] public float CylinderRotationOffset = 0.0f;
/// <summary>
/// Should tips be displayed?
/// </summary>
[SerializeField] public bool DisplayTips;
/// <summary>
/// Should we display compute shader / gizmos on all the vertices?
/// </summary>
[SerializeField] public bool DisplayAllVertices;
/// <summary>
/// Display vertices colour
/// </summary>
[SerializeField] public Color DisplayVerticesColour;
[SerializeField] public bool EnableVertexToolsShortcuts = true;
/// <summary>
/// Type of gizmos to use when drawing gizmos for vertices
/// </summary>
public GIZMO_TYPE GizmoType;
/// <summary>
/// Hover vertices scaling colour
/// </summary>
[SerializeField] public Color HoverVertColour;
/// <summary>
/// Number of points to generate around a rounded portion of a collider like sphere or capsules
/// </summary>
[SerializeField] public int MergeCollidersRoundnessAccuracy = 10;
/// <summary>
/// Method to use when generating mesh colliders
/// </summary>
[SerializeField] public MESH_COLLIDER_METHOD MeshColliderMethod;
/// <summary>
/// Overlapped vertice scaling colour
/// </summary>
[SerializeField] public Color OverlapSelectedVertColour;
/// <summary>
/// Key used to select points (any point on a mesh that isn't a vertex)
/// </summary>
[SerializeField] public KeyCode PointSelectKeyCode;
[SerializeField] public bool PopupDialogOnFinish;
/// <summary>
/// Collider type we want to preview
/// </summary>
[SerializeField] public CREATE_COLLIDER_TYPE PreviewColliderType;
/// <summary>
/// Color of lines to draw previewed colliders with.
/// </summary>
[SerializeField] public Color PreviewDrawColor;
/// <summary>
/// Are previews enabled?
/// </summary>
[SerializeField] public bool PreviewEnabled;
/// <summary>
/// Raycast delay time, ie only check / select at increments of this time.
/// </summary>
[SerializeField] public float RaycastDelayTime;
/// <summary>
/// Render point method
/// </summary>
[SerializeField] public RENDER_POINT_TYPE RenderPointType;
/// <summary>
/// Should colliders that are merged together be removed after merging is completed?
/// </summary>
[SerializeField] public bool RemoveMergedColliders;
/// <summary>
/// If true, puts rotated colliders on the same layer as the selected gameobject.
/// </summary>
[SerializeField] public bool CopyParentObjectLayer;
/// <summary>
/// Should the rotated colliders pivot be created at the center of the points, or at 0?
/// </summary>
[SerializeField] public bool RotatedColliderPivotAtCenter;
/// <summary>
/// Settings of the current rotate and duplicate section in collider creation.
/// </summary>
[SerializeField] public EasyColliderRotateDuplicate rotatedDupeSettings;
/// <summary>
/// When true, meshes created from creating convex hulls are saved as assets.
/// </summary>
[SerializeField] public bool SaveConvexHullAsAsset;
/// <summary>
/// Specifies how to search for a location to save the convex hull .asset files.
/// </summary>
[SerializeField] public CONVEX_HULL_SAVE_METHOD ConvexHullSaveMethod = CONVEX_HULL_SAVE_METHOD.PrefabMesh;
/// <summary>
/// if SaveConvexHullMeshAtSelected is false, saves at the path specified.
/// </summary>
[SerializeField] public string SaveConvexHullPath;
/// <summary>
/// Provides a subfolder to save colliders in an asset path when saving near the mesh
/// IE: if the mesh/prefab is found in an Environments/Meshes folder, an Environments/Meshes/ConvexHulls folder would be created to store the collision meshes
/// if using anything other than CONVEX_HULL_SAVE_METHOD.Folder
/// </summary>
[SerializeField] public string SaveConvexHullSubFolder;
/// <summary>
/// Suffix with which to save convex hulls.
/// </summary>
[SerializeField] public string SaveConvexHullSuffix;
/// <summary>
/// Selected vertice scaling colour
/// </summary>
[SerializeField] public Color SelectedVertColour;
[SerializeField] public KeyCode ShortcutInvert = KeyCode.I;
[SerializeField] public KeyCode ShortcutGrow = KeyCode.G;
[SerializeField] public KeyCode ShortcutGrowLast = KeyCode.L;
[SerializeField] public KeyCode ShortcutClear = KeyCode.C;
[SerializeField] public KeyCode ShortcutRing = KeyCode.R;
/// <summary>
/// Should the number of selected vertices be displayed in the ui?
/// </summary>
[SerializeField] public bool ShowSelectedVertexCount;
/// <summary>
/// Sphere method to use when creating a sphere collider.
/// </summary>
public SPHERE_COLLIDER_METHOD SphereColliderMethod;
/// <summary>
/// Should HandleUtility.GetHandleSize be used when using gizmos to draw to keep gizmo size constant regardless of distance to camera?
/// </summary>
[SerializeField] public bool UseFixedGizmoScale;
/// <summary>
/// Enables using left click to select vertices, and right click to select points.
/// </summary>
[SerializeField] public bool UseMouseClickSelection = true;
[SerializeField] public NORMAL_OFFSET VertexNormalOffsetType = NORMAL_OFFSET.Both;
/// <summary>
/// Amount to offset the vertex (in direction of it's averaged normal)
/// </summary>
[SerializeField] public float VertexNormalOffset = 0f;
/// <summary>
/// Amount to inset the vertex (in opposite direction of it's averaged normal)
/// </summary>
[SerializeField] public float VertexNormalInset = 0f;
/// <summary>
/// Method used when raycasting for closest vertices, add (only snap to unselected verts), remove (only snap to selected verts), both (default)
/// </summary>
[SerializeField] public VERTEX_SNAP_METHOD VertexSnapMethod;
/// <summary>
/// Key used to select vertices.
/// </summary>
[SerializeField] public KeyCode VertSelectKeyCode;
/// <summary>
/// Should we update the VHACD calculation and preview as parameters change?
/// </summary>
[SerializeField] public bool VHACDPreview;
/// <summary>
/// For editor window tab tracking, maintains previously open tab.
/// </summary>
[SerializeField] public ECE_WINDOW_TAB CurrentWindowTab;
/// <summary>
/// Sets all values to default values.
/// </summary>
public void SetDefaultValues()
{
#region VHACD settings
#if (!UNITY_EDITOR_LINUX)
VHACDParameters = new VHACDParameters();
VHACDPreview = true;
#endif
#endregion
#region other settings
AutoIncludeChildSkinnedMeshes = true;
AutoSelectOnPrefabOpen = false;
DisplayTips = true;
DisplayAllVertices = false;
PopupDialogOnFinish = false;
PreviewEnabled = true;
RaycastDelayTime = 0.1f;
ShowSelectedVertexCount = false;
rotatedDupeSettings = new EasyColliderRotateDuplicate();
RotatedColliderPivotAtCenter = false;
CylinderAsCapsuleOrientation = false;
#endregion
#region autoskinned preferences
AutoSkinnedMinBoneWeight = 0.5f;
AutoSkinnedDepenetrate = false;
AutoSkinnedIterativeDepenetrationCount = 15;
AutoSkinnedPairing = true;
AutoSkinnedIndents = true;
AutoSkinnedColliderType = SKINNED_MESH_COLLIDER_TYPE.Box;
AutoSkinnedShrinkAmount = 0.5f;
// I find outside in to give the best results generally.
AutoSkinnedDepenetrateOrder = SKINNED_MESH_DEPENETRATE_ORDER.OutsideIn;
AutoSkinnedForce256Triangles = true;
AutoSkinnedUseDistanceDeltaPairing = true;
AutoSkinnedPairedDistanceDelta = 0.01f;
#endregion
#region inputs
// shifts do not work.
BoxSelectMinusKey = KeyCode.S;
BoxSelectPlusKey = KeyCode.A;
CreateFromPreviewKey = KeyCode.BackQuote;
PointSelectKeyCode = KeyCode.B;
UseMouseClickSelection = true;
VertSelectKeyCode = KeyCode.V;
EnableVertexToolsShortcuts = true;
ShortcutInvert = KeyCode.I;
ShortcutGrow = KeyCode.G;
ShortcutGrowLast = KeyCode.L;
ShortcutClear = KeyCode.C;
ShortcutRing = KeyCode.R;
#endregion
#region Collider Methods
CapsuleColliderMethod = CAPSULE_COLLIDER_METHOD.MinMax;
MeshColliderMethod = MESH_COLLIDER_METHOD.QuickHull;
PreviewColliderType = CREATE_COLLIDER_TYPE.BOX;
SphereColliderMethod = SPHERE_COLLIDER_METHOD.MinMax;
#endregion
#region Collider Settings / Paramaters
MergeCollidersRoundnessAccuracy = 10;
VertexNormalOffset = 0f;
VertexNormalInset = 0f;
VertexNormalOffsetType = NORMAL_OFFSET.Both;
ColliderHolder = COLLIDER_HOLDER.Default;
CylinderNumberOfSides = 16;
CylinderOrientation = CYLINDER_ORIENTATION.Automatic;
CylinderRotationOffset = 0.0f;
MeshColliderMethod = MESH_COLLIDER_METHOD.QuickHull;
RemoveMergedColliders = true;
CopyParentObjectLayer = true;
#endregion
#region drawing
CommonScalingMultiplier = 1.0f;
DefaultScale = 0.01f;
HoveredScaleMult = 1.0f;
DisplayAllScaleMult = 1.0f;
OverlapScaleMult = 1.0f;
SelectedScaleMult = 1.0f;
DisplayVerticesColour = Color.blue;
GizmoType = GIZMO_TYPE.SPHERE;
HoverVertColour = Color.cyan;
OverlapSelectedVertColour = Color.red;
PreviewDrawColor = Color.cyan;
if (SystemInfo.graphicsShaderLevel < 45)
{
RenderPointType = RENDER_POINT_TYPE.GIZMOS;
}
else
{
RenderPointType = RENDER_POINT_TYPE.SHADER;
}
SelectedVertColour = Color.green;
UseFixedGizmoScale = true;
#endregion
#region Save Convex Hull Settings
ConvexHullSaveMethod = CONVEX_HULL_SAVE_METHOD.PrefabMesh;
ResetDefaultSavePath();
SaveConvexHullAsAsset = true;
SaveConvexHullSuffix = "_ConvexHull_";
ConvexMeshReadWriteEnabled = true;
SaveConvexHullSubFolder = "";
#endregion
}
private static EasyColliderPreferences _Prefereneces;
public static EasyColliderPreferences Preferences
{
get
{
if (_Prefereneces == null)
{
// lazy load preferences when needed.
_Prefereneces = FindOrCreatePreferences();
}
return _Prefereneces;
}
}
private static EasyColliderPreferences FindOrCreatePreferences()
{
EasyColliderPreferences preferences;
string[] ecp = AssetDatabase.FindAssets("EasyColliderPreferences t:ScriptableObject");
string assetPath = "";
if (ecp.Length > 0)
{
assetPath = AssetDatabase.GUIDToAssetPath(ecp[0]);
if (ecp.Length > 1)
{
Debug.LogWarning("Easy Collider Editor has found multiple preferences files. Using the one located at " + assetPath);
}
preferences = AssetDatabase.LoadAssetAtPath(assetPath, typeof(EasyColliderPreferences)) as EasyColliderPreferences;
}
else
{
ecp = AssetDatabase.FindAssets("EasyColliderWindow t:script");
if (ecp.Length > 0)
{
assetPath = AssetDatabase.GUIDToAssetPath(ecp[0]);
if (ecp.Length > 1)
{
Debug.LogWarning("Easy Collider Editor has found multiple preferences files. Using the one located at " + assetPath);
}
}
// preferences = AssetDatabase.LoadAssetAtPath(assetPath, typeof(EasyColliderPreferences)) as EasyColliderPreferences;
// Create a new preferences file.
string prefPath = assetPath.Remove(assetPath.Length - 21) + "EasyColliderPreferences.asset";
preferences = CreateInstance<EasyColliderPreferences>();
preferences.SetDefaultValues();
AssetDatabase.CreateAsset(preferences, prefPath);
AssetDatabase.SaveAssets();
Debug.LogWarning("Easy Collider Editor did not find a preferences file, new preferences file created at " + prefPath);
}
return preferences;
}
static string defaultFolderName = "Convex Hulls";
/// <summary>
/// Resets the default save path to the location of the preferences scriptable object.
/// </summary>
public bool ResetDefaultSavePath()
{
// path to this preferences object.
SaveConvexHullPath = AssetDatabase.GetAssetPath(MonoScript.FromScriptableObject(this));
SaveConvexHullPath = SaveConvexHullPath.Remove(SaveConvexHullPath.LastIndexOf("/")) + "/";
string rootPath = SaveConvexHullPath.Remove(SaveConvexHullPath.LastIndexOf("/Scripts/"), 9);
// if the preferences is in soemthing other than Assets (like packages, create a new folder at the root to hold convex hulls)
if (!SaveConvexHullPath.StartsWith("Assets"))
{
if (!AssetDatabase.IsValidFolder("Assets/Convex Hulls"))
{
AssetDatabase.CreateFolder("Assets", "Convex Hulls");
AssetDatabase.Refresh();
Debug.LogWarning("A folder has been created at: Assets/Convex Hulls to save convex mesh collider assets because Easy Collider exists in the packages folder. Folder to save assets in can be changed in Easy Collider Editor's preferences foldout.");
}
SaveConvexHullPath = "Assets/Convex Hulls/";
return true;
}
// remove invalid characters.
SaveConvexHullPath = string.Join("", SaveConvexHullPath.Split(Path.GetInvalidPathChars()));
// try creating and saving a Convex Hull specific folder if it doesn't exist.
if (!AssetDatabase.IsValidFolder(rootPath + "/" + defaultFolderName))
{
AssetDatabase.CreateFolder(rootPath, defaultFolderName);
AssetDatabase.Refresh();
if (AssetDatabase.IsValidFolder(rootPath + "/" + defaultFolderName))
{
SaveConvexHullPath = rootPath + "/" + defaultFolderName + "/";
return true;
}
}
else
{
SaveConvexHullPath = rootPath + "/" + defaultFolderName + "/";
}
return false;
}
public int GetCreationValuesHashCode()
{
return 0;
}
}
}
#endif
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: fb5e4193615d8464a82ea935f90494a0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 67880
packageName: Easy Collider Editor
packageVersion: 6.18.1
assetPath: Assets/EasyColliderEditor/Scripts/EasyColliderPreferences.cs
uploadId: 749371
@@ -0,0 +1,717 @@
#if (UNITY_EDITOR)
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
namespace ECE
{
/// <summary>
/// Scriptable object to preview colliders that would be created from the given points
/// </summary>
[System.Serializable]
public class EasyColliderPreviewer : ScriptableObject
{
/// <summary>
/// Current calculation method of the collider type we are using as an int
/// </summary>
public int CurrentMethod = 0;
/// <summary>
/// Current attach to transform used in the calculation
/// </summary>
public Transform CurrentAttachTo;
/// <summary>
/// Current vertex count for the last calculation we did for a preview
/// </summary>
public int CurrentVertexCount = 0;
/// <summary>
/// Current count of the nubmer of colliders selected for the last preview calculation.
/// </summary>
public int CurrentColliderCount = 0;
public float CurrentVertexNormalOffset = 0;
public float CurrentVertexNormalInset = 0;
public NORMAL_OFFSET CurrentNormalOffset;
/// <summary>
/// Color to draw the preview lines with
/// </summary>
public Color DrawColor = Color.cyan;
private EasyColliderCreator _ECC;
/// <summary>
/// Creator that calculates the colliders we use to preview.
/// </summary>
/// <value></value>
public EasyColliderCreator ECC
{
get
{
if (_ECC == null)
{
_ECC = new EasyColliderCreator();
}
return _ECC;
}
set { _ECC = value; }
}
/// <summary>
/// Shader used to draw mesh colliders.
/// </summary>
private Shader MeshColliderShader;
/// <summary>
/// All the data from the current preview calculation
/// </summary>
public EasyColliderData PreviewData;
public List<EasyColliderData> RotateAndDuplicateData = new List<EasyColliderData>();
public bool HasValidRotateAndDuplicateData()
{
if (RotateAndDuplicateData == null || RotateAndDuplicateData.Count == 0) return false;
foreach (EasyColliderData d in RotateAndDuplicateData)
{
if (!d.IsValid)
{
return false;
}
}
return true;
}
//TODO: integrate calculation of auto skinned into normal update-preview stuff.
public List<EasyColliderData> AutoSkinnedData = new List<EasyColliderData>();
/// <summary>
/// Preview data hides that rotated colliders are different "collider types" so this keeps track of that for updating the preview.
/// </summary>
public CREATE_COLLIDER_TYPE ActualColliderType;
public ECE_WINDOW_TAB CurrentPreviewTab;
#region DrawPreviews
/// <summary>
/// Draws a preview from the current preview data.
/// </summary>
private void DrawPreview()
{
if (RotateAndDuplicateData != null && RotateAndDuplicateData.Count > 0)
{
// Debug.Log("Rotate and duplicate preview");
DrawList(RotateAndDuplicateData);
}
else if (AutoSkinnedData != null && AutoSkinnedData.Count > 0)
{
// Debug.Log("Auto skinned preivew");
DrawList(AutoSkinnedData);
}
else
{
// make sure we have data, and it's valid.
if (PreviewData != null && PreviewData.IsValid)
{
// Draw based on the preview type.
switch (PreviewData.ColliderType)
{
case CREATE_COLLIDER_TYPE.BOX:
case CREATE_COLLIDER_TYPE.ROTATED_BOX:
DrawPreviewBox(PreviewData as BoxColliderData, DrawColor);
break;
case CREATE_COLLIDER_TYPE.SPHERE:
DrawPreviewSphere(PreviewData as SphereColliderData, DrawColor);
break;
case CREATE_COLLIDER_TYPE.CAPSULE:
case CREATE_COLLIDER_TYPE.ROTATED_CAPSULE:
DrawPreviewCapsule(PreviewData as CapsuleColliderData, DrawColor);
break;
case CREATE_COLLIDER_TYPE.CONVEX_MESH:
case CREATE_COLLIDER_TYPE.CYLINDER:
DrawPreviewConvexMesh(PreviewData as MeshColliderData, DrawColor);
break;
}
}
}
}
public void DrawList(List<EasyColliderData> data)
{
foreach (EasyColliderData PreviewData in data)
{
if (!PreviewData.IsValid) { continue; }
// Draw based on the preview type.
switch (PreviewData.ColliderType)
{
case CREATE_COLLIDER_TYPE.BOX:
case CREATE_COLLIDER_TYPE.ROTATED_BOX:
DrawPreviewBox(PreviewData as BoxColliderData, DrawColor);
break;
case CREATE_COLLIDER_TYPE.SPHERE:
DrawPreviewSphere(PreviewData as SphereColliderData, DrawColor);
break;
case CREATE_COLLIDER_TYPE.CAPSULE:
case CREATE_COLLIDER_TYPE.ROTATED_CAPSULE:
DrawPreviewCapsule(PreviewData as CapsuleColliderData, DrawColor);
break;
case CREATE_COLLIDER_TYPE.CONVEX_MESH:
case CREATE_COLLIDER_TYPE.CYLINDER:
DrawPreviewConvexMesh(PreviewData as MeshColliderData, DrawColor);
break;
}
}
}
/// <summary>
/// Draws a mesh collider preview
/// </summary>
/// <param name="data">Data from quickhull calculation</param>
private void DrawPreviewConvexMesh(MeshColliderData data, Color color)
{
// try to find mesh shader
if (MeshColliderShader == null)
{
MeshColliderShader = Shader.Find("Custom/EasyColliderMeshColliderPreview");
}
// if we have the shader, draw it using the wireframe and the color
if (MeshColliderShader != null && data.ConvexMesh != null)
{
Material wireMat = new Material(MeshColliderShader);
wireMat.SetColor("_Color", color);
wireMat.SetPass(0);
GL.wireframe = true;
Graphics.DrawMeshNow(data.ConvexMesh, data.Matrix);
GL.wireframe = false;
Graphics.DrawMeshNow(data.ConvexMesh, data.Matrix);
}
}
/// <summary>
/// Draws a box collider
/// </summary>
/// <param name="data">Data from box calculation</param>
private void DrawPreviewBox(BoxColliderData data, Color color)
{
// half size and center
Vector3 hs = data.Size / 2;
Vector3 c = data.Center;
// transform each point of the cube to world space with the transformation matrix
Vector3[] points = new Vector3[8]{
data.Matrix.MultiplyPoint3x4(c + hs),
data.Matrix.MultiplyPoint3x4(c + new Vector3(hs.x, hs.y, -hs.z)),
data.Matrix.MultiplyPoint3x4(c + new Vector3(hs.x, -hs.y, hs.z)),
data.Matrix.MultiplyPoint3x4(c + new Vector3(hs.x, -hs.y, -hs.z)),
data.Matrix.MultiplyPoint3x4(c + new Vector3(-hs.x, hs.y, hs.z)),
data.Matrix.MultiplyPoint3x4(c + new Vector3(-hs.x, hs.y, -hs.z)),
data.Matrix.MultiplyPoint3x4(c + new Vector3(-hs.x, -hs.y, hs.z)),
data.Matrix.MultiplyPoint3x4(c - hs)
};
// draw the lines connecting corners of the cube.
Handles.color = color;
Handles.DrawLine(points[0], points[1]);
Handles.DrawLine(points[0], points[2]);
Handles.DrawLine(points[0], points[4]);
Handles.DrawLine(points[7], points[5]);
Handles.DrawLine(points[7], points[6]);
Handles.DrawLine(points[7], points[3]);
Handles.DrawLine(points[1], points[5]);
Handles.DrawLine(points[1], points[3]);
Handles.DrawLine(points[2], points[6]);
Handles.DrawLine(points[2], points[3]);
Handles.DrawLine(points[4], points[5]);
Handles.DrawLine(points[4], points[6]);
}
public void DrawCapsuleCollider(CapsuleColliderData data, Color color)
{
DrawPreviewCapsule(data, color);
}
private void DrawPreviewCapsule(CapsuleColliderData data, Color color)
{
Handles.color = color;
// calculate top and bottom center sphere locations.
float offset = data.Height / 2;
Vector3 top, bottom = top = data.Center;
float radius = data.Radius;
#if (UNITY_2017_2_OR_NEWER)
Vector3 scale = data.Matrix.lossyScale;
#else
Vector3 scale = CurrentAttachTo.transform.lossyScale;
#endif
switch (data.Direction)
{
case 0: //x axis
//adjust radius by the bigger scale.
radius *= scale.y > scale.z ? scale.y : scale.z;
// adjust the offset to top and bottom mid points for spheres based on radius / scale in that direction
offset -= radius / scale.x;
// offset top and bottom points.
top.x += offset;
bottom.x -= offset;
break;
case 1:
radius *= scale.x > scale.z ? scale.x : scale.z;
offset -= radius / scale.y;
top.y += offset;
bottom.y -= offset;
break;
case 2:
radius *= scale.x > scale.y ? scale.x : scale.y;
offset -= radius / scale.z;
top.z += offset;
bottom.z -= offset;
break;
}
// dont know why mathf.approx wasn't working here, but the others don't work in rare cases. (top==bottom in this case works)
// which fixes issue where a preview would not be drawn in some extremely weird rare case.
if (data.Height < data.Radius * 2 || Mathf.Approximately(data.Height, data.Radius * 2) || top == bottom)
{
// draw just the sphere if the radius and the height will make a sphere.
Vector3 worldCenter = data.Matrix.MultiplyPoint(data.Center);
Handles.DrawWireDisc(worldCenter, Vector3.forward, radius);
Handles.DrawWireDisc(worldCenter, Vector3.right, radius);
Handles.DrawWireDisc(worldCenter, Vector3.up, radius);
return;
}
Vector3 worldTop = data.Matrix.MultiplyPoint3x4(top);
Vector3 worldBottom = data.Matrix.MultiplyPoint3x4(bottom);
Vector3 up = worldTop - worldBottom;
Vector3 cross1 = Vector3.up;
// dont want to cross if in same direction, forward works in this case as the first cross
if (up.normalized == cross1 || up.normalized == -cross1)
{
cross1 = Vector3.forward;
}
Vector3 right = Vector3.Cross(up, -cross1).normalized;
Vector3 forward = Vector3.Cross(up, -right).normalized;
// full circles at top and bottom
Handles.DrawWireDisc(worldTop, up, radius);
Handles.DrawWireDisc(worldBottom, up, radius);
// half arcs at top and bottom
Handles.DrawWireArc(worldTop, forward, right, 180f, radius);
Handles.DrawWireArc(worldTop, -right, forward, 180f, radius);
Handles.DrawWireArc(worldBottom, -forward, right, 180f, radius);
Handles.DrawWireArc(worldBottom, right, forward, 180f, radius);
// connect bottom and top side points
Handles.DrawLine(worldTop + right * radius, worldBottom + right * radius);
Handles.DrawLine(worldTop - right * radius, worldBottom - right * radius);
Handles.DrawLine(worldTop + forward * radius, worldBottom + forward * radius);
Handles.DrawLine(worldTop - forward * radius, worldBottom - forward * radius);
}
public void DrawSphereCollider(SphereColliderData data, Color color)
{
DrawPreviewSphere(data, color);
}
/// <summary>
/// Draws a sphere collider
/// </summary>
/// <param name="data">Data from sphere calculation</param>
private void DrawPreviewSphere(SphereColliderData data, Color color)
{
Handles.color = color;
Vector3 worldCenter = data.Matrix.MultiplyPoint3x4(data.Center);
// Draw all normal axis' rings at the world center location for both perspective and isometric/orthographic
float radius = data.Radius;
#if (UNITY_2017_2_OR_NEWER)
Vector3 scale = data.Matrix.lossyScale;
#else
Vector3 scale = CurrentAttachTo.transform.lossyScale;
#endif
float largestScale = Mathf.Max(Mathf.Max(scale.x, scale.y), scale.z);
radius *= largestScale;
Handles.DrawWireDisc(worldCenter, Vector3.forward, radius);
Handles.DrawWireDisc(worldCenter, Vector3.right, radius);
Handles.DrawWireDisc(worldCenter, Vector3.up, radius);
// orthographic camera
if (Camera.current != null)
{
if (Camera.current.orthographic)
{
// simple, use cameras forward in orthographic
Handles.DrawWireDisc(worldCenter, Camera.current.transform.forward, radius);
}
else
{
// draw a circle facing the camera covering all the radius in prespective mode
Vector3 normal = worldCenter - Handles.inverseMatrix.MultiplyPoint(Camera.current.transform.position);
float sqrMagnitude = normal.sqrMagnitude;
float r2 = radius * radius;
float r4m = r2 * r2 / sqrMagnitude;
float newRadius = Mathf.Sqrt(r2 - r4m);
Handles.DrawWireDisc(worldCenter - r2 * normal / sqrMagnitude, normal, newRadius);
}
}
}
#endregion
public void ClearPreview()
{
// PreviewData = new EasyColliderData();
PreviewData = null;
RotateAndDuplicateData = null;
AutoSkinnedData = null;
}
/// <summary>
/// Gets the method for the current preview collider type
/// </summary>
/// <param name="colliderType">type of collider we are previewing</param>
/// <returns>enum of method selected for collider type as an int</returns>
private int GetMethodForColliderPreviewType(EasyColliderPreferences preferences)
{
if (preferences.PreviewColliderType == CREATE_COLLIDER_TYPE.CAPSULE || preferences.PreviewColliderType == CREATE_COLLIDER_TYPE.ROTATED_CAPSULE)
{
return (int)preferences.CapsuleColliderMethod;
}
else if (preferences.PreviewColliderType == CREATE_COLLIDER_TYPE.SPHERE)
{
return (int)preferences.SphereColliderMethod;
}
else if (preferences.PreviewColliderType == CREATE_COLLIDER_TYPE.CONVEX_MESH)
{
return (int)preferences.MeshColliderMethod;
}
else if (preferences.PreviewColliderType == CREATE_COLLIDER_TYPE.CYLINDER)
{
return (int)preferences.CylinderNumberOfSides + (int)preferences.CylinderOrientation + ((int)preferences.CylinderRotationOffset * 1000);
}
else
{
return 0;
}
}
#region CalculatePreviews
/// <summary>
/// Calculates the preview data to be used to display.
/// </summary>
/// <param name="preferences">current preferences</param>
/// <param name="ece">current editor</param>
private void CalculatePreviewCollider(EasyColliderPreferences preferences, EasyColliderEditor ece)
{
// private void CalculatePreviewCollider(CREATE_COLLIDER_TYPE type, List<Vector3> worldVertices, List<Vector3> normals, GameObject attachTo, int method)
// CalculatePreviewCollider(preferences.PreviewColliderType, editor.GetWorldVertices(), editor.GetNormals(), editor.AttachToObject, GetMethodForColliderPreviewType(preferences));
List<Vector3> worldVertices = ece.GetWorldVertices(true);
switch (ActualColliderType)
{
case CREATE_COLLIDER_TYPE.BOX:
case CREATE_COLLIDER_TYPE.ROTATED_BOX:
PreviewData = ECC.CalculateBox(worldVertices, CurrentAttachTo.transform, ActualColliderType == CREATE_COLLIDER_TYPE.ROTATED_BOX);
break;
case CREATE_COLLIDER_TYPE.SPHERE:
PreviewData = CalculatePreviewSphere(worldVertices, CurrentAttachTo.transform, preferences.SphereColliderMethod);
break;
case CREATE_COLLIDER_TYPE.ROTATED_CAPSULE:
case CREATE_COLLIDER_TYPE.CAPSULE:
PreviewData = CalculatePreviewCapsule(worldVertices, CurrentAttachTo.transform, preferences.CapsuleColliderMethod, ActualColliderType == CREATE_COLLIDER_TYPE.ROTATED_CAPSULE);
break;
case CREATE_COLLIDER_TYPE.CONVEX_MESH:
PreviewData = CalculatePreviewMesh(worldVertices, ece.GetNormals(), CurrentAttachTo.transform, preferences.MeshColliderMethod);
break;
case CREATE_COLLIDER_TYPE.CYLINDER:
PreviewData = CalculatePreviewCylinder(worldVertices, CurrentAttachTo.transform);
break;
}
}
/// <summary>
/// Calculates the merge colliders preview data
/// </summary>
/// <param name="preferences">current preferences</param>
/// <param name="ece">current editor</param>
private void CalculatePreviewMerge(EasyColliderPreferences preferences, EasyColliderEditor ece)
{
// private void CalculatePreviewMerge(CREATE_COLLIDER_TYPE mergeTo, List<Collider> selectedColliders, GameObject attachTo, int method)
// CalculatePreviewMerge(preferences.PreviewColliderType, editor.SelectedColliders, editor.AttachToObject, GetMethodForColliderPreviewType(preferences));
if (CurrentColliderCount > 0)
{
EasyColliderCreator ecc = new EasyColliderCreator();
PreviewData = ecc.MergeCollidersPreview(ece.SelectedColliders, preferences.PreviewColliderType, CurrentAttachTo);
}
else
{
PreviewData = new EasyColliderData();
}
}
/// <summary>
/// Calculates the rotate and duplicate preview data.
/// </summary>
/// <param name="preferences">current preferences</param>
/// <param name="ece">current editor</param>
private void CalculatePreviewRotateAndDuplicate(EasyColliderPreferences preferences, EasyColliderEditor ece)
{
if (ece.AttachToObject == null || ece.SelectedGameObject == null || preferences.rotatedDupeSettings.pivot == null) return;
EasyColliderCreator ecc = new EasyColliderCreator();
RotateAndDuplicateData = ecc.CalculateRotateAndDuplicate(preferences, ece);
}
/// <summary>
/// Calculates a preview capsule
/// </summary>
/// <param name="worldVertices">world vertices used to calculate the collider</param>
/// <param name="attachTo">gameobject the collider will be attached to</param>
/// <param name="method">calculation method used to calculate the collider type as an int</param>
/// <param name="isRotated">will the collider be a rotated collider?</param>
/// <returns>Calculated capsule collider data</returns>
private EasyColliderData CalculatePreviewCapsule(List<Vector3> worldVertices, Transform attachTo, CAPSULE_COLLIDER_METHOD method, bool isRotated)
{
switch (method)
{
case CAPSULE_COLLIDER_METHOD.BestFit:
return ECC.CalculateCapsuleBestFit(worldVertices, attachTo, isRotated);
default:
return ECC.CalculateCapsuleMinMax(worldVertices, attachTo, method, isRotated);
}
}
/// <summary>
/// Calculates a preview cylinder
/// </summary>
/// <param name="worldVertices">world vertices used to calculate the collider</param>
/// <param name="attachTo">transform the collider will be attached to</param>
/// <returns>Calculated cylinder shaped mesh collider data</returns>
private MeshColliderData CalculatePreviewCylinder(List<Vector3> worldVertices, Transform attachTo)
{
EasyColliderCreator ecc = new EasyColliderCreator();
MeshColliderData data = ecc.CalculateCylinderCollider(worldVertices, attachTo);
return data;
}
/// <summary>
/// Calculates the preview data for a convex mesh collider. (uses quickhull calculation for both messy and quickhull method)
/// </summary>
/// <param name="worldVertices">World-Space vertices that are selected</param>
/// <param name="attachTo">Current AttachTo object</param>
/// <param name="method">Mesh Collider generation method</param>
/// <returns>EasyCollider data with a mesh value set.</returns>
private MeshColliderData CalculatePreviewMesh(List<Vector3> worldVertices, List<Vector3> normals, Transform attachTo, MESH_COLLIDER_METHOD method)
{
// Messy-hull not suited for preview as the intermediate mesh is essentially useless
// and the actual important result is from the internal calculation by the mesh collider, so it would have to be added.
// but since internall it uses a similar hull method, the result should be similar as well.
// automatically uses quickhull for messy-hull version as well
// if (method == MESH_COLLIDER_METHOD.QuickHullExtrude)
// {
// return EasyColliderQuickHull.CalculateHullData(worldVertices, normals, attachTo, preferences.VertexNormalOffset);
// }
return EasyColliderQuickHull.CalculateHullData(worldVertices, attachTo);
}
/// <summary>
/// Calculates a preview sphere
/// </summary>
/// <param name="worldVertices">world vertices used to calculate the collider</param>
/// <param name="attachTo">gameobject the collider will be attached to</param>
/// <param name="method">calculation method used to calculate the collider type as an int</param>
/// <returns>Calculated sphere collider data</returns>
private EasyColliderData CalculatePreviewSphere(List<Vector3> worldVertices, Transform attachTo, SPHERE_COLLIDER_METHOD method)
{
switch (method)
{
case SPHERE_COLLIDER_METHOD.Distance:
return ECC.CalculateSphereDistance(worldVertices, attachTo);
case SPHERE_COLLIDER_METHOD.BestFit:
return ECC.CalculateSphereBestFit(worldVertices, attachTo);
default:
return ECC.CalculateSphereMinMax(worldVertices, attachTo);
}
}
#endregion
/// <summary>
/// Checks to see if the collider needs to be calculated, so the preview is updated.
/// </summary>
/// <param name="editor"></param>
/// <param name="colliderType"></param>
/// <param name="method"></param>
/// <returns>true if the preview needs to be updated.</returns>
private bool NeedsUpdate(EasyColliderPreferences preferences, EasyColliderEditor editor)
{
// private bool NeedsUpdate(EasyColliderEditor editor, CREATE_COLLIDER_TYPE colliderType, int method)
//(NeedsUpdate(editor, preferences.PreviewColliderType, GetMethodForColliderPreviewType(preferences)) || forceUpdate)
if (preferences.CurrentWindowTab == ECE_WINDOW_TAB.Creation)
{
if (CurrentVertexCount != editor.SelectedVertices.Count
|| (PreviewData == null && RotateAndDuplicateData == null && preferences.rotatedDupeSettings.enabled)
|| (PreviewData == null && preferences.rotatedDupeSettings.enabled == false)
|| (PreviewData != null && PreviewData.ColliderType != preferences.PreviewColliderType)
|| CurrentMethod != GetMethodForColliderPreviewType(preferences)
|| CurrentAttachTo != editor.AttachToObject.transform
|| ActualColliderType != preferences.PreviewColliderType
|| editor.HasTransformMoved()
|| CurrentVertexNormalOffset != preferences.VertexNormalOffset
|| CurrentVertexNormalInset != preferences.VertexNormalInset
|| CurrentNormalOffset != preferences.VertexNormalOffsetType
)
{
return true;
}
}
else if (preferences.CurrentWindowTab == ECE_WINDOW_TAB.Editing)
{
if (CurrentColliderCount != editor.SelectedColliders.Count
|| PreviewData == null
|| CurrentMethod != GetMethodForColliderPreviewType(preferences)
|| CurrentAttachTo != editor.AttachToObject.transform
|| editor.HasTransformMoved()
|| ActualColliderType != preferences.PreviewColliderType)
{
return true;
}
return false;
}
return false;
}
/// <summary>
/// Updates the current preview if needed.
/// </summary>
/// <param name="editor"></param>
/// <param name="preferences"></param>
public void UpdatePreview(EasyColliderEditor editor, EasyColliderPreferences preferences, bool forceUpdate = false)
{
if (editor != null && preferences != null && editor.SelectedGameObject != null && editor.AttachToObject != null)
{
DrawColor = preferences.PreviewDrawColor;
if (NeedsUpdate(preferences, editor) || forceUpdate)
{
ActualColliderType = preferences.PreviewColliderType;
CurrentAttachTo = editor.AttachToObject.transform;
CurrentColliderCount = editor.SelectedColliders.Count;
CurrentMethod = GetMethodForColliderPreviewType(preferences);
CurrentPreviewTab = preferences.CurrentWindowTab;
CurrentVertexCount = editor.SelectedVertices.Count;
CurrentVertexNormalOffset = preferences.VertexNormalOffset;
CurrentVertexNormalInset = preferences.VertexNormalInset;
CurrentNormalOffset = preferences.VertexNormalOffsetType;
if (PreviewData == null)
{
PreviewData = new EasyColliderData();
}
if (preferences.CurrentWindowTab == ECE_WINDOW_TAB.Creation)
{
if (preferences.rotatedDupeSettings.enabled == true)
{
RotateAndDuplicateData = new List<EasyColliderData>();
CurrentAttachTo = preferences.rotatedDupeSettings.pivot.transform;
CalculatePreviewRotateAndDuplicate(preferences, editor);
}
else
{
CalculatePreviewCollider(preferences, editor);
}
PreviewData.ColliderType = ActualColliderType;
}
else if (preferences.CurrentWindowTab == ECE_WINDOW_TAB.Editing)
{
CalculatePreviewMerge(preferences, editor);
}
}
DrawPreview();
}
}
#region VHACDPREVIEW
/// <summary>
/// Array of triangles for use in VHACDResultPreview
/// </summary>
private int[] triangles;
/// <summary>
/// Array of vertices for use in VHACDResultPreview
/// </summary>
private Vector3[] vertices;
/// <summary>
/// List of randomized colors for use in VHACDResultPreview
/// </summary>
private List<Color> colors = new List<Color>();
public void DrawVHACDConversionPreview(List<EasyColliderData> data, VHACD_CONVERSION convertTo)
{
foreach (EasyColliderData d in data)
{
if (d == null) continue;
if (convertTo == VHACD_CONVERSION.Boxes)
{
BoxColliderData bcd = d as BoxColliderData;
if (bcd == null) continue;
DrawPreviewBox(bcd, DrawColor);
}
else if (convertTo == VHACD_CONVERSION.Capsules)
{
CapsuleColliderData ccd = d as CapsuleColliderData;
if (ccd == null) continue;
DrawPreviewCapsule(ccd, DrawColor);
}
else if (convertTo == VHACD_CONVERSION.Spheres)
{
SphereColliderData scd = d as SphereColliderData;
if (scd == null) continue;
DrawPreviewSphere(scd, DrawColor);
}
}
}
/// <summary>
/// Draws each mesh in the dictionary with a black wireframe, and a random color semi-transparent mesh.
/// </summary>
/// <param name="previewResult">Dictionary of transforms and meshes from the result of VHACD</param>
public void DrawVHACDResultPreview(Dictionary<Transform, Mesh[]> previewResult)
{
Shader s = Shader.Find("Custom/EasyColliderMeshColliderPreview");
if (s != null)
{
Material wireMat = new Material(s);
wireMat.SetColor("_Color", Color.black);
Material flatMat = new Material(s);
foreach (KeyValuePair<Transform, Mesh[]> kvp in previewResult)
{
if (kvp.Key == null) continue; // transform can be null if it's deleted.
if (colors.Count < kvp.Value.Length)
{
int addColors = kvp.Value.Length - colors.Count;
for (int i = 0; i < addColors; i++)
{
colors.Add(new Color(Random.Range(0f, 1f), Random.Range(0f, 1f), Random.Range(0f, 1f)));
}
}
for (int i = 0; i < kvp.Value.Length; i++)
{
flatMat.SetColor("_Color", colors[i]);
flatMat.SetPass(1);
Graphics.DrawMeshNow(kvp.Value[i], kvp.Key.localToWorldMatrix);
wireMat.SetPass(1);
GL.wireframe = true;
Graphics.DrawMeshNow(kvp.Value[i], kvp.Key.localToWorldMatrix);
GL.wireframe = false;
}
}
}
else
{
Debug.LogWarning("EasyColliderEditor: Unable to find shader for preview.");
}
}
#endregion
}
}
#endif
@@ -0,0 +1,20 @@
fileFormatVersion: 2
guid: 0975e5f3c5571d940891fd8dc17e7587
timeCreated: 1592761340
licenseType: Store
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 67880
packageName: Easy Collider Editor
packageVersion: 6.18.1
assetPath: Assets/EasyColliderEditor/Scripts/EasyColliderPreviewer.cs
uploadId: 749371
@@ -0,0 +1,100 @@
using UnityEngine;
namespace ECE
{
/// <summary>
/// Properties to use when creating a collider.
/// </summary>
public struct EasyColliderProperties
{
/// <summary>
/// Marks the collider's isTrigger property
/// </summary>
public bool IsTrigger;
/// <summary>
/// Layer of gameobject when creating a rotated collider.
/// </summary>
public int Layer;
#if (UNITY_6000_0_OR_NEWER)
/// <summary>
/// Physic material to set on collider.
/// </summary>
public PhysicsMaterial PhysicMaterial;
#else
/// <summary>
/// Physic material to set on collider.
/// </summary>
public PhysicMaterial PhysicMaterial;
public void SetPhysicMat(PhysicMaterial physmat)
{
PhysicMaterial = physmat;
}
#endif
#if (UNITY_2022_2_OR_NEWER)
/// <summary>
/// whether or not the collidere generates contacts for physics.contact event.
/// </summary>
public bool ProvidesContacts;
/// <summary>
/// layer overrides - layer override priority property on a collider.
/// </summary>
public int LayerOverridePriority;
/// <summary>
/// layer overrides exclude layer mask property on colliders.
/// </summary>
public LayerMask ExcludeLayers;
/// <summary>
/// layer overrides include layer mask property on colliders.
/// </summary>
public LayerMask IncludeLayers;
#endif
/// <summary>
/// Orientation of created collider.
/// </summary>
public COLLIDER_ORIENTATION Orientation;
/// <summary>
/// Gameobject collider gets added to.
/// </summary>
public GameObject AttachTo;
/// <summary>
/// Properties with which to create a collider
/// </summary>
/// <param name="isTrigger">Should the collider's isTrigger property be true?</param>
/// <param name="layer">Layer of gameobject when creating a rotated collider</param>
/// <param name="physicMaterial">Physic Material to apply to a collider</param>
/// <param name="attachTo">GameObject to attach the collider to</param>
/// <param name="orientation">Orientation of the collider for generation</param>
public EasyColliderProperties(bool isTrigger, int layer,
#if (UNITY_6000_0_OR_NEWER)
PhysicsMaterial physicMaterial,
#else
PhysicMaterial physicMaterial,
#endif
GameObject attachTo, COLLIDER_ORIENTATION orientation = COLLIDER_ORIENTATION.NORMAL)
{
IsTrigger = isTrigger;
Layer = layer;
PhysicMaterial = physicMaterial;
AttachTo = attachTo;
Orientation = orientation;
#if (UNITY_2022_2_OR_NEWER)
ProvidesContacts = false;
LayerOverridePriority = 0;
IncludeLayers = 0;
ExcludeLayers = 0;
#endif
}
}
}
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 6beb8fffd8449374b81cf9857e315469
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 67880
packageName: Easy Collider Editor
packageVersion: 6.18.1
assetPath: Assets/EasyColliderEditor/Scripts/EasyColliderProperties.cs
uploadId: 749371
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,20 @@
fileFormatVersion: 2
guid: ed797196cc351a34db4a5f88338cc1fe
timeCreated: 1600696552
licenseType: Store
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 67880
packageName: Easy Collider Editor
packageVersion: 6.18.1
assetPath: Assets/EasyColliderEditor/Scripts/EasyColliderQuickHull.cs
uploadId: 749371
@@ -0,0 +1,28 @@
using UnityEngine;
namespace ECE
{
[System.Serializable]
public class EasyColliderRotateDuplicate
{
public enum ROTATE_AXIS
{
X,
Y,
Z,
}
public bool enabled;
public ROTATE_AXIS axis;
public int NumberOfDuplications = 4;
public float StartRotation = 0.0f;
public float EndRotation = 360f;
public GameObject pivot;
public GameObject attachTo;
}
}
@@ -0,0 +1,20 @@
fileFormatVersion: 2
guid: 5e6a373c203fb6b459f89497990e1b24
timeCreated: 1618839991
licenseType: Store
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 67880
packageName: Easy Collider Editor
packageVersion: 6.18.1
assetPath: Assets/EasyColliderEditor/Scripts/EasyColliderRotateDuplicate.cs
uploadId: 749371
@@ -0,0 +1,351 @@
#if(UNITY_EDITOR)
using UnityEngine;
using UnityEditor;
using System.IO;
using UnityEditor.SceneManagement;
namespace ECE
{
public static class EasyColliderSaving
{
static UnityEngine.Object TryFindPrefabObject(GameObject go)
{
UnityEngine.Object foundObject = null;
#if UNITY_2018_2_OR_NEWER
// 2018_2+
foundObject = PrefabUtility.GetCorrespondingObjectFromSource(go);
#if (UNITY_2021_2_OR_NEWER)
// can get prefab stage in 2021+
if (foundObject == null)
{
PrefabStage stage = PrefabStageUtility.GetCurrentPrefabStage();
if (stage != null)
{
GameObject stagedObject = stage.openedFromInstanceObject;
foundObject = PrefabUtility.GetCorrespondingObjectFromSource(stagedObject);
}
}
#endif
#else
foundObject = PrefabUtility.GetPrefabParent(go);
if (foundObject == null)
{
foundObject = PrefabUtility.FindPrefabRoot(go);
}
#endif
return foundObject;
}
static UnityEngine.Object TryFindMeshOrSkinnedMeshObject(GameObject go)
{
UnityEngine.Object foundObject = null;
MeshFilter mf = go.GetComponent<MeshFilter>();
if (mf != null)
{
foundObject = mf.sharedMesh;
}
else
{
SkinnedMeshRenderer smr = go.GetComponent<SkinnedMeshRenderer>();
if (smr != null)
{
foundObject = smr.sharedMesh;
}
}
return foundObject;
}
/// <summary>
/// Static preferences asset that is currently loaded.
/// </summary>
/// <value></value>
static EasyColliderPreferences ECEPreferences { get { return EasyColliderPreferences.Preferences; } }
/// <summary>
/// Gets a valid path to save a convex hull at to feed into save convex hull meshes function.
/// </summary>
/// <param name="go">selected gameobject</param>
/// <param name="ECEPreferences">preferences object</param>
/// <returns>full save path (ie C:/UnityProjects/ProjectName/Assets/Folder/baseObject)</returns>
public static string GetValidConvexHullPath(GameObject go)
{
// use default specified path
// remove invalid characters from file name, just in case (user reported error, thanks!)
string goName = string.Join("_", go.name.Split(Path.GetInvalidFileNameChars()));
// start with the default path specified in preferences.
string path = ECEPreferences.SaveConvexHullPath;
// get path to gameobject
if (ECEPreferences.ConvexHullSaveMethod != CONVEX_HULL_SAVE_METHOD.Folder)
{
// bandaid for scaled temporary skinned mesh:
// as the scaled mesh filter is added during setup with the name Scaled Mesh Filter (Temporary)
if (go.name.Contains("Scaled Mesh Filter"))
{
go = go.transform.parent.gameObject; // set the gameobject to the temp's parent (as that will be a part of the prefab if it is one and thus should work.)
}
UnityEngine.Object foundObject = null;
if (ECEPreferences.ConvexHullSaveMethod == CONVEX_HULL_SAVE_METHOD.Prefab)
{
foundObject = TryFindPrefabObject(go);
}
else if (ECEPreferences.ConvexHullSaveMethod == CONVEX_HULL_SAVE_METHOD.Mesh)
{
foundObject = TryFindMeshOrSkinnedMeshObject(go);
}
else if (ECEPreferences.ConvexHullSaveMethod == CONVEX_HULL_SAVE_METHOD.PrefabMesh)
{
foundObject = TryFindPrefabObject(go);
if (foundObject == null)
{
foundObject = TryFindMeshOrSkinnedMeshObject(go);
}
}
else if (ECEPreferences.ConvexHullSaveMethod == CONVEX_HULL_SAVE_METHOD.MeshPrefab)
{
foundObject = TryFindMeshOrSkinnedMeshObject(go);
if (foundObject == null)
{
foundObject = TryFindPrefabObject(go);
}
}
string altPath = AssetDatabase.GetAssetPath(foundObject);
// but only use the path it if it exists.
if (altPath != null && altPath != "" && foundObject != null)
{
int index = altPath.LastIndexOf("/");
if (index >= 0)
{
string foundObjectName = string.Join("_", foundObject.name.Split(Path.GetInvalidFileNameChars()));
// removes object name.
path = altPath.Remove(index + 1);
// if they want a subfolder, create it if needed and use it.
if (!string.IsNullOrEmpty(ECEPreferences.SaveConvexHullSubFolder))
{
if (!AssetDatabase.IsValidFolder(path + ECEPreferences.SaveConvexHullSubFolder))
{
// path still has trailing '/' which needs to be removed for create folder.
AssetDatabase.CreateFolder(path.Remove(path.Length - 1), ECEPreferences.SaveConvexHullSubFolder);
}
path += ECEPreferences.SaveConvexHullSubFolder + "/";
}
}
}
}
string originalPath = path;
string pathFallback = path;
//remove any invalid path characters.
path = string.Join("", path.Split(Path.GetInvalidPathChars()));
// prefab/mesh searched for a folder to save in and failed to find a valid path, default to the save convex hull path specified in preferences.
if (!AssetDatabase.IsValidFolder(path) && originalPath != ECEPreferences.SaveConvexHullPath)
{
pathFallback = ECEPreferences.SaveConvexHullPath;
path = pathFallback;
path = string.Join("", path.Split(Path.GetInvalidPathChars()));
// could not find a valid mesh/prefab location, but the fallback save convex hull folder DOES work.
if (AssetDatabase.IsValidFolder(path))
{
Debug.LogWarning("Easy Collider Editor: Could not find a valid location to save the collider. Saving in the folder specified in preferences: " + pathFallback + ".\n\nPath originally found was:" + originalPath);
}
}
// saving in a non-asset path and does not have allow saving convex hulls in packages enabled
if ((!path.StartsWith("Assets") && !ECEPreferences.AllowSavingConvexHullsInPackages))
{
path = ECEPreferences.SaveConvexHullPath;
pathFallback = path;
}
// folder path is saved with / at the end, so remove if we have to.
if (path[path.Length - 1] == '/')
{
path = path.Remove(path.Length - 1);
}
// this will automatically be true if we're using a folder (and it failed) OR the fallback on prefab/mesh fails (which also uses SaveConvexHullPath)
if ((!AssetDatabase.IsValidFolder(path) && pathFallback == ECEPreferences.SaveConvexHullPath))
{
// path to ece preferences (in scripts typically)
path = AssetDatabase.GetAssetPath(MonoScript.FromScriptableObject(ECEPreferences));
// because the above is the full path to the file including the files name.
path = path.Remove(path.LastIndexOf("/"));
path = path.Replace("/Scripts", "");
path = string.Join("", path.Split(Path.GetInvalidPathChars()));
// asset path for preferences file is invalid, not in assets folder a
if (path.StartsWith("Assets") && !ECEPreferences.AllowSavingConvexHullsInPackages)
{
if (!AssetDatabase.IsValidFolder(path + "/Convex Hulls"))
{
AssetDatabase.CreateFolder(path, "Convex Hulls");
AssetDatabase.Refresh();
}
path = path + "/Convex Hulls";
if (originalPath == ECEPreferences.SaveConvexHullPath)
{
// original path was saving to a folder.
ECEPreferences.SaveConvexHullPath = path + "/";
Debug.LogWarning("Easy Collider Editor: Convex Hull save path specified in Easy Collider Editor's preferences could not be found, or it is an invalid asset folder. Saving in: " + path + " as a fallback and updating preferences. If the folder has been moved or deleted, update to a different folder in the edit preferences foldout.\n\n Original path: " + originalPath);
}
// so that if we already have a valid
else if (!ECEPreferences.SaveConvexHullPath.StartsWith("Assets"))
{
// used an alternative mesh/prefab/prefabmesh save method.
ECEPreferences.SaveConvexHullPath = path + "/";
Debug.LogWarning("Easy Collider Editor: Could not find a valid location to save the collider and the save path specified in preferences could not be found, or it is an invalid asset folder. Saving in: " + path + " and updated preferences to this folder. If the folder has been moved or deleted, update to a different folder in the edit preferences foldout.\n\n Original path: " + originalPath);
}
}
else // in a packages folder probably without AllowSavingConvexHullsInPackages enabled.
{
// final fallback.
pathFallback = "Assets/Convex Hulls";
path = pathFallback;
if (originalPath == ECEPreferences.SaveConvexHullPath)
{
// change default path to a valid path.
ECEPreferences.SaveConvexHullPath = pathFallback + "/";
#if (UNITY_2020_3_OR_NEWER)
AssetDatabase.SaveAssetIfDirty(ECEPreferences);
#endif
}
if (!AssetDatabase.IsValidFolder(path))
{
AssetDatabase.CreateFolder("Assets", "Convex Hulls");
AssetDatabase.Refresh();
if (originalPath == ECEPreferences.SaveConvexHullPath)
{
// original path was saving to a folder.
Debug.LogWarning("Easy Collider Editor: Convex Hull save path specified in Easy Collider Editor's preferences could not be found, or it is an invalid asset folder. A folder to save collider assets was created at: " + path + " and automatically set in preferences. A different folder in Easy Collider Editor's preferences foldout can be specified if desired.\n\n Original path: " + originalPath);
}
else
{
// used an alternative mesh/prefab/prefabmesh save method.
Debug.LogWarning("Easy Collider Editor: Could not find a valid location to save the collider and the save path specified in preferences could not be found, or it is an invalid asset folder. A new folder has been created at " + path + " to save mesh collider assets and automatically set in preferences. A different folder in Easy Collider Editor's preferences foldout can be specified if desired. \n\n Original path: " + originalPath);
}
}
}
}
string fullPath = path + "/" + goName;
return fullPath;
}
/// <summary>
/// goes thorugh the path and finds the first non-existing path that can be used to save.
/// </summary>
/// <param name="path">Full path up to save location: ie C:/UnityProjects/ProjectName/Assets/Folder/baseObject</param>
/// <param name="suffix">Suffix to add to save files ie _Suffix_</param>
/// <returns>first valid path for AssetDatabase.CreateAsset ie baseObject_Suffix_0</returns>
private static string GetFirstValidAssetPath(string path, string suffix)
{
string validPath = path;
if (File.Exists(validPath + suffix + "0.asset"))
{
int i = 1;
while (File.Exists(validPath + suffix + i + ".asset"))
{
i += 1;
}
validPath += suffix + i + ".asset";
}
else
{
validPath += suffix + "0.asset";
}
// replace application's data path (Unity Editor: <path to project folder>/Assets)
// "Assets" earlier in the path should no longer cause issues.
validPath = validPath.Replace(Application.dataPath, "Assets");
return validPath;
}
/// <summary>
/// Creates and saves a mesh asset in the asset database with appropriate path and suffix.
/// </summary>
/// <param name="mesh">mesh</param>
/// <param name="attachTo">gameobject the mesh will be attached to, used to find asset path.</param>
public static void CreateAndSaveMeshAsset(Mesh mesh, GameObject attachTo)
{
if (mesh != null && !DoesMeshAssetExists(mesh))
{
string savePath = GetValidConvexHullPath(attachTo);
if (savePath != "")
{
string assetPath = GetFirstValidAssetPath(savePath, ECEPreferences.SaveConvexHullSuffix);
AssetDatabase.CreateAsset(mesh, assetPath);
AssetDatabase.SaveAssets();
}
}
}
/// <summary>
/// Checks if the asset already exists (needed for rotate and duplicate, as the mesh is the same mesh repeated.)
/// </summary>
/// <param name="mesh"></param>
/// <returns></returns>
public static bool DoesMeshAssetExists(Mesh mesh)
{
string p = AssetDatabase.GetAssetPath(mesh);
if (p == null || p.Length == 0)
{
return false;
}
return true;
}
/// <summary>
/// Creates and saves an array of mesh assets in the assetdatabase at the path with the the format "savePath"+"suffix"+[0-n].asset
/// </summary>
/// <param name="savePath">Full path up to save location: ie C:/UnityProjects/ProjectName/Assets/Folder/baseObject</param>
/// <param name="suffix">Suffix to add to save files ie _Suffix_</param>
public static Mesh[] CreateAndSaveMeshAssets(Mesh[] meshes, string savePath, string suffix)
{
string firstAssetPath = null;
int assetSuffixIndex = -1;
for (int i = 0; i < meshes.Length; i++)
{
// get a new valid path for each mesh to save.
string path = GetFirstValidAssetPath(savePath, suffix);
try
{
if (ECEPreferences.CombinedVHACDColliders && firstAssetPath != null)
{
//adding a name to the mesh even though it isn't required to match the first assets name as it by default has the path's name.
string name = firstAssetPath.Remove(assetSuffixIndex, firstAssetPath.Length - assetSuffixIndex);
name = name.Remove(0, name.LastIndexOf("/") + 1);
meshes[i].name = name + suffix + i.ToString();
AssetDatabase.AddObjectToAsset(meshes[i], firstAssetPath);
}
else
{
AssetDatabase.CreateAsset(meshes[i], path);
}
}
catch (System.Exception error)
{
Debug.LogError("Error saving at path:" + path + ". Try changing the save Convex Hull path in Easy Collider Editor's preferences to a different folder.\n" + error.ToString());
}
if (firstAssetPath == null)
{
firstAssetPath = path;
assetSuffixIndex = firstAssetPath.IndexOf(suffix);
}
}
AssetDatabase.SaveAssets();
if (ECEPreferences.CombinedVHACDColliders)
{
// need to reload the assets and update the meshes array otherwise they don't point to the correct object
// only the first one will without this as for whatever reason create asset will correctly link the objects but adding an object to an asset will not.
var assets = AssetDatabase.LoadAllAssetsAtPath(firstAssetPath);
for (int i = 0; i < assets.Length; i++)
{
meshes[i] = (Mesh)assets[i];
}
}
return meshes;
}
}
}
#endif
@@ -0,0 +1,20 @@
fileFormatVersion: 2
guid: 6ddf66fc4a34fe740aee3cf08e0549af
timeCreated: 1600696849
licenseType: Store
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 67880
packageName: Easy Collider Editor
packageVersion: 6.18.1
assetPath: Assets/EasyColliderEditor/Scripts/EasyColliderSaving.cs
uploadId: 749371
@@ -0,0 +1,26 @@
#if (UNITY_EDITOR)
namespace ECE
{
/// <summary>
/// A list of tips for users of easy collider editor.
/// </summary>
public static class EasyColliderTips
{
public const string TRY_MOUSE_CONTROL = "Want to be able to select vertices with the mouse? Try enabling the mouse controls in preferences.";
public const string NEW_MOUSE_CONTROL = "Use left click to select the highlighted vertex, and the right click to select the point under the mouse.";
public const string COMPUTE_SHADER_TIP = "You're system's shader model does not support shaders with a compute buffer. Be sure to use the gizmo display method instead of shader in the preferences.";
public const string EDIT_PREFS_FORCED_FOCUSED = "You are editing preferences with forced window focus enabled. To make this easier, try disabling vertex selection, or the force focus scene option in preferences.";
public const string FORCED_FOCUSED_WINDOW = "Forced window focus is enabled, you may not be able to edit values easily by typing. Disable vertex selection, or the force focus scene option in preferences.";
public const string IN_PLAY_MODE = "Vertex selection is not enabled when in play mode.";
public const string NO_MESH_FILTER_FOUND = "No mesh filter is on the selected gameobject, try enabling include child meshes.";
public const string WRONG_FOCUSED_WINDOW = "Vertex selection only works when the scene view window is focused.";
public const string ROTATED_BOX_COLLIDER_TIP = "The first 3 points determine the orientation of a rotated box collider.";
public const string ROTATED_CAPSULE_COLLIDER_TIP = "The first 2 points determine the orientation of a rotated capsule collider.";
public const string COLLIDER_CREATION_SHORTCUTS_1 = "Shortcuts:\n\t[1-7] Change collider preview\n\t[~] Create the collider being previewed\n\tDouble Tap [1-7] Create the collider";
public const string AUTO_SKILLED_CONTROL_PARAMETERS = "Holding CTRL while adjusting a parameter in Per Bone Settings will also adjust all of it's children.";
}
}
#endif
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 3855a2c50be7c1742950276affa94392
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 67880
packageName: Easy Collider Editor
packageVersion: 6.18.1
assetPath: Assets/EasyColliderEditor/Scripts/EasyColliderTips.cs
uploadId: 749371
@@ -0,0 +1,918 @@
#if (UNITY_EDITOR)
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using System;
namespace ECE
{
public static class EasyColliderUIHelpers
{
/// <summary>
/// Stores all the collider icons
/// </summary>
public static Texture2D[] ColliderIcons;
public static Texture2D[] ColliderMergeIcons;
/// <summary>
/// Creates a bunch of buttons that function similar to an enum popup where only one can be selected.
/// </summary>
/// <param name="selected">Current selected enum</param>
/// <returns>Selected enum</returns>
public static Enum EnumButtonArray(Enum selected, string[] labels, string[] toolTips)
{
GUIStyle style = new GUIStyle(GUI.skin.button);
style.padding.left = 5;
style.padding.right = 5;
style.padding.bottom = 2;
style.padding.top = 0;
Array a = Enum.GetValues(selected.GetType());
int currentValue = Convert.ToInt32(selected);
for (int i = 0; i < a.Length; i++)
{
GUIContent content = new GUIContent(labels[i], toolTips[i]);
if ((int)a.GetValue(i) == currentValue)
{
Color TempGUIColor = GUI.color;
GUI.color = _DisabledButtonColor;
GUILayout.Button(content, style);
GUI.color = TempGUIColor;
}
else
{
if (GUILayout.Button(content, style))
{
return (Enum)a.GetValue(i);
}
}
}
return selected;
}
/// <summary>
/// Creates buttons with icons as content that return an Enum when clicked.
/// </summary>
/// <param name="selected"></param>
/// <param name="iconContentNames"></param>
/// <param name="toolTips"></param>
/// <returns></returns>
public static Enum EnumIconButtonArray(Enum selected, string[] iconContentNames, string[] toolTips)
{
GUIStyle style = new GUIStyle(GUI.skin.box);
style.padding = new RectOffset(0, 0, 0, 0);
style.margin = new RectOffset(0, 2, 4, 0);
Array a = Enum.GetValues(selected.GetType());
int currentValue = Convert.ToInt32(selected);
for (int i = 0; i < a.Length; i++)
{
GUIContent content = EditorGUIUtility.IconContent(iconContentNames[i], toolTips[i]);
if ((int)a.GetValue(i) == currentValue)
{
Color TempGUIColor = GUI.color;
GUI.color = _DisabledButtonColor;
GUILayout.Button(content, style);
GUI.color = TempGUIColor;
}
else
{
if (GUILayout.Button(content, style))
{
return (Enum)a.GetValue(i);
}
}
}
return selected;
}
/// <summary>
/// Gets all the editor icons and loads them and stores them in an array
/// </summary>
public static void GetIcons()
{
ColliderIcons = new Texture2D[7];
ColliderMergeIcons = new Texture2D[7];
string[] locs = AssetDatabase.FindAssets("ECEUIBox t:texture2D");
if (locs.Length > 0)
{
ColliderIcons[0] = AssetDatabase.LoadAssetAtPath<Texture2D>(AssetDatabase.GUIDToAssetPath(locs[0]));
ColliderMergeIcons[0] = AssetDatabase.LoadAssetAtPath<Texture2D>(AssetDatabase.GUIDToAssetPath(locs[1]));
}
locs = AssetDatabase.FindAssets("ECEUIRotatedBox t:texture2D");
if (locs.Length > 0)
{
ColliderIcons[1] = AssetDatabase.LoadAssetAtPath<Texture2D>(AssetDatabase.GUIDToAssetPath(locs[0]));
ColliderMergeIcons[1] = AssetDatabase.LoadAssetAtPath<Texture2D>(AssetDatabase.GUIDToAssetPath(locs[1]));
}
locs = AssetDatabase.FindAssets("ECEUISphere t:texture2D");
if (locs.Length > 0)
{
ColliderIcons[2] = AssetDatabase.LoadAssetAtPath<Texture2D>(AssetDatabase.GUIDToAssetPath(locs[0]));
ColliderMergeIcons[2] = AssetDatabase.LoadAssetAtPath<Texture2D>(AssetDatabase.GUIDToAssetPath(locs[1]));
}
locs = AssetDatabase.FindAssets("ECEUICapsule t:texture2D");
if (locs.Length > 0)
{
ColliderIcons[3] = AssetDatabase.LoadAssetAtPath<Texture2D>(AssetDatabase.GUIDToAssetPath(locs[0]));
ColliderMergeIcons[3] = AssetDatabase.LoadAssetAtPath<Texture2D>(AssetDatabase.GUIDToAssetPath(locs[1]));
}
locs = AssetDatabase.FindAssets("ECEUIRotatedCapsule t:texture2D");
if (locs.Length > 0)
{
ColliderIcons[4] = AssetDatabase.LoadAssetAtPath<Texture2D>(AssetDatabase.GUIDToAssetPath(locs[0]));
ColliderMergeIcons[4] = AssetDatabase.LoadAssetAtPath<Texture2D>(AssetDatabase.GUIDToAssetPath(locs[1]));
}
locs = AssetDatabase.FindAssets("ECEUIConvexMesh t:texture2D");
if (locs.Length > 0)
{
ColliderIcons[5] = AssetDatabase.LoadAssetAtPath<Texture2D>(AssetDatabase.GUIDToAssetPath(locs[0]));
ColliderMergeIcons[5] = AssetDatabase.LoadAssetAtPath<Texture2D>(AssetDatabase.GUIDToAssetPath(locs[1]));
}
locs = AssetDatabase.FindAssets("ECEUICylinder t:texture2D");
if (locs.Length > 0)
{
ColliderIcons[6] = AssetDatabase.LoadAssetAtPath<Texture2D>(AssetDatabase.GUIDToAssetPath(locs[0]));
ColliderMergeIcons[6] = AssetDatabase.LoadAssetAtPath<Texture2D>(AssetDatabase.GUIDToAssetPath(locs[1]));
// ColliderMergeIcons[3] = AssetDatabase.LoadAssetAtPath<Texture2D>(AssetDatabase.GUIDToAssetPath(locs[1]));
}
}
/// <summary>
/// checks to see if the icons have moved / need to be found.
/// </summary>
public static void VerifyIcons()
{
bool needsUpdate = false;
if (ColliderIcons == null || ColliderMergeIcons == null)
{
GetIcons();
}
else
{
foreach (Texture2D t2d in ColliderIcons)
{
if (t2d == null)
{
needsUpdate = true;
}
}
foreach (Texture2D t2d in ColliderMergeIcons)
{
if (t2d == null)
{
needsUpdate = true;
}
}
if (needsUpdate)
{
GetIcons();
}
}
}
/// <summary>
/// Helper method to create a button with a 32x32 Icon where the icons are found seperately and stored in an array.
/// </summary>
/// <param name="tooltip">tooltip to display when button is enabled</param>
/// <param name="disabledToolTip">tooltip to display when disabled</param>
/// <param name="iconNumber">icon number in texture2d array</param>
/// <param name="isEnabled">is this icon enable?</param>
/// <returns>true if enabled and the button is clicked, false otherwise</returns>
public static bool DisableableIconButton(string tooltip, string disabledToolTip, int iconNumber, bool isEnabled)
{
VerifyIcons();
if (ColliderIcons[iconNumber] == null) return false; // an icon was deleted.
GUIStyle style = new GUIStyle(GUI.skin.button);
style.imagePosition = ImagePosition.ImageAbove;
style.padding = new RectOffset(4, 4, 4, 4);
GUIContent content = new GUIContent("Text", ColliderIcons[iconNumber]);
GUI.enabled = isEnabled;
bool button = GUILayout.Button(content, style, GUILayout.ExpandWidth(false));
GUI.enabled = true;
return button;
}
static string[] alphaKeys = new string[7] { "1", "2", "3", "4", "5", "6", "7" };
private static string KeyCodeToString(KeyCode keyCode)
{
return alphaKeys[((int)keyCode - 257)];
}
private static GUIStyle _highlightedStyle;
private static GUIStyle HighLightedStyle
{
get
{
if (_highlightedStyle == null)
{
_highlightedStyle = new GUIStyle(GUI.skin.box);
Texture2D text = new Texture2D(1, 1);
text.SetPixel(0, 0, Color.red);
_highlightedStyle.normal.background = text;
_highlightedStyle.fixedHeight = 0;
_highlightedStyle.padding = new RectOffset(4, 4, 1, 16);
}
return _highlightedStyle;
}
}
private static GUIStyle _iconButtonLabelStyle;
private static GUIStyle IconButtonLabelStyle
{
get
{
if (_iconButtonLabelStyle == null)
{
_iconButtonLabelStyle = new GUIStyle(GUI.skin.box);
_iconButtonLabelStyle.richText = true;
_iconButtonLabelStyle.fixedHeight = 16;
_iconButtonLabelStyle.fixedWidth = 40;
_iconButtonLabelStyle.padding.bottom = 1;
_iconButtonLabelStyle.alignment = TextAnchor.LowerCenter;
}
return _iconButtonLabelStyle;
}
}
/// <summary>
/// Helper method to create a button with a 32x32 Icon where the icons are found seperately and stored in an array.
/// </summary>
/// <param name="tooltip">tooltip to display when button is enabled</param>
/// <param name="disabledToolTip">tooltip to display when disabled</param>
/// <param name="iconNumber">icon number in texture2d array</param>
/// <param name="isEnabled">is this icon enable?</param>
/// <returns>true if enabled and the button is clicked, false otherwise</returns>
public static bool DisableableIconButtonShortcutCreation(string tooltip, string disabledToolTip, int iconNumber, bool isEnabled, KeyCode shortCut, bool highlight)
{
VerifyIcons();
if (ColliderIcons.Length - 1 < iconNumber || ColliderIcons[iconNumber] == null) return false; // an icon was deleted.
GUIStyle style = new GUIStyle(GUI.skin.button);
style.padding = new RectOffset(4, 4, 1, 16);
GUIStyle labelStyle = new GUIStyle(GUI.skin.box);
labelStyle.richText = true;
labelStyle.fixedHeight = 16;
labelStyle.fixedWidth = 40;
labelStyle.padding.bottom = 1;
labelStyle.alignment = TextAnchor.LowerCenter;
GUIContent content = new GUIContent(ColliderIcons[iconNumber]);
Rect r = GUILayoutUtility.GetRect(content, style);
style.fixedHeight = 48;
GUI.enabled = isEnabled;
if (highlight && isEnabled)
{
Rect rect = new Rect(r.x - 2, r.y - 2, r.width + 4, r.height + 3);
Color bc = GUI.backgroundColor;
GUI.backgroundColor = new Color(0, 0.5f, 1f, 1f);
GUI.Box(rect, GUIContent.none, HighLightedStyle);
GUI.backgroundColor = bc;
}
style.fixedHeight = 48;
content.tooltip = isEnabled ? tooltip : disabledToolTip;
bool button = GUI.Button(r, content, style);
r.y += 32;
// better dark mode colors, also light mode enabled/disabled button colors.
string colorCode = isEnabled ? "black" : "#525252";
if (EditorGUIUtility.isProSkin)
{
colorCode = isEnabled ? "#C4C4C4" : "#6C6C6C";
}
GUI.Label(r, "<color=" + colorCode + "><b>" + KeyCodeToString(shortCut) + "</b></color>", IconButtonLabelStyle);
GUI.enabled = true;
return button;
}
public static bool DisableableIconButtonShortcutMerge(string tooltip, string disabledToolTip, int iconNumber, bool isEnabled, KeyCode shortCut, bool highlight)
{
VerifyIcons();
if (ColliderMergeIcons.Length - 1 < iconNumber || ColliderMergeIcons[iconNumber] == null) return false; // an icon was deleted.
GUIStyle style = new GUIStyle(GUI.skin.button);
style.padding = new RectOffset(4, 4, 1, 16);
GUIStyle labelStyle = new GUIStyle(GUI.skin.box);
labelStyle.richText = true;
labelStyle.fixedHeight = 16;
labelStyle.fixedWidth = 40;
labelStyle.padding.bottom = 1;
labelStyle.alignment = TextAnchor.LowerCenter;
GUIContent content = new GUIContent(ColliderMergeIcons[iconNumber]);
Rect r = GUILayoutUtility.GetRect(content, style);
style.fixedHeight = 48;
GUI.enabled = isEnabled;
if (highlight && isEnabled)
{
Rect rect = new Rect(r.x - 2, r.y - 2, r.width + 4, r.height + 3);
Color bc = GUI.backgroundColor;
GUI.backgroundColor = new Color(0, 0.5f, 1f, 1f);
GUI.Box(rect, GUIContent.none, HighLightedStyle);
GUI.backgroundColor = bc;
}
content.tooltip = isEnabled ? tooltip : disabledToolTip;
bool button = GUI.Button(r, content, style);
r.y += 32;
// better dark mode colors, also light mode enabled/disabled button colors.
string colorCode = isEnabled ? "black" : "#525252";
if (EditorGUIUtility.isProSkin)
{
colorCode = isEnabled ? "#C4C4C4" : "#6C6C6C";
}
GUI.Label(r, "<color=" + colorCode + "><b>" + KeyCodeToString(shortCut) + "</b></color>", IconButtonLabelStyle);
GUI.enabled = true;
return button;
}
/// <summary>
/// Background GUI Color to use for buttons when they are disabled
/// </summary>
public static Color _DisabledButtonColor = new Color(0.7f, 0.7f, 0.7f, 1f);
/// <summary>
/// Background GUI Color for toggles when they are disabled
/// </summary>
public static Color _DisabledToggleColor = new Color(1, 1, 1, 0.33f);
/// <summary>
/// Creates a disableable and undoable foldout list.
/// Allows you to pass a method to check if an item a user is trying to add is valid before adding to the list.
/// Has an X button beside each item to directly remove it, and a clear list button at the bottom.
/// </summary>
/// <param name="obj">Object to record undo on</param>
/// <param name="foldoutContent">GUI Content of the foldout</param>
/// <param name="disabledText">Text to be displayed when the foldout is disabled and open</param>
/// <param name="isOpen">references to the bool controlling if the foldout is open</param>
/// <param name="list">List of items to display</param>
/// <param name="objType">Type to use in object field</param>
/// <param name="OnAddMethod">Method that returns true if the object should be added to the list</param>
/// <param name="isEnabled">Is the foldout enabled?</param>
/// <typeparam name="T">List's type</typeparam>
public static void DisableableFoldoutList<T>(
UnityEngine.Object obj,
GUIContent foldoutContent,
string disabledText, ref bool isOpen,
ref List<T> list,
System.Type objType,
Func<T, bool> OnAddMethod,
bool isEnabled) where T : UnityEngine.Object
{
// createa foldout.
isOpen = EditorGUILayout.Foldout(isOpen, foldoutContent);
if (isOpen) // only display if the foldout is open.
{
if (isEnabled) // if the list is enabled, display it
{
// Variables to keep track of current item being displayed
T previous; // current item prior to it changing (if it does)
T current; // current item after changing (if it does)
List<T> itemsToRemove = new List<T>();
for (int i = 0; i < list.Count; i++)
{
// each item is horizontally displayed
EditorGUILayout.BeginHorizontal();
// quick removal button
if (GUILayout.Button("X", GUILayout.ExpandWidth(false)))
{
itemsToRemove.Add(list[i]);
}
else
{
// Create a field for each list
previous = list[i];
current = (T)EditorGUILayout.ObjectField(list[i], objType, true);
if (current == null) // if the new item is null, mark for removal.
{
itemsToRemove.Add(list[i]);
}
// otherwise, call the onadd method to see if the item in the field should be added to the list
else if (!OnAddMethod(current))
{
// if it shouldn't be added, then set the item to the previous item
// this cleans up items that are in the list when the onadd method uses different parameters
if (!OnAddMethod(previous))
{
// if that item is also invalid, remove it fromt he list.
itemsToRemove.Add(list[i]);
}
}
else
{
// the new item is valid, set that list item to that value.
list[i] = current;
}
}
EditorGUILayout.EndHorizontal();
}
if (itemsToRemove.Count > 0)
{
// record the removal of all items to remove.
Undo.RecordObject(obj, "Change List");
foreach (T item in itemsToRemove) list.Remove(item);
}
// Use an empty object field at the bottom as a way to quickly add to the list.
current = (T)EditorGUILayout.ObjectField(null, objType, true);
// if its not null and passes the OnAddMethod function
if (current != null && OnAddMethod(current))
{
// record the undo of adding an object
Undo.RecordObject(obj, "Change List");
list.Add(current);
}
if (GUILayout.Button("Clear List"))
{
Undo.RecordObject(obj, "Clear List");
list.Clear();
}
}
else // list is disabled, just display the disabled text as a lebel when the foldout is opened.
{
GUIStyle label = new GUIStyle(GUI.skin.label);
label.wordWrap = true;
EditorGUILayout.LabelField(disabledText, label);
}
}
}
/// <summary>
/// Creates a button that allows undoable changing of a keycode value.
/// Button displays current keycode, then press any key when pressed and listens for a keypress, then updates the keycode.
/// </summary>
/// <param name="obj">Object to record undo on.</param>
/// <param name="label">Label to display beside button</param>
/// <param name="key">KeyCode to change. Should be unique for each button.</param>
/// <param name="isChanging">Bool representing whether it should be listening to key presses. Should be unique for each button.</param>
public static bool ChangeButtonKeyCodeUndoable(UnityEngine.Object obj, string label, string labelTooltip, ref KeyCode key, ref bool isChanging, float windowWidth, bool drawlabel = false)
{
float labelWidth = 100;
// -15 to add padding to prevent a horizontal scrollbar always being present, this can probably be actually calculated from some unity internal padding values but whatever.
float buttonWidth = windowWidth - labelWidth - 25;
if (buttonWidth < 120) { buttonWidth = 120; }
GUIStyle pressedButtonStyle = new GUIStyle(GUI.skin.box);
pressedButtonStyle.fontStyle = FontStyle.Bold;
pressedButtonStyle.fixedWidth = buttonWidth;
GUIStyle buttonStyle = new GUIStyle(GUI.skin.button);
buttonStyle.fixedWidth = buttonWidth;
//buttonStyle.min
//buttonStyle.stretchWidth = true;
// EditorGUILayout.BeginHorizontal();
// GUILayout.Label(new GUIContent(label, labelTooltip));
// EditorGUILayout.LabelField(new GUIContent(label, labelTooltip), GUILayout.ExpandWidth(false));
string buttonTitle = isChanging ? "Press a key" : key.ToString();
if (drawlabel)
{
EditorGUILayout.BeginHorizontal();
// GUILayout.Label(new GUIContent(label, labelTooltip), GUILayout.ExpandWidth(false));
LabelWidth(label, labelTooltip, labelWidth);
}
if (GUILayout.Button(new GUIContent(buttonTitle, "Click then press a key to change.\nModifier keys (like alt, ctrl, space, shift, etc.) can not be used."), isChanging ? pressedButtonStyle : buttonStyle))
{
isChanging = true;
}
if (drawlabel)
{
EditorGUILayout.EndHorizontal();
}
// EditorGUILayout.EndHorizontal();
if (isChanging)
{
if (CheckKeypressChangeUndoable(obj, ref key))
{
isChanging = false;
}
}
return isChanging;
}
/// <summary>
/// Changes the KeyCode of keyCode through an undoable action when a key is pressed down.
/// </summary>
/// <param name="obj">Object to record undo on.</param>
/// <param name="keyCode">KeyCode to change to new key</param>
/// <returns>true if key was changed.</returns>
private static bool CheckKeypressChangeUndoable(UnityEngine.Object obj, ref KeyCode keyCode)
{
if (Event.current != null // have an event.
&& Event.current.type == EventType.KeyDown // a key down event.
&& Event.current.keyCode != KeyCode.None && !IsModifierKeyUsed(Event.current.keyCode)) // a key down event that wasn't None.
{
Undo.RecordObject(obj, "Change keycode");
keyCode = Event.current.keyCode;
return true;
}
return false;
}
public static void HorizontalLineLight()
{
HorizontalLine(new Color(0, 0, 0, 0.25f));
}
/// <summary>
/// Draws a vertical line of thickness and color at the current control rect at a single line height.
/// </summary>
/// <param name="color"></param>
/// <param name="lineThickness"></param>
/// <param name="paddingLeft"></param>
/// <param name="extraHeight"></param>
public static void VerticalLine(Color color, float lineThickness = 1f, float paddingLeft = 0f, float extraHeight = 2f)
{
Rect r = EditorGUILayout.GetControlRect(GUILayout.Width(lineThickness));
r.height = EditorGUIUtility.singleLineHeight + extraHeight;
r.width = lineThickness;
r.x += paddingLeft;
EditorGUI.DrawRect(r, color);
}
/// <summary>
/// draws a horizontal line of a given color, thickness, and padding. Centered in the rect.
/// </summary>
/// <param name="color">color of the line</param>
/// <param name="lineThickness">thickness of the line</param>
/// <param name="padding"></param>
public static void HorizontalLine(Color color, float lineThickness = 2f, float padding = 6f)
{
Rect r = EditorGUILayout.GetControlRect(GUILayout.Height(padding));
// thickness of line to draw is the height
r.height = lineThickness;
// center the line in the rect.
r.y = r.y + (padding - lineThickness) / 2;
// draw the rect.
EditorGUI.DrawRect(r, color);
}
public static void VerticalSpace(float size)
{
Rect r = EditorGUILayout.GetControlRect(GUILayout.Height(size));
EditorGUI.DrawRect(r, new Color(0, 0, 0, 0));
}
/// <summary>
/// checks to see if the keycode is one of the many modifier keys.
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
private static bool IsModifierKeyUsed(KeyCode value)
{
switch (value)
{
case KeyCode.LeftShift:
case KeyCode.RightShift:
case KeyCode.LeftControl:
case KeyCode.RightControl:
case KeyCode.LeftAlt:
case KeyCode.RightAlt:
case KeyCode.LeftCommand:
case KeyCode.RightCommand:
case KeyCode.Numlock:
case KeyCode.CapsLock:
case KeyCode.LeftWindows: // covers both keycodes for right/left apple as well.
case KeyCode.RightWindows:
return true;
default:
return false;
}
}
/// <summary>
/// In case we want to modify all labels used in the future more easily.
/// Just makes a GUILayout.Label(label)
/// </summary>
/// <param name="label"></param>
public static void Label(string label, string tooltip = "")
{
GUILayout.Label(new GUIContent(label, tooltip));
}
public static void LabelWidth(string label, string tooltip = "", float width = -1)
{
GUIStyle labelStyle = new GUIStyle(GUI.skin.label);
if (width > 0) { labelStyle.fixedWidth = width; }
GUILayout.Label(new GUIContent(label, tooltip), labelStyle);
}
public static void LabelEmptyNoStretch(float size = 50f)
{
// float currentSize = EditorGUIUtility.labelWidth;
// EditorGUIUtility.labelWidth = size;
GUIStyle style = new GUIStyle(GUI.skin.label);
style.stretchWidth = false;
GUILayout.Label("", style);
// EditorGUIUtility.labelWidth = currentSize;
}
public static void LabelBold(string label, string tooltip = "")
{
GUIStyle style = new GUIStyle(GUI.skin.label);
style.fontStyle = FontStyle.Bold;
style.stretchWidth = false;
if (tooltip == "")
{
GUILayout.Label(label, style);
}
else
{
GUILayout.Label(new GUIContent(label, tooltip), style);
}
}
public static bool FoldoutBold(string label, ref bool foldout, string tooltip = "")
{
GUIStyle style = new GUIStyle(EditorStyles.foldout);
style.fontStyle = FontStyle.Bold;
style.stretchWidth = false;
if (tooltip == "")
{
// GUILayout.Label(label, style);
foldout = EditorGUILayout.Foldout(foldout, label, style);
}
else
{
foldout = EditorGUILayout.Foldout(foldout, new GUIContent(label, tooltip), style);
}
return foldout;
}
public static void LabelIcon(string label, string iconName, string tooltip = "")
{
GUIStyle style = new GUIStyle(GUI.skin.label);
style.wordWrap = true;
GUIContent icon = EditorGUIUtility.IconContent(iconName, tooltip);
EditorGUILayout.BeginHorizontal();
GUILayout.Label(icon, GUILayout.ExpandWidth(false));
GUILayout.Label(new GUIContent(label, tooltip), style);
GUILayout.Label(icon, GUILayout.ExpandWidth(false));
EditorGUILayout.EndHorizontal();
}
/// <summary>
/// Creates an undoable color field
/// </summary>
/// <param name="obj">Object to record the undo on</param>
/// <param name="content">GUI Content for the auto-layout field</param>
/// <param name="undoString">String to use for undos</param>
/// <param name="value">Value of the color</param>
public static void ColorFieldUndoable(UnityEngine.Object obj, string undoString, ref Color value)
{
Color _ColorField = value;
EditorGUI.BeginChangeCheck();
_ColorField = EditorGUILayout.ColorField(_ColorField);
if (EditorGUI.EndChangeCheck())
{
Undo.RegisterCompleteObjectUndo(obj, undoString);
value = _ColorField;
}
}
public static bool DisableableButtonWithShortcut(string text, string enabledTooltip, string disabledTooltip, bool isEnabled, KeyCode shortcut, bool isShortcutEnabled)
{
if (isShortcutEnabled)
{
text = text + " (" + shortcut.ToString() + ")";
}
GUI.enabled = isEnabled;
bool button = GUILayout.Button(new GUIContent(text, isEnabled ? enabledTooltip : disabledTooltip));
GUI.enabled = true;
return button;
}
/// <summary>
/// Creates a button that displays different if it is enabled or disabled. Button always returns false if disabled.
/// <param name="title">text of button</param>
/// <param name="enabledTooltip">tool tip for button when enabled</param>
/// <param name="disabledTooltip">tool tip for box when disabled</param>
/// <param name="isEnabled">is the button enabled?</param>
/// <returns>false if disabled, true if enabled and button is clicked</returns>
public static bool DisableableButton(string text, string enabledTooltip, string disabledTooltip, bool isEnabled)
{
GUI.enabled = isEnabled;
bool button = GUILayout.Button(new GUIContent(text, isEnabled ? enabledTooltip : disabledTooltip));
GUI.enabled = true;
return button;
}
/// <summary>
/// Creates an undoable float field that can also be disabled
/// </summary>
/// <param name="obj">Object to record the undo on</param>
/// <param name="label">Label of the float field</param>
/// <param name="tooltip">Tooltip to display when enabled</param>
/// <param name="disabledTooltip">Tooltip to display when disabled</param>
/// <param name="undoString">String to use for undos</param>
/// <param name="value">Value of the float</param>
/// <param name="isEnabled">Is the float field enabled?</param>
public static void DisableableFloatFieldUndoable(UnityEngine.Object obj, string label, string tooltip, string disabledTooltip, string undoString, ref float value, bool isEnabled)
{
GUI.enabled = isEnabled;
FloatFieldUndoable(obj, new GUIContent(label, isEnabled ? tooltip : disabledTooltip), undoString, ref value);
GUI.enabled = true;
}
/// <summary>
/// Creates a left toggle if the toggle is enabled that functions normally,
/// otherwise creates a style toggle that is not toggleable and grayed-out.
/// </summary>
/// <param name="text">Text to show beside the toggle</param>
/// <param name="enabledTooltip">Tool tip when toggle is enabled</param>
/// <param name="disabledTooltip">Tool tip when toggle is disabled</param>
/// <param name="isEnabled">Is the toggle enabled</param>
/// <param name="toggle">Bool the toggle controls</param>
/// <returns>Value of toggle</returns>
public static bool DisableableToggleLeft(string text, string enabledTooltip, string disabledTooltip, bool isEnabled, bool toggle)
{
GUI.enabled = isEnabled;
bool toggleValue = GUILayout.Toggle(toggle, new GUIContent(text, isEnabled ? enabledTooltip : disabledTooltip));
GUI.enabled = true;
return toggleValue;
}
/// <summary>
/// Creates an undoable float field.
/// </summary>
/// <param name="obj">Object to record the undo on</param>
/// <param name="content">GUI Content for the auto-layout field</param>
/// <param name="undoString">String to use for undos</param>
/// <param name="value">Value of the float</param>
public static void FloatFieldUndoable(UnityEngine.Object obj, GUIContent content, string undoString, ref float value, int labelSize = -1)
{
float _FloatField = value;
EditorGUI.BeginChangeCheck();
float w = EditorGUIUtility.labelWidth;
if (labelSize > 0)
{
EditorGUIUtility.labelWidth = labelSize;
}
_FloatField = EditorGUILayout.FloatField(content, _FloatField);
if (EditorGUI.EndChangeCheck())
{
Undo.RegisterCompleteObjectUndo(obj, undoString);
value = _FloatField;
}
EditorGUIUtility.labelWidth = w;
}
static GUIStyle ButtonStyle;
public static bool IconButton(string iconContentName, string tooltip)
{
ButtonStyle = new GUIStyle(GUI.skin.button);
ButtonStyle.padding = new RectOffset(4, 4, 1, 1);
ButtonStyle.margin = new RectOffset(4, 4, 2, 0);
ButtonStyle.stretchWidth = false;
GUIContent icon = EditorGUIUtility.IconContent(iconContentName, tooltip);
// text was not tooltip!
icon.tooltip = tooltip;
if (GUILayout.Button(icon, ButtonStyle))
{
return true;
}
return false;
}
/// <summary>
/// Creates a float slider that converts basePow^current to an integer in actual result.
/// </summary>
/// <param name="current">Current Value of the float slider</param>
/// <param name="min">Min Value of the float slider</param>
/// <param name="max">Max value of the float slider</param>
/// <param name="actualResult">Result of all calculations that is actually used</param>
/// <param name="aMin">Min value to clamp result to</param>
/// <param name="aMax">Max value to clamp result to</param>
/// <param name="basePow">power to use when calculating actual result in Mathf.Pow(basePow, current)</param>
/// <returns>Current value of the slider itself</returns>
public static float SliderFloatToIntBase2(GUIContent label, float current, float min, float max, ref int actualResult, int aMin, int aMax, float basePow = 2f)
{
EditorGUILayout.BeginHorizontal();
// get the current control rect.
Rect r = EditorGUILayout.GetControlRect();
// quarter of width goes to the label.
r.width = r.width / 4;
// label of the slider
EditorGUI.LabelField(r, label);
// set up the control name for the slider
GUI.SetNextControlName("FloatSlider" + current);
// keep track if the slider changes
EditorGUI.BeginChangeCheck();
//sliderbar uses half of space.
r.x += r.width;
r.width *= 2;
// draw the slider.
current = GUI.HorizontalSlider(r, current, min, max);
// if it changes, and is not focused, change the focus to the slider
// this helps keep the area where you can directly enter the number with the keyboard updated as the slider moves.
if (EditorGUI.EndChangeCheck() && GUI.GetNameOfFocusedControl() != "FloatSlider" + current)
{
GUI.FocusControl("FloatSlider" + current);
}
// Set the actual result using the current slider.
actualResult = (int)Mathf.Clamp(Mathf.Pow(basePow, current), aMin, aMax);
// check if the user has updated the int field input
EditorGUI.BeginChangeCheck();
// adjust rect to use last quarter of space.
r.x += r.width + 8;
r.width = r.width / 2 - 8;
actualResult = EditorGUI.IntField(r, actualResult);
// actualResult = EditorGUILayout.IntField(actualResult, GUILayout.ExpandWidth(false));
if (EditorGUI.EndChangeCheck())
{
actualResult = Mathf.Clamp(actualResult, aMin, aMax);
// update the current value if the text has changed.
current = Mathf.Log(actualResult, 2);
}
EditorGUILayout.EndHorizontal();
// were done, return the current value.
return current;
}
/// <summary>
/// Creates an undoable toggle field.
/// </summary>
/// <param name="obj">Object to record the undo on</param>
/// <param name="content">GUI Content for the auto-layout field</param>
/// <param name="undoString">String to use for undos</param>
/// <param name="value">Value of the toggle</param>
public static void ToggleLeftUndoable(UnityEngine.Object obj, GUIContent content, string undoString, ref bool value, float labelWidth = 10f)
{
bool _ToggleField = value;
EditorGUI.BeginChangeCheck();
// _ToggleField = EditorGUILayout.ToggleLeft(content, _ToggleField);
float lw = EditorGUIUtility.labelWidth;
EditorGUIUtility.labelWidth = labelWidth;
// _ToggleField = GUILayout.Toggle(_ToggleField, content, GUILayout.ExpandWidth(false));
_ToggleField = EditorGUILayout.ToggleLeft(content, _ToggleField);
EditorGUIUtility.labelWidth = lw;
if (EditorGUI.EndChangeCheck())
{
// again record only works in some cases, and complete works significantly better.
// ie can't record changing DrawGizmos without the complete object undo.
Undo.RegisterCompleteObjectUndo(obj, undoString);
value = _ToggleField;
}
}
/// <summary>
/// creates a toggle left with no change check
/// </summary>
/// <param name="content"></param>
/// <param name="value"></param>
/// <param name="labelWidth"></param>
public static bool ToggleLeft(GUIContent content, bool value, float labelWidth = 10f)
{
bool _ToggleField = value;
float lw = EditorGUIUtility.labelWidth;
EditorGUIUtility.labelWidth = labelWidth;
_ToggleField = EditorGUILayout.ToggleLeft(content, _ToggleField);
EditorGUIUtility.labelWidth = lw;
return _ToggleField;
}
public static Enum EnumPopup(GUIContent content, Enum selected, float labelWidth = 50f)
{
float lw = EditorGUIUtility.labelWidth;
EditorGUIUtility.labelWidth = labelWidth;
GUIStyle miniPopupStyle = GUI.skin.GetStyle("MiniPopup");
if (miniPopupStyle != null)
{
GUIStyle enumStyle = new GUIStyle(miniPopupStyle);
Enum val = EditorGUILayout.EnumPopup(content, selected, enumStyle);
EditorGUIUtility.labelWidth = lw;
return val;
}
else
{
Enum val = EditorGUILayout.EnumPopup(content, selected);
EditorGUIUtility.labelWidth = lw;
return val;
}
}
}
}
#endif
@@ -0,0 +1,20 @@
fileFormatVersion: 2
guid: 6d01889b53b9585409077f8e53708c46
timeCreated: 1592405766
licenseType: Store
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 67880
packageName: Easy Collider Editor
packageVersion: 6.18.1
assetPath: Assets/EasyColliderEditor/Scripts/EasyColliderUIHelpers.cs
uploadId: 749371
@@ -0,0 +1,478 @@
#if (UNITY_EDITOR && !UNITY_EDITOR_LINUX)
using System.Collections.Generic;
using UnityEngine;
using System.Runtime.InteropServices;
using System;
using System.Linq;
namespace ECE
{
//Future potential features:
// The option to covert the convex hulls generated into other colliders, like box colliders (boxelization is a fun term).
// So that we can leverage VHACD results into alternative basic colliders.
// New version of vhacd is out but in my testing it is much slower than the older performance branch version
// additionally, it offers less adjustable parameters, which makes it harder to get a good fit,
// even though the fit isn't perfect with any vhacd implementation since it's approximate convex decomposition
// and even though the current parameters aren't particularily understandable, you can adjust them and see the output quickly until something is close enough.
public class EasyColliderVHACD
{
// If you're getting an error about DLL not found exception, you'll likely be pointed to this line by the error
// near the top of this file you'll find " const string dllName = "ECE_VHACD"; " ,
// this is where the dll name is placed (these same comments are there as well)
// To fix this on Mac: sometimes it can not recognize the .bundle, try either "ECE_VHACD.bundle" or "ECE_VHACD" as the dllName string
// Occasionally this can also happen when the dll/bundles are updated, and imported into unity after they were already used
// to correctly update when vhacd is updated, be sure to close unity, and immediately update the asset on opening the project
// currently only supports windows, and OSX (arm / silicon and intel) versions of unity.
const string dllName = "ECE_VHACD";
[DllImport(dllName, EntryPoint = "GetMaxNumVerticesPerCH")]
private static extern uint GetMaxNumVerticesPerCH();
// extern "C" VHACD_API double* GetConvexHullCenter();
[DllImport(dllName, EntryPoint = "GetConvexHullCenter")]
private static extern IntPtr GetConvexHullCenter();
// extern "C" VHACD_API unsigned int* GetConvexHullTriangles();
[DllImport(dllName, EntryPoint = "GetConvexHullTriangles")]
private static extern IntPtr GetConvexHullTriangles();
// extern "C" VHACD_API double* GetConvexHullPoints();
[DllImport(dllName, EntryPoint = "GetConvexHullPoints")]
private static extern IntPtr GetConvexHullPoints();
// extern "C" VHACD_API void Compute();
[DllImport(dllName, EntryPoint = "Compute")]
private static extern void Compute();
// extern "C" VHACD_API bool Create();
[DllImport(dllName, EntryPoint = "Create")]
private static extern bool Create();
// extern "C" VHACD_API bool Create_ASYNC();
[DllImport(dllName, EntryPoint = "Create_ASYNC")]
private static extern bool Create_ASYNC();
// extern "C" VHACD_API void Destroy();
[DllImport(dllName, EntryPoint = "Destroy")]
private static extern void Destroy();
// extern "C" VHACD_API int GetConvexHullNumPoints();
[DllImport(dllName, EntryPoint = "GetConvexHullNumPoints")]
private static extern int GetConvexHullNumPoints();
// extern "C" VHACD_API int GetConvexHullNumTriangles();
[DllImport(dllName, EntryPoint = "GetConvexHullNumTriangles")]
private static extern int GetConvexHullNumTriangles();
// extern "C" VHACD_API double GetConvexHullPoint(int index);
[DllImport(dllName, EntryPoint = "GetConvexHullPoint")]
private static extern double GetConvexHullPoint(int index);
// extern "C" VHACD_API int GetConvexHullTriangle(int index);
[DllImport(dllName, EntryPoint = "GetConvexHullTriangle")]
private static extern int GetConvexHullTriangle(int index);
// extern "C" VHACD_API double GetConvexHullVolume();
[DllImport(dllName, EntryPoint = "GetConvexHullVolume")]
private static extern double GetConvexHullVolume();
// extern "C" VHACD_API int GetNumberOfConvexHulls();
[DllImport(dllName, EntryPoint = "GetNumberOfConvexHulls")]
private static extern int GetNumberOfConvexHulls();
// extern "C" VHACD_API int GetPointSize();
[DllImport(dllName, EntryPoint = "GetPointSize")]
private static extern int GetPointSize();
// extern "C" VHACD_API int GetPointSize();
[DllImport(dllName, EntryPoint = "IsReady")]
private static extern bool IsReady();
// extern "C" VHACD_API void SetConvexHull(int index);
[DllImport(dllName, EntryPoint = "SetConvexHull")]
private static extern void SetConvexHull(int index);
// extern "C" VHACD_API void SetMaxHulls(int value);
[DllImport(dllName, EntryPoint = "SetMaxHulls")]
private static extern void SetMaxHulls(int value);
// extern "C" VHACD_API void SetMaxVerticesPerHull(int value);
[DllImport(dllName, EntryPoint = "SetMaxVerticesPerHull")]
private static extern void SetMaxVerticesPerHull(int value);
// For branch PERFORMANCE ENHANCEMENTS
// extern "C" VHACD_API void SetParameters(
// double concavity,
// double alpha,
// double beta,
// double minVolumePerConvexHull,
// int resolution,
// int maxNumVerticesPerCH,
// int planeDownsampling,
// int convexhullDownsampling,
// int maxConvexHulls,
// bool projectHullVertices,
// unsigned int fillMode);
[DllImport(dllName, EntryPoint = "SetParameters")]
private static extern void SetParameters(
double concavity,
double alpha,
double beta,
double minVolumePerConvexHull,
int resolution,
int maxNumVerticesPerCH,
int planeDownsampling,
int convexhullDownsampling,
int maxConvexHulls,
bool projectHullVertices,
uint fillMode
);
// extern "C" VHACD_API void SetPoint(int index, float value);
[DllImport(dllName, EntryPoint = "SetPoint")]
private static extern void SetPoint(int index, float value);
// extern "C" VHACD_API void SetPoints(float pointsArr[], int size);
[DllImport(dllName, EntryPoint = "SetPoints")]
private static extern void SetPoints(float[] pointsArr, int size);
// extern "C" VHACD_API void SetPointSize(int size);
[DllImport(dllName, EntryPoint = "SetPointSize")]
private static extern void SetPointSize(int size);
// extern "C" VHACD_API void SetResolution(int value);
[DllImport(dllName, EntryPoint = "SetResolution")]
private static extern void SetResolution(int value);
// extern "C" VHACD_API void SetTriangle(int index, int value);
[DllImport(dllName, EntryPoint = "SetTriangle")]
private static extern void SetTriangle(int index, int value);
// extern "C" VHACD_API void SetTriangles(int trianglesArr[], int size);
[DllImport(dllName, EntryPoint = "SetTriangles")]
private static extern void SetTriangles(int[] trianglesArr, int size);
// extern "C" VHACD_API void SetTriangleSize(int size);
[DllImport(dllName, EntryPoint = "SetTriangleSize")]
private static extern void SetTriangleSize(int size);
/// <summary>
/// Is an instance of vhacd initialized?
/// </summary>
/// this is a fix for the new version of vhacd which is not used yet for various reasons.
private bool isInitialized = false;
/// <summary>
/// Initializes a VHACD instance
/// </summary>
/// <param name="async">Use async process?</param>
/// <returns></returns>
public bool Init(bool async = true)
{
Clean();
if (async)
{
// fixes an issue in new vhacd without changing the api.
isInitialized = true;
// If you're getting an error about DLL not found exception, you'll likely be pointed to this line by the error
// near the top of this file you'll find " const string dllName = "ECE_VHACD"; " ,
// this is where the dll name is placed (these same comments are there as well)
// To fix this on Mac: sometimes it can not recognize the .bundle, try either "ECE_VHACD.bundle" or "ECE_VHACD" as the dllName string
// Occasionally this can also happen when the dll/bundles are updated, and imported into unity after they were already used
// to correctly update when vhacd is updated, be sure to close unity, and immediately update the asset on opening the project
// currently only supports windows, and OSX (arm / silicon and intel) versions of unity.
return Create_ASYNC();
}
else
{
isInitialized = true;
return Create();
}
}
/// <summary>
/// Destroys the VHACD instance, if it is already initialized.
/// </summary>
/// <returns>true if destroyed, false if not destroyed(because it wasn't initialized yet)</returns>
public bool Clean()
{
// fixes issue where vhacd isn't initialized and tries to destroy itself (in new vhacd)
if (isInitialized)
{
// Debug.Log("Clean" + dllName);
isInitialized = false;
Destroy();
return true;
}
else
{
return false;
}
}
/// <summary>
/// Gets all calculated convex hulls and turn them into meshes.
/// </summary>
/// <returns>convex hull meshes</returns>
public Mesh[] CreateConvexHullMeshes()
{
int numHulls = GetNumberOfConvexHulls();
Mesh[] meshes = new Mesh[numHulls];
for (int i = 0; i < numHulls; i++)
{
// get the current convex hull
SetConvexHull(i);
// get the ch data
int pointCount = GetConvexHullNumPoints();
int triangleCount = GetConvexHullNumTriangles();
// create new vertex and triangles array.
Vector3[] vertices = new Vector3[pointCount];
int[] triangles = new int[triangleCount * 3];
for (int j = 0; j < triangleCount * 3; j++)
{
triangles[j] = GetConvexHullTriangle(j);
}
// assing each point to a vertex in the array
Vector3 point = Vector3.zero;
for (int j = 0; j < pointCount * 3; j += 3)
{
// note that in VHACD, each vertex is not a vector.
// instead each vertex is simply the 3 values in order.
point.x = (float)GetConvexHullPoint(j);
point.y = (float)GetConvexHullPoint(j + 1);
point.z = (float)GetConvexHullPoint(j + 2);
vertices[j / 3] = point;
}
// create and save the mesh.
Mesh mesh = new Mesh();
mesh.vertices = vertices;
mesh.triangles = triangles;
// be sure to add it to our meshes array
meshes[i] = mesh;
}
//return the array of meshes so they can be added as convex mesh colliders.
return meshes;
}
/// <summary>
/// Gets the number of convex hulls calcalated
/// </summary>
/// <returns># convex hulls computed</returns>
public int GetConvexHullCount()
{
return GetNumberOfConvexHulls();
}
/// <summary>
/// Checks if the async computation of convex hulls is complete
/// </summary>
/// <returns>true if finished</returns>
public bool IsComputeFinished()
{
return IsReady();
}
/// <summary>
/// Checks to see if each convex hull is under 256 vertices and 256 triangles.
/// </summary>
/// <returns>True if under limits</returns>
public bool IsValid()
{
// calculate max triangle count and max vertex count
int maxTriangleCount = 0;
int maxVertexCount = 0;
int numHulls = GetConvexHullCount();
for (int i = 0; i < numHulls; i++)
{
SetConvexHull(i);
int currentTriCount = GetConvexHullNumTriangles();
int currentVertCount = GetConvexHullNumPoints();
if (currentTriCount > maxTriangleCount)
{
maxTriangleCount = currentTriCount;
}
if (currentVertCount > maxVertexCount)
{
maxVertexCount = currentVertCount;
}
}
// if both are under 256, unity will generate no errors.
// (these errors are hidden in some older versions of unity.)
if (maxVertexCount < 256 && maxTriangleCount < 256)
{
return true;
}
return false;
}
/// <summary>
/// Sets the vertices and triangles array for VHACD from mesh
/// </summary>
/// <param name="meshFilter">mesh filter of the source mesh</param>
/// <param name="attachTo">transform the mesh collider will be attached to</param>
/// <returns>true if preparation succeeds, false otherwise</returns>
public bool PrepareMeshData(MeshFilter meshFilter, Transform attachTo, Mesh mesh)
{
if (mesh == null) return false;
// convert from meshes' object to world space, to attach to's local space, then calculate, then add.
Vector3[] vertices = mesh.vertices;
int[] triangles = mesh.triangles;
List<Vector3> localAttachVertices = new List<Vector3>();
if (meshFilter != null && meshFilter.transform != attachTo && meshFilter.sharedMesh != null && meshFilter.sharedMesh == mesh)
{
foreach (Vector3 v in vertices)
{
// transform from mesh filters local space, to world space, to the attach to's local space.
localAttachVertices.Add(attachTo.transform.InverseTransformPoint(meshFilter.transform.TransformPoint(v)));
}
}
else
{
localAttachVertices = vertices.ToList();
}
// could have used an intptr but this way is fast enough
// and we can let VHACD take care of itself.
SetPointSize(localAttachVertices.Count * 3);
SetTriangleSize(triangles.Length);
for (int i = 0; i < localAttachVertices.Count; i++)
{
SetPoint(i * 3, localAttachVertices[i].x);
SetPoint(i * 3 + 1, localAttachVertices[i].y);
SetPoint(i * 3 + 2, localAttachVertices[i].z);
}
for (int i = 0; i < triangles.Length; i++)
{
SetTriangle(i, triangles[i]);
}
return true;
}
/// <summary>
/// prepares an array of meshfilters for a single convex hull decomposition.
/// </summary>
/// <param name="meshFilters">array of meshfilters</param>
public bool PrepareMeshData(List<MeshFilter> meshFilters, Transform attachTo)
{
// convert vertices from the mesh filters local space, to world space, to the attach to's local space.
int vertexCount = 0;
int triangleCount = 0;
List<Vector3> localAttachVertices = new List<Vector3>();
List<int> triangles = new List<int>();
foreach (MeshFilter mf in meshFilters)
{
// skip any mesh filters that were deleted, or had their shared mesh changed to null
if (mf == null || mf.sharedMesh == null) continue;
// convert to local vertices of the attach to object.
Vector3[] verts = mf.sharedMesh.vertices;
foreach (Vector3 v in verts)
{
localAttachVertices.Add(attachTo.transform.InverseTransformPoint(mf.transform.TransformPoint(v)));
}
// get current shared mesh triangles
int[] tris = mf.sharedMesh.triangles;
for (int i = 0; i < tris.Length; i++)
{
// add the vertex index, plus the offset of the total running vertex count.
triangles.Add(tris[i] + vertexCount);
}
vertexCount += mf.sharedMesh.vertices.Length;
triangleCount += mf.sharedMesh.triangles.Length;
}
// could have used intptr etc. to pass all the data at once
// but this way is still fast enough, and we can just let VHACD handle it's own stuff.
SetPointSize(vertexCount * 3);
SetTriangleSize(triangleCount);
for (int i = 0; i < localAttachVertices.Count; i++)
{
SetPoint(i * 3, localAttachVertices[i].x);
SetPoint(i * 3 + 1, localAttachVertices[i].y);
SetPoint(i * 3 + 2, localAttachVertices[i].z);
}
for (int i = 0; i < triangles.Count; i++)
{
SetTriangle(i, triangles[i]);
}
return true;
}
/// <summary>
/// Recalculates the current convex hulls based on max triangles and vertices with an aim to get max triangles below 256
/// </summary>
/// <returns></returns>
public bool RecomputeVHACD()
{
int maxTriangleCount = 0;
int maxVertexCount = 0;
int numHulls = GetConvexHullCount();
// calculate max triangles and vertices from convex hulls.
for (int i = 0; i < numHulls; i++)
{
SetConvexHull(i);
int currentTriCount = GetConvexHullNumTriangles();
int currentVertCount = GetConvexHullNumPoints();
if (currentTriCount > maxTriangleCount)
{
maxTriangleCount = currentTriCount;
}
if (currentVertCount > maxVertexCount)
{
maxVertexCount = currentVertCount;
}
}
// reduce the max number of vertices.
float trisPerVertMax = (float)maxTriangleCount / maxVertexCount;
int maxVerticesPerConvexHull = (int)(255 / trisPerVertMax);
// set the new max number of vertices
SetMaxVerticesPerHull(maxVerticesPerConvexHull);
// compute again.
Compute();
return true;
}
/// <summary>
/// Calls compute method on the current VHACD instance
/// </summary>
/// <returns></returns>
public bool RunVHACD()
{
Compute();
return true;
}
/// <summary>
/// Sets parameters on the current VHACD instance
/// </summary>
/// <param name="parameters">parameters to set</param>
public bool SetParameters(VHACDParameters parameters)
{
SetParameters(
parameters.concavity,
parameters.alpha,
parameters.beta,
parameters.minVolumePerCH,
parameters.resolution,
parameters.maxNumVerticesPerConvexHull,
parameters.planeDownsampling,
parameters.convexhullDownSampling,
parameters.maxConvexHulls,
parameters.projectHullVertices,
(uint)parameters.fillMode
);
return true;
}
}
/// <summary>
/// Fill mode for VHACD
/// </summary>
public enum VHACD_FILL_MODE
{
FLOOD_FILL,
SURFACE_ONLY,
RAYCAST_FILL,
}
}
#endif
@@ -0,0 +1,20 @@
fileFormatVersion: 2
guid: 492957b54e69e0944a816663cdf414ff
timeCreated: 1591919081
licenseType: Store
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 67880
packageName: Easy Collider Editor
packageVersion: 6.18.1
assetPath: Assets/EasyColliderEditor/Scripts/EasyColliderVHACD.cs
uploadId: 749371
@@ -0,0 +1,60 @@
#if (UNITY_EDITOR)
using System;
using UnityEngine;
namespace ECE
{
/// <summary>
/// A vertex represented by the transform it's attached to and it's local position.
/// </summary>
[System.Serializable]
public class EasyColliderVertex : IEquatable<EasyColliderVertex>
{
/// <summary>
/// Local position of the vertex on the transform.
/// </summary>
public Vector3 LocalPosition;
public Vector3 Normal = Vector3.zero;
/// <summary>
/// Transform the vertex comes from.
/// </summary>
public Transform T;
/// <summary>
/// Create a new Easy Collider Vertex
/// </summary>
/// <param name="transform">Transform the vertex is on</param>
/// <param name="localPosition">Local position of the vertex</param>
public EasyColliderVertex(Transform transform, Vector3 localPosition)
{
this.T = transform;
this.LocalPosition = localPosition;
}
public EasyColliderVertex(EasyColliderVertex ecv)
{
this.T = ecv.T;
this.LocalPosition = ecv.LocalPosition;
}
// since we've used hashsets prior to adding normals, and we calculate smoothed normals
// when things get selected and store the those as the selected vertices,
// various things would have to change to include the normals in the equals and get hash code.
// so for now, we're still just position based.
public bool Equals(EasyColliderVertex other)
{
return (other.LocalPosition == this.LocalPosition && other.T == this.T);// && other.Normal == this.Normal);
}
public override int GetHashCode()
{
int hashCode = 13 * 31 + LocalPosition.GetHashCode();
// hashCode += 17 * this.Normal.GetHashCode();
return hashCode * 31 + T.GetHashCode();
}
}
}
#endif
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 41abfd88235d8c444be04e8d0ddd38b7
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 67880
packageName: Easy Collider Editor
packageVersion: 6.18.1
assetPath: Assets/EasyColliderEditor/Scripts/EasyColliderVertex.cs
uploadId: 749371
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 8aba5803d0eee804792b9405ce7990cf
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 67880
packageName: Easy Collider Editor
packageVersion: 6.18.1
assetPath: Assets/EasyColliderEditor/Scripts/EasyColliderWindow.cs
uploadId: 749371
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: ac9df4839a2693149a285fc07e42c21f
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,39 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace ECE
{
public interface IEasyColliderPostProcessor
{
/// <summary>
/// post processes a box collider, properties orientation indiciates if it's a rotated collider.
/// </summary>
/// <param name="box"></param>
/// <param name="properties"></param>
void PostProcessCollider(BoxCollider boxCollider, EasyColliderProperties properties);
/// <summary>
/// post processes a capsule collider, properties orientation indiciates if it's a rotated collider.
/// </summary>
/// <param name="box"></param>
/// <param name="properties"></param>
void PostProcessCollider(CapsuleCollider capsuleCollider, EasyColliderProperties properties);
/// <summary>
/// post processes a mesh collider. cylinder colliders are mesh colliders as well.
/// </summary>
/// <param name="box"></param>
/// <param name="properties"></param>
void PostProcessCollider(MeshCollider meshCollider, EasyColliderProperties properties);
/// <summary>
/// post processes a sphere collider
/// </summary>
/// <param name="box"></param>
/// <param name="properties"></param>
void PostProcessCollider(SphereCollider sphereCollider, EasyColliderProperties properties);
}
}
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: b6cf4bc0f3d036f46a48313c8a796bed
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 67880
packageName: Easy Collider Editor
packageVersion: 6.18.1
assetPath: Assets/EasyColliderEditor/Scripts/Interfaces/IEasyColliderPostProcessor.cs
uploadId: 749371
@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: a8a38e163b87eb748aebb1b989f8503b
folderAsset: yes
timeCreated: 1591980098
licenseType: Store
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,96 @@
fileFormatVersion: 2
guid: 68a88bb9c40937341bf6536bbe774f0d
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 0
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
: Any
second:
enabled: 0
settings:
Exclude Editor: 0
Exclude Linux: 1
Exclude Linux64: 1
Exclude LinuxUniversal: 1
Exclude OSXUniversal: 1
Exclude Win: 1
Exclude Win64: 1
- first:
Any:
second:
enabled: 0
settings: {}
- first:
Editor: Editor
second:
enabled: 1
settings:
CPU: AnyCPU
DefaultValueInitialized: true
OS: Windows
- first:
Facebook: Win
second:
enabled: 0
settings:
CPU: AnyCPU
- first:
Facebook: Win64
second:
enabled: 0
settings:
CPU: AnyCPU
- first:
Standalone: Linux
second:
enabled: 0
settings:
CPU: x86
- first:
Standalone: Linux64
second:
enabled: 0
settings:
CPU: AnyCPU
- first:
Standalone: LinuxUniversal
second:
enabled: 0
settings:
CPU: None
- first:
Standalone: OSXUniversal
second:
enabled: 0
settings:
CPU: AnyCPU
- first:
Standalone: Win
second:
enabled: 0
settings:
CPU: AnyCPU
- first:
Standalone: Win64
second:
enabled: 0
settings:
CPU: AnyCPU
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 67880
packageName: Easy Collider Editor
packageVersion: 6.18.1
assetPath: Assets/EasyColliderEditor/Scripts/Plugins/ECE_VHACD.dll
uploadId: 749371
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 88f8f3ea0a40624418d9c27ab616b7ea
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,74 @@
fileFormatVersion: 2
guid: a9491b77ec748994585680ed2c3066b5
folderAsset: yes
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 0
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
: Any
second:
enabled: 0
settings:
Exclude Editor: 0
Exclude Linux64: 1
Exclude OSXUniversal: 1
Exclude Win: 1
Exclude Win64: 1
- first:
: OSXIntel
second:
enabled: 1
settings: {}
- first:
: OSXIntel64
second:
enabled: 1
settings: {}
- first:
Any:
second:
enabled: 0
settings: {}
- first:
Editor: Editor
second:
enabled: 1
settings:
CPU: AnyCPU
DefaultValueInitialized: true
OS: OSX
- first:
Standalone: Linux64
second:
enabled: 0
settings:
CPU: None
- first:
Standalone: OSXUniversal
second:
enabled: 0
settings:
CPU: None
- first:
Standalone: Win
second:
enabled: 0
settings:
CPU: None
- first:
Standalone: Win64
second:
enabled: 0
settings:
CPU: None
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 6a8585019d15a9a46bcd1c5a4672a0dc
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,48 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>BuildMachineOSBuild</key>
<string>22G313</string>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>ECE_VHACD</string>
<key>CFBundleIdentifier</key>
<string>com.pmurph0305.vhacd</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>ECE_VHACD</string>
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSupportedPlatforms</key>
<array>
<string>MacOSX</string>
</array>
<key>CFBundleVersion</key>
<string>1</string>
<key>DTCompiler</key>
<string>com.apple.compilers.llvm.clang.1_0</string>
<key>DTPlatformBuild</key>
<string></string>
<key>DTPlatformName</key>
<string>macosx</string>
<key>DTPlatformVersion</key>
<string>14.0</string>
<key>DTSDKBuild</key>
<string>23A334</string>
<key>DTSDKName</key>
<string>macosx14.0</string>
<key>DTXcode</key>
<string>1501</string>
<key>DTXcodeBuild</key>
<string>15A507</string>
<key>LSMinimumSystemVersion</key>
<string>10.14.6</string>
<key>NSHumanReadableCopyright</key>
<string>Patrick Murphy</string>
</dict>
</plist>
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: a0f15c4d5e14a654984875f8b9c256e2
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: f1b2f199639e70343a1ee88ed11361b5
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,159 @@
#pragma once
#ifndef HACD_CIRCULAR_LIST_INL
# define HACD_CIRCULAR_LIST_INL
namespace VHACD
{
template <typename T>
inline bool CircularList<T>::Delete(CircularListElement<T>* element)
{
if (!element)
{
return false;
}
if (m_size > 1)
{
CircularListElement<T>* next = element->GetNext();
CircularListElement<T>* prev = element->GetPrev();
delete element;
m_size--;
if (element == m_head)
{
m_head = next;
}
next->GetPrev() = prev;
prev->GetNext() = next;
return true;
}
else if (m_size == 1)
{
delete m_head;
m_size--;
m_head = 0;
return true;
}
else
{
return false;
}
}
template <typename T>
inline bool CircularList<T>::Delete()
{
if (m_size > 1)
{
CircularListElement<T>* next = m_head->GetNext();
CircularListElement<T>* prev = m_head->GetPrev();
delete m_head;
m_size--;
m_head = next;
next->GetPrev() = prev;
prev->GetNext() = next;
return true;
}
else if (m_size == 1)
{
delete m_head;
m_size--;
m_head = 0;
return true;
}
else
{
return false;
}
}
template <typename T>
inline CircularListElement<T>* CircularList<T>::Add(const T* data)
{
if (m_size == 0)
{
if (data)
{
m_head = new CircularListElement<T>(*data);
}
else
{
m_head = new CircularListElement<T>();
}
m_head->GetNext() = m_head->GetPrev() = m_head;
}
else
{
CircularListElement<T>* next = m_head->GetNext();
CircularListElement<T>* element = m_head;
if (data)
{
m_head = new CircularListElement<T>(*data);
}
else
{
m_head = new CircularListElement<T>();
}
m_head->GetNext() = next;
m_head->GetPrev() = element;
element->GetNext() = m_head;
next->GetPrev() = m_head;
}
m_size++;
return m_head;
}
template <typename T>
inline CircularListElement<T>* CircularList<T>::Add(const T& data)
{
const T* pData = &data;
return Add(pData);
}
template <typename T>
inline bool CircularList<T>::Next()
{
if (m_size == 0)
{
return false;
}
m_head = m_head->GetNext();
return true;
}
template <typename T>
inline bool CircularList<T>::Prev()
{
if (m_size == 0)
{
return false;
}
m_head = m_head->GetPrev();
return true;
}
template <typename T>
inline CircularList<T>::CircularList(const CircularList& rhs)
{
if (rhs.m_size > 0)
{
CircularListElement<T>* current = rhs.m_head;
do
{
current = current->GetNext();
Add(current->GetData());
} while (current != rhs.m_head);
}
}
template <typename T>
inline const CircularList<T>& CircularList<T>::operator=(const CircularList& rhs)
{
if (&rhs != this)
{
Clear();
if (rhs.m_size > 0)
{
CircularListElement<T>* current = rhs.m_head;
do
{
current = current->GetNext();
Add(current->GetData());
} while (current != rhs.m_head);
}
}
return (*this);
}
} // namespace VHACD
#endif
@@ -0,0 +1,375 @@
#pragma once
#ifndef VHACD_VECTOR_INL
# define VHACD_VECTOR_INL
namespace VHACD
{
template <typename T>
inline Vec3<T> operator*(T lhs, const Vec3<T>& rhs)
{
return Vec3<T>(lhs * rhs.X(), lhs * rhs.Y(), lhs * rhs.Z());
}
template <typename T>
inline T& Vec3<T>::X()
{
return m_data[0];
}
template <typename T>
inline T& Vec3<T>::Y()
{
return m_data[1];
}
template <typename T>
inline T& Vec3<T>::Z()
{
return m_data[2];
}
template <typename T>
inline const T& Vec3<T>::X() const
{
return m_data[0];
}
template <typename T>
inline const T& Vec3<T>::Y() const
{
return m_data[1];
}
template <typename T>
inline const T& Vec3<T>::Z() const
{
return m_data[2];
}
template <typename T>
inline T Vec3<T>::Normalize()
{
T n = sqrt(m_data[0] * m_data[0] + m_data[1] * m_data[1] + m_data[2] * m_data[2]);
if (n != 0.0)
(*this) /= n;
return n;
}
template <typename T>
inline T Vec3<T>::GetNorm() const
{
return sqrt(m_data[0] * m_data[0] + m_data[1] * m_data[1] + m_data[2] * m_data[2]);
}
template <typename T>
inline void Vec3<T>::operator=(const Vec3& rhs)
{
this->m_data[0] = rhs.m_data[0];
this->m_data[1] = rhs.m_data[1];
this->m_data[2] = rhs.m_data[2];
}
template <typename T>
inline void Vec3<T>::operator+=(const Vec3& rhs)
{
this->m_data[0] += rhs.m_data[0];
this->m_data[1] += rhs.m_data[1];
this->m_data[2] += rhs.m_data[2];
}
template <typename T>
inline void Vec3<T>::operator-=(const Vec3& rhs)
{
this->m_data[0] -= rhs.m_data[0];
this->m_data[1] -= rhs.m_data[1];
this->m_data[2] -= rhs.m_data[2];
}
template <typename T>
inline void Vec3<T>::operator-=(T a)
{
this->m_data[0] -= a;
this->m_data[1] -= a;
this->m_data[2] -= a;
}
template <typename T>
inline void Vec3<T>::operator+=(T a)
{
this->m_data[0] += a;
this->m_data[1] += a;
this->m_data[2] += a;
}
template <typename T>
inline void Vec3<T>::operator/=(T a)
{
this->m_data[0] /= a;
this->m_data[1] /= a;
this->m_data[2] /= a;
}
template <typename T>
inline void Vec3<T>::operator*=(T a)
{
this->m_data[0] *= a;
this->m_data[1] *= a;
this->m_data[2] *= a;
}
template <typename T>
inline Vec3<T> Vec3<T>::operator^(const Vec3<T>& rhs) const
{
return Vec3<T>(m_data[1] * rhs.m_data[2] - m_data[2] * rhs.m_data[1],
m_data[2] * rhs.m_data[0] - m_data[0] * rhs.m_data[2],
m_data[0] * rhs.m_data[1] - m_data[1] * rhs.m_data[0]);
}
template <typename T>
inline T Vec3<T>::operator*(const Vec3<T>& rhs) const
{
return (m_data[0] * rhs.m_data[0] + m_data[1] * rhs.m_data[1] + m_data[2] * rhs.m_data[2]);
}
template <typename T>
inline Vec3<T> Vec3<T>::operator+(const Vec3<T>& rhs) const
{
return Vec3<T>(m_data[0] + rhs.m_data[0], m_data[1] + rhs.m_data[1], m_data[2] + rhs.m_data[2]);
}
template <typename T>
inline Vec3<T> Vec3<T>::operator-(const Vec3<T>& rhs) const
{
return Vec3<T>(m_data[0] - rhs.m_data[0], m_data[1] - rhs.m_data[1], m_data[2] - rhs.m_data[2]);
}
template <typename T>
inline Vec3<T> Vec3<T>::operator-() const
{
return Vec3<T>(-m_data[0], -m_data[1], -m_data[2]);
}
template <typename T>
inline Vec3<T> Vec3<T>::operator*(T rhs) const
{
return Vec3<T>(rhs * this->m_data[0], rhs * this->m_data[1], rhs * this->m_data[2]);
}
template <typename T>
inline Vec3<T> Vec3<T>::operator/(T rhs) const
{
return Vec3<T>(m_data[0] / rhs, m_data[1] / rhs, m_data[2] / rhs);
}
template <typename T>
inline Vec3<T>::Vec3(T a)
{
m_data[0] = m_data[1] = m_data[2] = a;
}
template <typename T>
inline Vec3<T>::Vec3(T x, T y, T z)
{
m_data[0] = x;
m_data[1] = y;
m_data[2] = z;
}
template <typename T>
inline Vec3<T>::Vec3(const Vec3& rhs)
{
m_data[0] = rhs.m_data[0];
m_data[1] = rhs.m_data[1];
m_data[2] = rhs.m_data[2];
}
template <typename T>
inline Vec3<T>::~Vec3(void){};
template <typename T>
inline Vec3<T>::Vec3()
{
}
template <typename T>
inline const bool Colinear(const Vec3<T>& a, const Vec3<T>& b, const Vec3<T>& c)
{
return ((c.Z() - a.Z()) * (b.Y() - a.Y()) - (b.Z() - a.Z()) * (c.Y() - a.Y()) == 0.0 /*EPS*/) &&
((b.Z() - a.Z()) * (c.X() - a.X()) - (b.X() - a.X()) * (c.Z() - a.Z()) == 0.0 /*EPS*/) &&
((b.X() - a.X()) * (c.Y() - a.Y()) - (b.Y() - a.Y()) * (c.X() - a.X()) == 0.0 /*EPS*/);
}
template <typename T>
inline const T ComputeVolume4(const Vec3<T>& a, const Vec3<T>& b, const Vec3<T>& c, const Vec3<T>& d)
{
return (a - d) * ((b - d) ^ (c - d));
}
template <typename T>
inline bool Vec3<T>::operator<(const Vec3& rhs) const
{
if (X() == rhs[0])
{
if (Y() == rhs[1])
{
return (Z() < rhs[2]);
}
return (Y() < rhs[1]);
}
return (X() < rhs[0]);
}
template <typename T>
inline bool Vec3<T>::operator>(const Vec3& rhs) const
{
if (X() == rhs[0])
{
if (Y() == rhs[1])
{
return (Z() > rhs[2]);
}
return (Y() > rhs[1]);
}
return (X() > rhs[0]);
}
template <typename T>
inline Vec2<T> operator*(T lhs, const Vec2<T>& rhs)
{
return Vec2<T>(lhs * rhs.X(), lhs * rhs.Y());
}
template <typename T>
inline T& Vec2<T>::X()
{
return m_data[0];
}
template <typename T>
inline T& Vec2<T>::Y()
{
return m_data[1];
}
template <typename T>
inline const T& Vec2<T>::X() const
{
return m_data[0];
}
template <typename T>
inline const T& Vec2<T>::Y() const
{
return m_data[1];
}
template <typename T>
inline void Vec2<T>::Normalize()
{
T n = sqrt(m_data[0] * m_data[0] + m_data[1] * m_data[1]);
if (n != 0.0)
(*this) /= n;
}
template <typename T>
inline T Vec2<T>::GetNorm() const
{
return sqrt(m_data[0] * m_data[0] + m_data[1] * m_data[1]);
}
template <typename T>
inline void Vec2<T>::operator=(const Vec2& rhs)
{
this->m_data[0] = rhs.m_data[0];
this->m_data[1] = rhs.m_data[1];
}
template <typename T>
inline void Vec2<T>::operator+=(const Vec2& rhs)
{
this->m_data[0] += rhs.m_data[0];
this->m_data[1] += rhs.m_data[1];
}
template <typename T>
inline void Vec2<T>::operator-=(const Vec2& rhs)
{
this->m_data[0] -= rhs.m_data[0];
this->m_data[1] -= rhs.m_data[1];
}
template <typename T>
inline void Vec2<T>::operator-=(T a)
{
this->m_data[0] -= a;
this->m_data[1] -= a;
}
template <typename T>
inline void Vec2<T>::operator+=(T a)
{
this->m_data[0] += a;
this->m_data[1] += a;
}
template <typename T>
inline void Vec2<T>::operator/=(T a)
{
this->m_data[0] /= a;
this->m_data[1] /= a;
}
template <typename T>
inline void Vec2<T>::operator*=(T a)
{
this->m_data[0] *= a;
this->m_data[1] *= a;
}
template <typename T>
inline T Vec2<T>::operator^(const Vec2<T>& rhs) const
{
return m_data[0] * rhs.m_data[1] - m_data[1] * rhs.m_data[0];
}
template <typename T>
inline T Vec2<T>::operator*(const Vec2<T>& rhs) const
{
return (m_data[0] * rhs.m_data[0] + m_data[1] * rhs.m_data[1]);
}
template <typename T>
inline Vec2<T> Vec2<T>::operator+(const Vec2<T>& rhs) const
{
return Vec2<T>(m_data[0] + rhs.m_data[0], m_data[1] + rhs.m_data[1]);
}
template <typename T>
inline Vec2<T> Vec2<T>::operator-(const Vec2<T>& rhs) const
{
return Vec2<T>(m_data[0] - rhs.m_data[0], m_data[1] - rhs.m_data[1]);
}
template <typename T>
inline Vec2<T> Vec2<T>::operator-() const
{
return Vec2<T>(-m_data[0], -m_data[1]);
}
template <typename T>
inline Vec2<T> Vec2<T>::operator*(T rhs) const
{
return Vec2<T>(rhs * this->m_data[0], rhs * this->m_data[1]);
}
template <typename T>
inline Vec2<T> Vec2<T>::operator/(T rhs) const
{
return Vec2<T>(m_data[0] / rhs, m_data[1] / rhs);
}
template <typename T>
inline Vec2<T>::Vec2(T a)
{
m_data[0] = m_data[1] = a;
}
template <typename T>
inline Vec2<T>::Vec2(T x, T y)
{
m_data[0] = x;
m_data[1] = y;
}
template <typename T>
inline Vec2<T>::Vec2(const Vec2& rhs)
{
m_data[0] = rhs.m_data[0];
m_data[1] = rhs.m_data[1];
}
template <typename T>
inline Vec2<T>::~Vec2(void){};
template <typename T>
inline Vec2<T>::Vec2()
{
}
/*
InsideTriangle decides if a point P is Inside of the triangle
defined by A, B, C.
*/
template <typename T>
inline const bool InsideTriangle(const Vec2<T>& a, const Vec2<T>& b, const Vec2<T>& c, const Vec2<T>& p)
{
T ax, ay, bx, by, cx, cy, apx, apy, bpx, bpy, cpx, cpy;
T cCROSSap, bCROSScp, aCROSSbp;
ax = c.X() - b.X();
ay = c.Y() - b.Y();
bx = a.X() - c.X();
by = a.Y() - c.Y();
cx = b.X() - a.X();
cy = b.Y() - a.Y();
apx = p.X() - a.X();
apy = p.Y() - a.Y();
bpx = p.X() - b.X();
bpy = p.Y() - b.Y();
cpx = p.X() - c.X();
cpy = p.Y() - c.Y();
aCROSSbp = ax * bpy - ay * bpx;
cCROSSap = cx * apy - cy * apx;
bCROSScp = bx * cpy - by * cpx;
return ((aCROSSbp >= 0.0) && (bCROSScp >= 0.0) && (cCROSSap >= 0.0));
}
} // namespace VHACD
#endif // VHACD_VECTOR_INL
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 053bcd82e5178b84f92ae9aad65047d0
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,150 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>files</key>
<dict>
<key>Resources/FloatMath.inl</key>
<data>
FQ02laH8m+/JTJ+xcwqF4fWRY4w=
</data>
<key>Resources/vhacdCircularList.inl</key>
<data>
bg5DMaZXXwN+gpc16iPOfKbGOD4=
</data>
<key>Resources/vhacdVector.inl</key>
<data>
LRgKZE2bbNoNlvmVBByTASOiAlI=
</data>
</dict>
<key>files2</key>
<dict>
<key>Resources/FloatMath.inl</key>
<dict>
<key>hash2</key>
<data>
7c/f0AfVvxJKCxxwRLRSiPEGbmEje0PvDdrLJebRkXU=
</data>
</dict>
<key>Resources/vhacdCircularList.inl</key>
<dict>
<key>hash2</key>
<data>
WmykxJuTQfrpkVu/j2zvrquydZ+YDyad4TWxrxQgeIE=
</data>
</dict>
<key>Resources/vhacdVector.inl</key>
<dict>
<key>hash2</key>
<data>
s1ji9RXyq8hW10f7880Nngs65lwHqd3pgFjjovRn1mM=
</data>
</dict>
</dict>
<key>rules</key>
<dict>
<key>^Resources/</key>
<true/>
<key>^Resources/.*\.lproj/</key>
<dict>
<key>optional</key>
<true/>
<key>weight</key>
<real>1000</real>
</dict>
<key>^Resources/.*\.lproj/locversion.plist$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>1100</real>
</dict>
<key>^Resources/Base\.lproj/</key>
<dict>
<key>weight</key>
<real>1010</real>
</dict>
<key>^version.plist$</key>
<true/>
</dict>
<key>rules2</key>
<dict>
<key>.*\.dSYM($|/)</key>
<dict>
<key>weight</key>
<real>11</real>
</dict>
<key>^(.*/)?\.DS_Store$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>2000</real>
</dict>
<key>^(Frameworks|SharedFrameworks|PlugIns|Plug-ins|XPCServices|Helpers|MacOS|Library/(Automator|Spotlight|LoginItems))/</key>
<dict>
<key>nested</key>
<true/>
<key>weight</key>
<real>10</real>
</dict>
<key>^.*</key>
<true/>
<key>^Info\.plist$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>20</real>
</dict>
<key>^PkgInfo$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>20</real>
</dict>
<key>^Resources/</key>
<dict>
<key>weight</key>
<real>20</real>
</dict>
<key>^Resources/.*\.lproj/</key>
<dict>
<key>optional</key>
<true/>
<key>weight</key>
<real>1000</real>
</dict>
<key>^Resources/.*\.lproj/locversion.plist$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>1100</real>
</dict>
<key>^Resources/Base\.lproj/</key>
<dict>
<key>weight</key>
<real>1010</real>
</dict>
<key>^[^/]+$</key>
<dict>
<key>nested</key>
<true/>
<key>weight</key>
<real>10</real>
</dict>
<key>^embedded\.provisionprofile$</key>
<dict>
<key>weight</key>
<real>20</real>
</dict>
<key>^version\.plist$</key>
<dict>
<key>weight</key>
<real>20</real>
</dict>
</dict>
</dict>
</plist>
@@ -0,0 +1,29 @@
BSD 3-Clause License
Copyright (c) 2011, Khaled Mamou (kmamou at gmail dot com)
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,16 @@
fileFormatVersion: 2
guid: 0a79fff97a7a7294b835aea10e1cb6cf
timeCreated: 1596043168
licenseType: Store
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 67880
packageName: Easy Collider Editor
packageVersion: 6.18.1
assetPath: Assets/EasyColliderEditor/Scripts/Plugins/VHACDLicense.txt
uploadId: 749371
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: e07e2f113dc48584a95e5460e745c076
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

Some files were not shown because too many files have changed in this diff Show More