浏览代码

Twas the night before Poly Brush, and all was quiet and safe. No errors in the console, least till the packages awake.

Also saving before I upgrade Shader Graph
/main
John-O-Really 6 年前
当前提交
18f9cdc5
共有 579 个文件被更改,包括 7919 次插入153 次删除
  1. 6
      Assets/IslandScene/Water/Material_IslandWater.mat
  2. 538
      Assets/IslandScene/Water/Shader_IslandWater.ShaderGraph
  3. 2
      ProjectSettings/ProjectVersion.txt
  4. 8
      Assets/IslandScene/Fish/Materials.meta
  5. 8
      Assets/IslandScene/Fish/TropicalFish03.fbm.meta
  6. 8
      Assets/ProCore.meta
  7. 76
      Assets/IslandScene/Fish/Materials/TropicalFish03-02 - Default.mat
  8. 8
      Assets/IslandScene/Fish/Materials/TropicalFish03-02 - Default.mat.meta
  9. 602
      Assets/IslandScene/Fish/TropicalFish03.fbm/TropicalFish02.jpg
  10. 132
      Assets/IslandScene/Fish/TropicalFish03.fbm/TropicalFish02.jpg.meta
  11. 9
      Assets/ProCore/Polybrush.meta
  12. 8
      Assets/ProCore/Polybrush/Brush Settings.meta
  13. 43
      Assets/ProCore/Polybrush/Brush Settings/Default.asset
  14. 8
      Assets/ProCore/Polybrush/Brush Settings/Default.asset.meta
  15. 9
      Assets/ProCore/Polybrush/Code.meta
  16. 9
      Assets/ProCore/Polybrush/Code/Editor.meta
  17. 9
      Assets/ProCore/Polybrush/Code/Editor/Brush Modes.meta
  18. 206
      Assets/ProCore/Polybrush/Code/Editor/Brush Modes/z_BrushMode.cs
  19. 12
      Assets/ProCore/Polybrush/Code/Editor/Brush Modes/z_BrushMode.cs.meta
  20. 94
      Assets/ProCore/Polybrush/Code/Editor/Brush Modes/z_BrushModeMesh.cs
  21. 12
      Assets/ProCore/Polybrush/Code/Editor/Brush Modes/z_BrushModeMesh.cs.meta
  22. 393
      Assets/ProCore/Polybrush/Code/Editor/Brush Modes/z_BrushModePaint.cs
  23. 12
      Assets/ProCore/Polybrush/Code/Editor/Brush Modes/z_BrushModePaint.cs.meta
  24. 434
      Assets/ProCore/Polybrush/Code/Editor/Brush Modes/z_BrushModePrefab.cs
  25. 12
      Assets/ProCore/Polybrush/Code/Editor/Brush Modes/z_BrushModePrefab.cs.meta
  26. 123
      Assets/ProCore/Polybrush/Code/Editor/Brush Modes/z_BrushModeRaiseLower.cs
  27. 12
      Assets/ProCore/Polybrush/Code/Editor/Brush Modes/z_BrushModeRaiseLower.cs.meta
  28. 129
      Assets/ProCore/Polybrush/Code/Editor/Brush Modes/z_BrushModeSculpt.cs
  29. 12
      Assets/ProCore/Polybrush/Code/Editor/Brush Modes/z_BrushModeSculpt.cs.meta
  30. 115
      Assets/ProCore/Polybrush/Code/Editor/Brush Modes/z_BrushModeSmooth.cs
  31. 12
      Assets/ProCore/Polybrush/Code/Editor/Brush Modes/z_BrushModeSmooth.cs.meta
  32. 422
      Assets/ProCore/Polybrush/Code/Editor/Brush Modes/z_BrushModeTexture.cs
  33. 12
      Assets/ProCore/Polybrush/Code/Editor/Brush Modes/z_BrushModeTexture.cs.meta
  34. 9
      Assets/ProCore/Polybrush/Code/Editor/Classes.meta
  35. 134
      Assets/ProCore/Polybrush/Code/Editor/Classes/z_BrushSettings.cs
  36. 12
      Assets/ProCore/Polybrush/Code/Editor/Classes/z_BrushSettings.cs.meta
  37. 100
      Assets/ProCore/Polybrush/Code/Editor/Classes/z_BrushTarget.cs
  38. 12
      Assets/ProCore/Polybrush/Code/Editor/Classes/z_BrushTarget.cs.meta
  39. 47
      Assets/ProCore/Polybrush/Code/Editor/Classes/z_ColorPalette.cs
  40. 12
      Assets/ProCore/Polybrush/Code/Editor/Classes/z_ColorPalette.cs.meta
  41. 4
      Assets/ProCore/Polybrush/Code/Editor/Classes/z_Delegate.cs
  42. 12
      Assets/ProCore/Polybrush/Code/Editor/Classes/z_Delegate.cs.meta
  43. 507
      Assets/ProCore/Polybrush/Code/Editor/Classes/z_EditableObject.cs
  44. 12
      Assets/ProCore/Polybrush/Code/Editor/Classes/z_EditableObject.cs.meta
  45. 66
      Assets/ProCore/Polybrush/Code/Editor/Classes/z_LocalPref.cs
  46. 12
      Assets/ProCore/Polybrush/Code/Editor/Classes/z_LocalPref.cs.meta
  47. 30
      Assets/ProCore/Polybrush/Code/Editor/Classes/z_PrefabAndSettings.cs
  48. 12
      Assets/ProCore/Polybrush/Code/Editor/Classes/z_PrefabAndSettings.cs.meta
  49. 20
      Assets/ProCore/Polybrush/Code/Editor/Classes/z_PrefabPalette.cs
  50. 12
      Assets/ProCore/Polybrush/Code/Editor/Classes/z_PrefabPalette.cs.meta
  51. 220
      Assets/ProCore/Polybrush/Code/Editor/Classes/z_PreferenceDictionary.cs
  52. 12
      Assets/ProCore/Polybrush/Code/Editor/Classes/z_PreferenceDictionary.cs.meta
  53. 77
      Assets/ProCore/Polybrush/Code/Editor/Classes/z_RaycastHit.cs
  54. 12
      Assets/ProCore/Polybrush/Code/Editor/Classes/z_RaycastHit.cs.meta
  55. 437
      Assets/ProCore/Polybrush/Code/Editor/Classes/z_ReflectionUtil.cs
  56. 12
      Assets/ProCore/Polybrush/Code/Editor/Classes/z_ReflectionUtil.cs.meta
  57. 9
      Assets/ProCore/Polybrush/Code/Editor/Enum.meta
  58. 42
      Assets/ProCore/Polybrush/Code/Editor/Enum/z_BrushTool.cs
  59. 12
      Assets/ProCore/Polybrush/Code/Editor/Enum/z_BrushTool.cs.meta
  60. 9
      Assets/ProCore/Polybrush/Code/Editor/Interface.meta
  61. 80
      Assets/ProCore/Polybrush/Code/Editor/Interface/z_About.cs
  62. 12
      Assets/ProCore/Polybrush/Code/Editor/Interface/z_About.cs.meta
  63. 49
      Assets/ProCore/Polybrush/Code/Editor/Interface/z_AdditionalVertexStreamsEditor.cs
  64. 12
      Assets/ProCore/Polybrush/Code/Editor/Interface/z_AdditionalVertexStreamsEditor.cs.meta
  65. 76
      Assets/ProCore/Polybrush/Code/Editor/Interface/z_AttributeLayoutContainerEditor.cs
  66. 12
      Assets/ProCore/Polybrush/Code/Editor/Interface/z_AttributeLayoutContainerEditor.cs.meta
  67. 148
      Assets/ProCore/Polybrush/Code/Editor/Interface/z_AttributeLayoutJsonEditor.cs
  68. 12
      Assets/ProCore/Polybrush/Code/Editor/Interface/z_AttributeLayoutJsonEditor.cs.meta
  69. 52
      Assets/ProCore/Polybrush/Code/Editor/Interface/z_BlendMaterialInspector.cs
  70. 12
      Assets/ProCore/Polybrush/Code/Editor/Interface/z_BlendMaterialInspector.cs.meta
  71. 197
      Assets/ProCore/Polybrush/Code/Editor/Interface/z_BrushSettingsEditor.cs
  72. 12
      Assets/ProCore/Polybrush/Code/Editor/Interface/z_BrushSettingsEditor.cs.meta
  73. 366
      Assets/ProCore/Polybrush/Code/Editor/Interface/z_ColorPaletteEditor.cs
  74. 12
      Assets/ProCore/Polybrush/Code/Editor/Interface/z_ColorPaletteEditor.cs.meta
  75. 1001
      Assets/ProCore/Polybrush/Code/Editor/Interface/z_Editor.cs
  76. 12
      Assets/ProCore/Polybrush/Code/Editor/Interface/z_Editor.cs.meta
  77. 113
      Assets/ProCore/Polybrush/Code/Editor/Interface/z_GlobalSettingsEditor.cs
  78. 12
      Assets/ProCore/Polybrush/Code/Editor/Interface/z_GlobalSettingsEditor.cs.meta
  79. 38
      Assets/ProCore/Polybrush/Code/Editor/Interface/z_MeshFilterEditor.cs
  80. 12
      Assets/ProCore/Polybrush/Code/Editor/Interface/z_MeshFilterEditor.cs.meta
  81. 207
      Assets/ProCore/Polybrush/Code/Editor/Interface/z_PrefabPaletteEditor.cs
  82. 12
      Assets/ProCore/Polybrush/Code/Editor/Interface/z_PrefabPaletteEditor.cs.meta
  83. 125
      Assets/ProCore/Polybrush/Code/Editor/Interface/z_PreferenceDictionaryEditor.cs
  84. 12
      Assets/ProCore/Polybrush/Code/Editor/Interface/z_PreferenceDictionaryEditor.cs.meta
  85. 34
      Assets/ProCore/Polybrush/Code/Editor/Interface/z_SplatWeightEditor.cs
  86. 12
      Assets/ProCore/Polybrush/Code/Editor/Interface/z_SplatWeightEditor.cs.meta
  87. 59
      Assets/ProCore/Polybrush/Code/Editor/Interface/z_ZoomOverrideEditor.cs
  88. 12
      Assets/ProCore/Polybrush/Code/Editor/Interface/z_ZoomOverrideEditor.cs.meta
  89. 9
      Assets/ProCore/Polybrush/Code/Editor/Utility.meta

6
Assets/IslandScene/Water/Material_IslandWater.mat


- Vector1_137DC7ED: 0
- Vector1_1C76134F: 0.39
- Vector1_2067D572: 0.5
- Vector1_213C6A32: 2.65
- Vector1_221E0A39: 0.97
- Vector1_3170A691: 0.663
- Vector1_361B5521: 5.2

- Vector1_503C980E: 0.406
- Vector1_5685904E: 1.464
- Vector1_5721F4C2: 0.63
- Vector1_5D17CBA2: 0.3

- Vector1_6EF52C6: 1.98
- Vector1_72F0D5FC: 0.013
- Vector1_730BBE62: 0.799
- Vector1_770B5A60: 1.67
- Vector1_7FD4B9D0: 1

- Vector1_F68B8AAF: 1
- Vector1_F8EFDF11: 17.82
- Vector1_F9DF03AF: 35
- Vector1_FA3225CB: 4.99
- Vector1_FF940B40: 1
- _AlphaClip: 0
- _Blend: 0
- _BumpScale: 1

538
Assets/IslandScene/Water/Shader_IslandWater.ShaderGraph
文件差异内容过多而无法显示
查看文件

2
ProjectSettings/ProjectVersion.txt


m_EditorVersion: 2018.2.4f1
m_EditorVersion: 2018.2.8f1

8
Assets/IslandScene/Fish/Materials.meta


fileFormatVersion: 2
guid: 8bc88451f67a54a48ae59b0f048b8702
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

8
Assets/IslandScene/Fish/TropicalFish03.fbm.meta


fileFormatVersion: 2
guid: 3174d514c25b94a4f905d43660eb20fb
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

8
Assets/ProCore.meta


fileFormatVersion: 2
guid: 1610a8ff9609c5641861aeea9edbc5d4
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

76
Assets/IslandScene/Fish/Materials/TropicalFish03-02 - Default.mat


%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!21 &2100000
Material:
serializedVersion: 6
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_Name: TropicalFish03-02 - Default
m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0}
m_ShaderKeywords:
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
- _BumpMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailAlbedoMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailMask:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailNormalMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _EmissionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MainTex:
m_Texture: {fileID: 2800000, guid: 9a919a681b93f5f4d9dc8bc8d1528285, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MetallicGlossMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _OcclusionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _ParallaxMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Floats:
- _BumpScale: 1
- _Cutoff: 0.5
- _DetailNormalMapScale: 1
- _DstBlend: 0
- _GlossMapScale: 1
- _Glossiness: 0
- _GlossyReflections: 1
- _Metallic: 0
- _Mode: 0
- _OcclusionStrength: 1
- _Parallax: 0.02
- _SmoothnessTextureChannel: 0
- _SpecularHighlights: 1
- _SrcBlend: 1
- _UVSec: 0
- _ZWrite: 1
m_Colors:
- _Color: {r: 0.5882353, g: 0.5882353, b: 0.5882353, a: 1}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 0}

8
Assets/IslandScene/Fish/Materials/TropicalFish03-02 - Default.mat.meta


fileFormatVersion: 2
guid: 5da75daabe504794eabf02a8eef7740a
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 2100000
userData:
assetBundleName:
assetBundleVariant:

602
Assets/IslandScene/Fish/TropicalFish03.fbm/TropicalFish02.jpg
文件差异内容过多而无法显示
查看文件

132
Assets/IslandScene/Fish/TropicalFish03.fbm/TropicalFish02.jpg.meta


fileFormatVersion: 2
guid: 9a919a681b93f5f4d9dc8bc8d1528285
TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 7
mipmaps:
mipMapMode: 0
enableMipMap: 1
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: -1
aniso: 2
mipBias: -100
wrapU: 0
wrapV: 0
wrapW: 0
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 0
textureShape: 1
singleChannelComponent: 0
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
platformSettings:
- serializedVersion: 2
buildTarget: DefaultTexturePlatform
maxTextureSize: 8192
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
- serializedVersion: 2
buildTarget: Standalone
maxTextureSize: 8192
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
- serializedVersion: 2
buildTarget: iPhone
maxTextureSize: 4096
resizeAlgorithm: 0
textureFormat: 32
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 1
androidETC2FallbackOverride: 0
- serializedVersion: 2
buildTarget: Android
maxTextureSize: 4096
resizeAlgorithm: 0
textureFormat: 34
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 1
androidETC2FallbackOverride: 0
- serializedVersion: 2
buildTarget: Windows Store Apps
maxTextureSize: 8192
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID:
vertices: []
indices:
edges: []
weights: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:

9
Assets/ProCore/Polybrush.meta


fileFormatVersion: 2
guid: e88df36e2b19b854eb1458fd08552791
folderAsset: yes
timeCreated: 1444938565
licenseType: Store
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

8
Assets/ProCore/Polybrush/Brush Settings.meta


fileFormatVersion: 2
guid: c3e11b7f11f9c9a4b9d67a4ac473779e
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

43
Assets/ProCore/Polybrush/Brush Settings/Default.asset


%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 0c229c73eab51b9478029375e5ca314a, type: 3}
m_Name: Default
m_EditorClassIdentifier:
brushRadiusMin: 0.001
brushRadiusMax: 5
_radius: 1
_falloff: 0.5
_strength: 1
_curve:
serializedVersion: 2
m_Curve:
- serializedVersion: 3
time: 0
value: 1
inSlope: 0
outSlope: 0
tangentMode: 0
weightedMode: 0
inWeight: 0
outWeight: 0
- serializedVersion: 3
time: 1
value: 0
inSlope: -3
outSlope: -3
tangentMode: 0
weightedMode: 0
inWeight: 0
outWeight: 0
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
allowNonNormalizedFalloff: 0

8
Assets/ProCore/Polybrush/Brush Settings/Default.asset.meta


fileFormatVersion: 2
guid: 371c9f00ac06ade40bc1547283173ae0
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:

9
Assets/ProCore/Polybrush/Code.meta


fileFormatVersion: 2
guid: c173ce858118bfd4cad923b0608a888b
folderAsset: yes
timeCreated: 1444938570
licenseType: Store
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

9
Assets/ProCore/Polybrush/Code/Editor.meta


fileFormatVersion: 2
guid: 7416ccb9a80991e4fb5678884b5098d2
folderAsset: yes
timeCreated: 1444938577
licenseType: Store
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

9
Assets/ProCore/Polybrush/Code/Editor/Brush Modes.meta


fileFormatVersion: 2
guid: b408c10689a2f164fa20aaf168c0872f
folderAsset: yes
timeCreated: 1447947185
licenseType: Store
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

206
Assets/ProCore/Polybrush/Code/Editor/Brush Modes/z_BrushMode.cs


// #define Z_DEBUG
using UnityEngine;
using UnityEditor;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
namespace Polybrush
{
/**
* Base class for brush modes.
*/
[System.Serializable]
public abstract class z_BrushMode : ScriptableObject
{
// The message that will accompany Undo commands for this brush. Undo/Redo is handled by z_Editor.
public virtual string UndoMessage { get { return "Apply Brush"; } }
// A temporary component attached to the currently editing object. Use this to (by default) override the
// scene zoom functionality, or optionally extend (see z_OverlayRenderer).
[SerializeField] protected z_ZoomOverride tempComponent;
// The title to be displayed in the settings header.
protected abstract string ModeSettingsHeader { get; }
// The link to the documentation page for this mode.
protected abstract string DocsLink { get; }
protected Color innerColor, outerColor;
protected virtual void CreateTempComponent(z_EditableObject target, z_BrushSettings settings)
{
if(!z_Util.IsValid(target))
return;
tempComponent = target.gameObject.AddComponent<z_ZoomOverride>();
tempComponent.hideFlags = HideFlags.HideAndDontSave;
tempComponent.SetWeights(null, 0f);
}
protected virtual void UpdateTempComponent(z_BrushTarget target, z_BrushSettings settings)
{
if(!z_Util.IsValid(target))
return;
tempComponent.SetWeights(target.GetAllWeights(), settings.strength);
}
protected virtual void DestroyTempComponent()
{
if(tempComponent != null)
GameObject.DestroyImmediate(tempComponent);
}
// Called on instantiation. Base implementation sets HideFlags.
public virtual void OnEnable()
{
this.hideFlags = HideFlags.HideAndDontSave;
innerColor = z_Pref.GetColor(z_Pref.brushColor);
outerColor = z_Pref.GetGradient(z_Pref.brushGradient).Evaluate(1f);
innerColor.a = .9f;
outerColor.a = .35f;
}
// Called when mode is disabled.
public virtual void OnDisable()
{
DestroyTempComponent();
}
// Called by z_Editor when brush settings have been modified.
public virtual void OnBrushSettingsChanged(z_BrushTarget target, z_BrushSettings settings)
{
UpdateTempComponent(target, settings);
}
// Inspector GUI shown in the Editor window.
public virtual void DrawGUI(z_BrushSettings brushSettings)
{
if( z_GUILayout.HeaderWithDocsLink( z_GUI.TempContent(ModeSettingsHeader, "")) )
Application.OpenURL(DocsLink);
}
// Called when the mouse begins hovering an editable object.
public virtual void OnBrushEnter(z_EditableObject target, z_BrushSettings settings)
{
if(z_Pref.GetBool(z_Pref.hideWireframe) && target.renderer != null)
{
// disable wirefame
z_EditorUtility.SetSelectionRenderState(target.renderer, z_EditorUtility.GetSelectionRenderState() & z_SelectionRenderState.Outline);
}
CreateTempComponent(target, settings);
}
// Called whenever the brush is moved. Note that @target may have a null editableObject.
public virtual void OnBrushMove(z_BrushTarget target, z_BrushSettings settings)
{
UpdateTempComponent(target, settings);
}
// Called when the mouse exits hovering an editable object.
public virtual void OnBrushExit(z_EditableObject target)
{
if(target.renderer != null)
z_EditorUtility.SetSelectionRenderState(target.renderer, z_EditorUtility.GetSelectionRenderState());
DestroyTempComponent();
}
// Called when the mouse begins a drag across a valid target.
public virtual void OnBrushBeginApply(z_BrushTarget target, z_BrushSettings settings) {}
// Called every time the brush should apply itself to a valid target. Default is on mouse move.
public abstract void OnBrushApply(z_BrushTarget target, z_BrushSettings settings);
// Called when a brush application has finished. Use this to clean up temporary resources or apply
// deferred actions to a mesh (rebuild UV2, tangents, whatever).
public virtual void OnBrushFinishApply(z_BrushTarget target, z_BrushSettings settings)
{
DestroyTempComponent();
}
// Draw scene gizmos. Base implementation draws the brush preview.
public virtual void DrawGizmos(z_BrushTarget target, z_BrushSettings settings)
{
foreach(z_RaycastHit hit in target.raycastHits)
z_Handles.DrawBrush(hit.position, hit.normal, settings, target.localToWorldMatrix, innerColor, outerColor);
#if Z_DEBUG
#if Z_DRAW_WEIGHTS || DRAW_PER_VERTEX_ATTRIBUTES
float[] w = target.GetAllWeights();
#endif
#if Z_DRAW_WEIGHTS
Mesh m = target.mesh;
Vector3[] v = m.vertices;
GUIContent content = new GUIContent("","");
Handles.BeginGUI();
for(int i = 0; i < v.Length; i++)
{
if(w[i] < .0001f)
continue;
content.text = w[i].ToString("F2");
GUI.Label(HandleUtility.WorldPointToSizedRect(target.transform.TransformPoint(v[i]), content, EditorStyles.label), content);
}
Handles.EndGUI();
#endif
#if DRAW_PER_VERTEX_ATTRIBUTES
z_Mesh m = target.editableObject.editMesh;
Color32[] colors = m.colors;
Vector4[] tangents = m.tangents;
List<Vector4> uv0 = m.uv0;
List<Vector4> uv1 = m.uv1;
List<Vector4> uv2 = m.uv2;
List<Vector4> uv3 = m.uv3;
int vertexCount = m.vertexCount;
Vector3[] verts = m.vertices;
GUIContent gc = new GUIContent("");
List<List<int>> common = z_MeshUtility.GetCommonVertices(m);
System.Text.StringBuilder sb = new System.Text.StringBuilder();
Handles.BeginGUI();
foreach(List<int> l in common)
{
if( w[l[0]] < .001 )
continue;
Vector3 v = target.transform.TransformPoint(verts[l[0]]);
if(colors != null) sb.AppendLine("color: " + colors[l[0]].ToString("F2"));
if(tangents != null) sb.AppendLine("tangent: " + tangents[l[0]].ToString("F2"));
if(uv0 != null && uv0.Count == vertexCount) sb.AppendLine("uv0: " + uv0[l[0]].ToString("F2"));
if(uv1 != null && uv1.Count == vertexCount) sb.AppendLine("uv1: " + uv1[l[0]].ToString("F2"));
if(uv2 != null && uv2.Count == vertexCount) sb.AppendLine("uv2: " + uv2[l[0]].ToString("F2"));
if(uv3 != null && uv3.Count == vertexCount) sb.AppendLine("uv3: " + uv3[l[0]].ToString("F2"));
gc.text = sb.ToString();
sb.Remove(0, sb.Length); // @todo .NET 4.0
GUI.Label(HandleUtility.WorldPointToSizedRect(v, gc, EditorStyles.label), gc);
}
Handles.EndGUI();
#endif
#endif
}
public abstract void RegisterUndo(z_BrushTarget brushTarget);
public virtual void UndoRedoPerformed(List<GameObject> modified)
{
DestroyTempComponent();
}
}
}

12
Assets/ProCore/Polybrush/Code/Editor/Brush Modes/z_BrushMode.cs.meta


fileFormatVersion: 2
guid: ef7af1d5fe5c313488bb9b9ebc72fd2c
timeCreated: 1445433619
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

94
Assets/ProCore/Polybrush/Code/Editor/Brush Modes/z_BrushModeMesh.cs


using UnityEngine;
using UnityEditor;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
namespace Polybrush
{
/**
* Base class for brush modes that modify the mesh.
*/
[System.Serializable]
public abstract class z_BrushModeMesh : z_BrushMode
{
// All meshes that have ever been modified, ever. Kept around to refresh mesh vertices
// on Undo/Redo since Unity doesn't.
private HashSet<Mesh> modifiedMeshes = new HashSet<Mesh>();
private HashSet<object> modifiedPbMeshes = new HashSet<object>();
EditorWindow _pbEditor = null;
public override void OnBrushBeginApply(z_BrushTarget brushTarget, z_BrushSettings brushSettings)
{
_pbEditor = z_ReflectionUtil.ProBuilderEditorWindow;
base.OnBrushBeginApply(brushTarget, brushSettings);
}
public override void OnBrushApply(z_BrushTarget brushTarget, z_BrushSettings brushSettings)
{
// false means no ToMesh or Refresh, true does. Optional addl bool runs pb_Object.Optimize()
brushTarget.editableObject.Apply(true);
if(_pbEditor != null)
z_ReflectionUtil.Invoke(_pbEditor, "Internal_UpdateSelectionFast", BindingFlags.Instance | BindingFlags.NonPublic);
UpdateTempComponent(brushTarget, brushSettings);
}
public override void RegisterUndo(z_BrushTarget brushTarget)
{
if(z_ReflectionUtil.IsProBuilderObject(brushTarget.gameObject))
{
object pb = z_ReflectionUtil.GetComponent(brushTarget.gameObject, "pb_Object");
Undo.RegisterCompleteObjectUndo(pb as UnityEngine.Object, UndoMessage);
modifiedPbMeshes.Add(pb);
}
else
{
Undo.RegisterCompleteObjectUndo(brushTarget.editableObject.graphicsMesh, UndoMessage);
modifiedMeshes.Add(brushTarget.editableObject.graphicsMesh);
}
brushTarget.editableObject.isDirty = true;
}
public override void UndoRedoPerformed(List<GameObject> modified)
{
modifiedMeshes = new HashSet<Mesh>(modifiedMeshes.Where(x => x != null));
if(z_ReflectionUtil.ProBuilderExists())
{
// delete & undo causes cases where object is not null but the reference to it's pb_Object is
HashSet<object> remove = new HashSet<object>();
foreach(object pb in modifiedPbMeshes)
{
try
{
z_ReflectionUtil.ProBuilder_ToMesh(pb);
z_ReflectionUtil.ProBuilder_Refresh(pb);
z_ReflectionUtil.ProBuilder_Optimize(pb);
}
catch
{
remove.Add(pb);
}
}
if(remove.Count() > 0)
modifiedPbMeshes.SymmetricExceptWith(remove);
}
foreach(Mesh m in modifiedMeshes)
{
m.vertices = m.vertices;
m.UploadMeshData(false);
}
base.UndoRedoPerformed(modified);
}
}
}

12
Assets/ProCore/Polybrush/Code/Editor/Brush Modes/z_BrushModeMesh.cs.meta


fileFormatVersion: 2
guid: 28a002c53bdb2204f8ff3786a5af1b27
timeCreated: 1447956411
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

393
Assets/ProCore/Polybrush/Code/Editor/Brush Modes/z_BrushModePaint.cs


using UnityEngine;
using UnityEditor;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
namespace Polybrush
{
/**
* Vertex painter brush mode.
*/
public class z_BrushModePaint : z_BrushModeMesh
{
// how many applications it should take to reach the full strength
const float STRENGTH_MODIFIER = 1f/8f;
private static readonly Color32 WHITE = new Color32(255, 255, 255, 255);
[SerializeField] z_PaintMode paintMode = z_PaintMode.Brush;
[SerializeField] bool likelySupportsVertexColors = false;
// mesh vertex colors
[SerializeField] Color32[] colors_cache = null, target_colors = null, erase_colors = null, colors = null;
[SerializeField] Color32 brushColor = Color.green;
z_ColorMask mask = new z_ColorMask(true, true, true, true);
z_ColorPalette[] availablePalettes = null;
string[] availablePalettes_str = null;
int currentPaletteIndex = -1;
// temp vars
private z_Edge[] _fillModeEdges = new z_Edge[3];
private List<int> _fillModeAdjacentTris = null;
// used for fill mode
Dictionary<z_Edge, List<int>> triangleLookup = null;
public GUIContent[] modeIcons = new GUIContent[]
{
new GUIContent("Brush", "Brush" ),
new GUIContent("Fill", "Fill" ),
new GUIContent("Flood", "Flood" )
};
// The current color palette.
[SerializeField] z_ColorPalette _colorPalette = null;
private z_ColorPalette colorPalette
{
get
{
if(_colorPalette == null)
colorPalette = z_EditorUtility.GetDefaultAsset<z_ColorPalette>("Color Palettes/Default.asset");
return _colorPalette;
}
set
{
_colorPalette = value;
}
}
// An Editor for the colorPalette.
[SerializeField] z_ColorPaletteEditor _colorPaletteEditor = null;
private z_ColorPaletteEditor colorPaletteEditor
{
get
{
if(_colorPaletteEditor == null || _colorPaletteEditor.target != colorPalette)
{
_colorPaletteEditor = (z_ColorPaletteEditor) Editor.CreateEditor(colorPalette);
_colorPaletteEditor.hideFlags = HideFlags.HideAndDontSave;
}
return _colorPaletteEditor;
}
}
// The message that will accompany Undo commands for this brush. Undo/Redo is handled by z_Editor.
public override string UndoMessage { get { return "Paint Brush"; } }
protected override string ModeSettingsHeader { get { return "Paint Settings"; } }
protected override string DocsLink { get { return "http://procore3d.github.io/polybrush/modes/color/"; } }
public override void OnEnable()
{
base.OnEnable();
//modeIcons[0].image = z_IconUtility.GetIcon("Icon/Brush");
//modeIcons[1].image = z_IconUtility.GetIcon("Icon/Roller");
//modeIcons[2].image = z_IconUtility.GetIcon("Icon/Flood");
RefreshAvailablePalettes();
}
public override void OnDisable()
{
base.OnDisable();
if(_colorPaletteEditor != null)
Object.DestroyImmediate(_colorPaletteEditor);
}
// Inspector GUI shown in the Editor window. Base class shows z_BrushSettings by default
public override void DrawGUI(z_BrushSettings brushSettings)
{
base.DrawGUI(brushSettings);
GUILayout.BeginHorizontal();
if(colorPalette == null)
RefreshAvailablePalettes();
EditorGUI.BeginChangeCheck();
currentPaletteIndex = EditorGUILayout.Popup(currentPaletteIndex, availablePalettes_str, "popup");
if(EditorGUI.EndChangeCheck())
{
if(currentPaletteIndex >= availablePalettes.Length)
SetColorPalette( z_ColorPaletteEditor.AddNew() );
else
SetColorPalette(availablePalettes[currentPaletteIndex]);
}
paintMode = (z_PaintMode) GUILayout.Toolbar( (int) paintMode, modeIcons, "Command", GUILayout.Width(120));
GUILayout.EndHorizontal();
if(!likelySupportsVertexColors)
EditorGUILayout.HelpBox("It doesn't look like any of the materials on this object support vertex colors!", MessageType.Warning);
colorPaletteEditor.onSelectIndex = (color) => { SetBrushColor(color, brushSettings.strength); };
colorPaletteEditor.onSaveAs = SetColorPalette;
mask = z_GUILayout.ColorMaskField("Color Mask", mask);
colorPaletteEditor.OnInspectorGUI();
}
private void SetBrushColor(Color color, float strength)
{
brushColor = color;
RebuildColorTargets(color, strength);
}
private void RefreshAvailablePalettes()
{
if(colorPalette == null)
colorPalette = z_EditorUtility.GetDefaultAsset<z_ColorPalette>("Color Palettes/Default.asset");
availablePalettes = Resources.FindObjectsOfTypeAll<z_ColorPalette>().Where(x => !string.IsNullOrEmpty(AssetDatabase.GetAssetPath(x))).ToArray();
availablePalettes_str = availablePalettes.Select(x => x.name).ToArray();
ArrayUtility.Add<string>(ref availablePalettes_str, string.Empty);
ArrayUtility.Add<string>(ref availablePalettes_str, "Add Palette...");
currentPaletteIndex = System.Array.IndexOf(availablePalettes, colorPalette);
}
private void SetColorPalette(z_ColorPalette palette)
{
colorPalette = palette;
RefreshAvailablePalettes();
}
public override void OnBrushSettingsChanged(z_BrushTarget target, z_BrushSettings settings)
{
base.OnBrushSettingsChanged(target, settings);
RebuildColorTargets(brushColor, settings.strength);
}
private void RebuildColorTargets(Color color, float strength)
{
if( colors_cache == null ||
target_colors == null ||
colors_cache.Length != target_colors.Length)
return;
for(int i = 0; i < colors_cache.Length; i++)
{
target_colors[i] = z_Util.Lerp(colors_cache[i], color, mask, strength);
erase_colors[i] = z_Util.Lerp(colors_cache[i], WHITE, mask, strength);
}
}
// Called when the mouse begins hovering an editable object.
public override void OnBrushEnter(z_EditableObject target, z_BrushSettings settings)
{
base.OnBrushEnter(target, settings);
if(target.graphicsMesh == null)
return;
RebuildCaches(target, settings);
triangleLookup = z_MeshUtility.GetAdjacentTriangles(target.editMesh);
MeshRenderer mr = target.gameObject.GetComponent<MeshRenderer>();
if(mr != null && mr.sharedMaterials != null)
likelySupportsVertexColors = mr.sharedMaterials.Any(x => x.shader != null && z_ShaderUtil.SupportsVertexColors(x.shader));
else
likelySupportsVertexColors = false;
}
private void RebuildCaches(z_EditableObject target, z_BrushSettings settings)
{
z_Mesh m = target.editMesh;
int vertexCount = m.vertexCount;
if(m.colors != null && m.colors.Length == vertexCount)
colors_cache = z_Util.Duplicate(m.colors);
else
colors_cache = z_Util.Fill<Color32>( x => { return Color.white; }, vertexCount);
colors = new Color32[vertexCount];
target_colors = new Color32[vertexCount];
erase_colors = new Color32[vertexCount];
RebuildColorTargets(brushColor, settings.strength);
}
// Called whenever the brush is moved. Note that @target may have a null editableObject.
public override void OnBrushMove(z_BrushTarget target, z_BrushSettings settings)
{
base.OnBrushMove(target, settings);
if(!z_Util.IsValid(target))
return;
bool shift = Event.current.shift && Event.current.type != EventType.ScrollWheel;
z_Mesh mesh = target.editableObject.editMesh;
int vertexCount = mesh.vertexCount;
float[] weights = target.GetAllWeights();
switch(paintMode)
{
case z_PaintMode.Flood:
for(int i = 0; i < vertexCount; i++)
colors[i] = target_colors[i];
break;
case z_PaintMode.Fill:
System.Array.Copy(colors_cache, colors, vertexCount);
int[] indices = target.editableObject.editMesh.GetTriangles();
int index = 0;
foreach(z_RaycastHit hit in target.raycastHits)
{
if(hit.triangle > -1)
{
index = hit.triangle * 3;
colors[indices[index + 0]] = shift ? WHITE : target_colors[indices[index + 0]];
colors[indices[index + 1]] = shift ? WHITE : target_colors[indices[index + 1]];
colors[indices[index + 2]] = shift ? WHITE : target_colors[indices[index + 2]];
_fillModeEdges[0].x = indices[index+0];
_fillModeEdges[0].y = indices[index+1];
_fillModeEdges[1].x = indices[index+1];
_fillModeEdges[1].y = indices[index+2];
_fillModeEdges[2].x = indices[index+2];
_fillModeEdges[2].y = indices[index+0];
for(int i = 0; i < 3; i++)
{
if(triangleLookup.TryGetValue(_fillModeEdges[i], out _fillModeAdjacentTris))
{
for(int n = 0; n < _fillModeAdjacentTris.Count; n++)
{
index = _fillModeAdjacentTris[n] * 3;
colors[indices[index + 0]] = shift ? WHITE : target_colors[indices[index + 0]];
colors[indices[index + 1]] = shift ? WHITE : target_colors[indices[index + 1]];
colors[indices[index + 2]] = shift ? WHITE : target_colors[indices[index + 2]];
}
}
}
}
}
break;
default:
{
for(int i = 0; i < vertexCount; i++)
{
colors[i] = z_Util.Lerp(colors_cache[i],
shift ? erase_colors[i] : target_colors[i],
mask,
weights[i]);
}
break;
}
}
target.editableObject.editMesh.colors = colors;
target.editableObject.ApplyMeshAttributes(z_MeshChannel.Color);
}
// Called when the mouse exits hovering an editable object.
public override void OnBrushExit(z_EditableObject target)
{
base.OnBrushExit(target);
if(target.editMesh != null)
{
target.editMesh.colors = colors_cache;
target.ApplyMeshAttributes(z_MeshChannel.Color);
}
likelySupportsVertexColors = true;
}
// Called every time the brush should apply itself to a valid target. Default is on mouse move.
public override void OnBrushApply(z_BrushTarget target, z_BrushSettings settings)
{
System.Array.Copy(colors, colors_cache, colors.Length);
target.editableObject.editMesh.colors = colors_cache;
base.OnBrushApply(target, settings);
}
// set mesh colors back to their original state before registering for undo
public override void RegisterUndo(z_BrushTarget brushTarget)
{
brushTarget.editableObject.editMesh.colors = colors_cache;
brushTarget.editableObject.ApplyMeshAttributes(z_MeshChannel.Color);
base.RegisterUndo(brushTarget);
}
public override void DrawGizmos(z_BrushTarget target, z_BrushSettings settings)
{
if(z_Util.IsValid(target) && paintMode == z_PaintMode.Fill)
{
Vector3[] vertices = target.editableObject.editMesh.vertices;
int[] indices = target.editableObject.editMesh.GetTriangles();
z_Handles.PushMatrix();
z_Handles.PushHandleColor();
Handles.matrix = target.transform.localToWorldMatrix;
int index = 0;
foreach(z_RaycastHit hit in target.raycastHits)
{
if(hit.triangle > -1)
{
Handles.color = target_colors[indices[index]];
index = hit.triangle * 3;
Handles.DrawLine(vertices[indices[index+0]] + hit.normal * .1f, vertices[indices[index+1]] + hit.normal * .1f);
Handles.DrawLine(vertices[indices[index+1]] + hit.normal * .1f, vertices[indices[index+2]] + hit.normal * .1f);
Handles.DrawLine(vertices[indices[index+2]] + hit.normal * .1f, vertices[indices[index+0]] + hit.normal * .1f);
_fillModeEdges[0].x = indices[index+0];
_fillModeEdges[0].y = indices[index+1];
_fillModeEdges[1].x = indices[index+1];
_fillModeEdges[1].y = indices[index+2];
_fillModeEdges[2].x = indices[index+2];
_fillModeEdges[2].y = indices[index+0];
for(int i = 0; i < 3; i++)
{
if(triangleLookup.TryGetValue(_fillModeEdges[i], out _fillModeAdjacentTris))
{
for(int n = 0; n < _fillModeAdjacentTris.Count; n++)
{
index = _fillModeAdjacentTris[n] * 3;
Handles.DrawLine(vertices[indices[index+0]] + hit.normal * .1f, vertices[indices[index+1]] + hit.normal * .1f);
Handles.DrawLine(vertices[indices[index+1]] + hit.normal * .1f, vertices[indices[index+2]] + hit.normal * .1f);
Handles.DrawLine(vertices[indices[index+2]] + hit.normal * .1f, vertices[indices[index+0]] + hit.normal * .1f);
}
}
}
}
}
z_Handles.PopHandleColor();
z_Handles.PopMatrix();
}
else
{
base.DrawGizmos(target, settings);
}
}
}
}

12
Assets/ProCore/Polybrush/Code/Editor/Brush Modes/z_BrushModePaint.cs.meta


fileFormatVersion: 2
guid: f425014c97249344099c3f447082d4bc
timeCreated: 1446562266
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

434
Assets/ProCore/Polybrush/Code/Editor/Brush Modes/z_BrushModePrefab.cs


using UnityEngine;
using UnityEditor;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
namespace Polybrush
{
/**
* Prefab painter brush mode.
*/
public class z_BrushModePrefab : z_BrushMode
{
const string PREFAB_PALETTE_PATH = "Prefab Palettes/Default.asset";
private double lastBrushApplication = 0.0;
private z_LocalPref<bool> hitSurfaceIsParent;
private z_LocalPref<bool> avoidOverlappingGameObjects;
private z_LocalPref<int> previewThumbSize;
// preferences
private bool placeWithPivot = false;
// The current prefab palette
[SerializeField] z_PrefabPalette _prefabPalette = null;
z_PrefabPalette[] availablePalettes = null;
string[] availablePalettes_str = null;
int currentPaletteIndex = -1;
private z_PrefabPalette prefabPalette
{
get
{
if(_prefabPalette == null)
prefabPalette = z_EditorUtility.GetDefaultAsset<z_PrefabPalette>(PREFAB_PALETTE_PATH);
return _prefabPalette;
}
set
{
if(prefabPaletteEditor != null)
GameObject.DestroyImmediate(prefabPaletteEditor);
_prefabPalette = value;
prefabPaletteEditor = (z_PrefabPaletteEditor) Editor.CreateEditor(_prefabPalette);
prefabPaletteEditor.onSelectionChanged = SelectedPrefab;
}
}
// An Editor for the prefabPalette.
z_PrefabPaletteEditor prefabPaletteEditor = null;
// all instances of prefabs in the current palette in this scene.
private List<GameObject> instances = null;
private List<z_PrefabAndSettings> queued = null;
public override string UndoMessage { get { return "Paint Prefabs"; } }
protected override string ModeSettingsHeader { get { return "Placement Settings"; } }
protected override string DocsLink { get { return "http://procore3d.github.io/polybrush/modes/place/"; } }
private GUIStyle paletteStyle;
static GUIContent gc_usePrefabPivot = new GUIContent("Use Pivot", "By default Polybrush will position placed objects entirely on top of the target plane. When 'Use Pivot' is enabled objects will instead be placed by their assigned mesh origin.");
static GUIContent gc_hitSurfaceIsParent = new GUIContent("Hit Surface is Parent", "When enabled any instantiated prefab from this mode will be automatically made a child of the surface it was placed on.");
static GUIContent gc_avoidOverlappingGameObjects = new GUIContent("Avoid Overlap", "If enabled Polybrush will attempt to avoid placing prefabs where they may overlap with another placed GameObject.");
static string FormatInstanceName(GameObject go)
{
return string.Format("{0}(Clone)", go.name);
}
public override void OnEnable()
{
base.OnEnable();
RefreshAvailablePalettes();
if(_prefabPalette == null)
prefabPalette = z_EditorUtility.GetDefaultAsset<z_PrefabPalette>(PREFAB_PALETTE_PATH);
if(prefabPaletteEditor != null)
{
Object.DestroyImmediate(prefabPaletteEditor);
prefabPaletteEditor = null;
}
prefabPaletteEditor = (z_PrefabPaletteEditor) Editor.CreateEditor(_prefabPalette);
// unity won't serialize delegates, so even if prefabPalette isn't null and the editor remains valid
// the delegate could still be null after a script reload.
prefabPaletteEditor.onSelectionChanged = SelectedPrefab;
paletteStyle = new GUIStyle();
paletteStyle.padding = new RectOffset(8, 8, 8, 8);
hitSurfaceIsParent = new z_LocalPref<bool>("prefab_hitSurfaceIsParent", true);
avoidOverlappingGameObjects = new z_LocalPref<bool>("prefab_avoidOverlappingGameObjects");
previewThumbSize = new z_LocalPref<int>("prefab_previewThumbSize", 64);
}
public override void OnDisable()
{
base.OnDisable();
if(prefabPaletteEditor != null)
{
GameObject.DestroyImmediate(prefabPaletteEditor);
prefabPaletteEditor = null;
}
}
// Inspector GUI shown in the Editor window. Base class shows z_BrushSettings by default
public override void DrawGUI(z_BrushSettings brushSettings)
{
base.DrawGUI(brushSettings);
placeWithPivot = z_GUILayout.Toggle(gc_usePrefabPivot, placeWithPivot);
z_GlobalSettingsEditor.lockBrushToFirst = z_GUILayout.Toggle(z_GlobalSettingsEditor.gc_lockBrushToFirst, z_GlobalSettingsEditor.lockBrushToFirst);
hitSurfaceIsParent.prefValue = z_GUILayout.Toggle(gc_hitSurfaceIsParent, hitSurfaceIsParent);
avoidOverlappingGameObjects.prefValue = z_GUILayout.Toggle(gc_avoidOverlappingGameObjects, avoidOverlappingGameObjects);
GUILayout.Space(4);
if(prefabPalette == null)
RefreshAvailablePalettes();
EditorGUI.BeginChangeCheck();
currentPaletteIndex = EditorGUILayout.Popup(currentPaletteIndex, availablePalettes_str, "popup");
if(EditorGUI.EndChangeCheck())
{
if(currentPaletteIndex >= availablePalettes.Length)
SetPrefabPalette( z_PrefabPaletteEditor.AddNew() );
else
SetPrefabPalette(availablePalettes[currentPaletteIndex]);
}
GUILayout.Space(4);
GUILayout.BeginHorizontal();
GUILayout.Label("Prefabs");
previewThumbSize.prefValue = (int) GUILayout.HorizontalSlider((float)previewThumbSize, 16f, 128f);
GUILayout.EndHorizontal();
GUILayout.BeginVertical( paletteStyle );
if(prefabPaletteEditor != null)
prefabPaletteEditor.OnInspectorGUI_Internal(previewThumbSize);
GUILayout.EndVertical();
}
private void SetPrefabPalette(z_PrefabPalette palette)
{
prefabPalette = palette;
RefreshAvailablePalettes();
}
private void RefreshAvailablePalettes()
{
availablePalettes = Resources.FindObjectsOfTypeAll<z_PrefabPalette>().Where(x => !string.IsNullOrEmpty(AssetDatabase.GetAssetPath(x))).ToArray();
availablePalettes_str = availablePalettes.Select(x => x.name).ToArray();
ArrayUtility.Add<string>(ref availablePalettes_str, string.Empty);
ArrayUtility.Add<string>(ref availablePalettes_str, "Add Palette...");
currentPaletteIndex = System.Array.IndexOf(availablePalettes, _prefabPalette);
}
private void SelectedPrefab(IEnumerable<int> selected)
{
if(selected == null)
queued = null;
else
queued = prefabPalette.prefabs.Where( (x, i) => { return selected.Contains(i); } ).ToList();
}
public override void OnBrushSettingsChanged(z_BrushTarget target, z_BrushSettings settings)
{
base.OnBrushSettingsChanged(target, settings);
}
// Called when the mouse begins hovering an editable object.
public override void OnBrushEnter(z_EditableObject target, z_BrushSettings settings)
{
base.OnBrushEnter(target, settings);
}
// Called whenever the brush is moved. Note that @target may have a null editableObject.
public override void OnBrushMove(z_BrushTarget target, z_BrushSettings settings)
{
base.OnBrushMove(target, settings);
}
// Called when the mouse exits hovering an editable object.
public override void OnBrushExit(z_EditableObject target)
{
base.OnBrushExit(target);
}
public override void OnBrushBeginApply(z_BrushTarget target, z_BrushSettings settings)
{
base.OnBrushBeginApply(target, settings);
instances = z_SceneUtility.FindInstancesInScene(prefabPalette.prefabs.Select(x => x.gameObject), FormatInstanceName).ToList();
}
// Called every time the brush should apply itself to a valid target. Default is on mouse move.
public override void OnBrushApply(z_BrushTarget target, z_BrushSettings settings)
{
bool shift = Event.current.shift && Event.current.type != EventType.ScrollWheel;
if( (EditorApplication.timeSinceStartup - lastBrushApplication) > Mathf.Max(.06f, (1f - settings.strength)) )
{
lastBrushApplication = EditorApplication.timeSinceStartup;
if(shift)
{
foreach(z_RaycastHit hit in target.raycastHits)
RemoveGameObjects(hit, target, settings);
}
else
{
foreach(z_RaycastHit hit in target.raycastHits)
PlaceGameObject(hit, GetPrefab().gameObject, target, settings);
}
}
}
// Handle Undo locally since it doesn't follow the same pattern as mesh modifications.
public override void RegisterUndo(z_BrushTarget brushTarget) {}
private void PlaceGameObject(z_RaycastHit hit, GameObject prefab, z_BrushTarget target, z_BrushSettings settings)
{
if(prefab == null)
return;
Ray ray = RandomRay(hit.position, hit.normal, settings.radius, settings.falloff, settings.falloffCurve);
z_RaycastHit rand_hit;
Vector3[] vertices = target.editableObject.editMesh.vertices;
int[] triangles = target.editableObject.editMesh.GetTriangles();
if( z_SceneUtility.MeshRaycast(ray, vertices, triangles, out rand_hit) )
{
float pivotOffset = placeWithPivot ? 0f : GetPivotOffset(prefab);
Quaternion rotation = Quaternion.FromToRotation(Vector3.up, target.transform.TransformDirection(rand_hit.normal));
Quaternion random = Quaternion.AngleAxis(Random.Range(0f, 360f), Vector3.up);
GameObject inst = PrefabUtility.ConnectGameObjectToPrefab(Instantiate(prefab), prefab);
inst.transform.localPosition = target.transform.TransformPoint(rand_hit.position);
inst.transform.localRotation = rotation * random;
inst.name = FormatInstanceName(prefab);
inst.transform.position = inst.transform.position + inst.transform.up * pivotOffset;
if( avoidOverlappingGameObjects && TestIntersection(inst) )
{
Object.DestroyImmediate(inst);
return;
}
if( hitSurfaceIsParent )
inst.transform.SetParent(target.transform);
PrefabUtility.RecordPrefabInstancePropertyModifications(inst);
instances.Add(inst);
Undo.RegisterCreatedObjectUndo(inst, UndoMessage);
}
}
private void RemoveGameObjects(z_RaycastHit hit, z_BrushTarget target, z_BrushSettings settings)
{
Vector3 worldHitPosition = target.editableObject.transform.TransformPoint(hit.position);
int count = instances.Count;
for(int i = 0; i < count; i++)
{
if( instances[i] != null && Vector3.Distance(worldHitPosition, instances[i].transform.position) < settings.radius )
{
GameObject go = instances[i];
instances.RemoveAt(i);
count--;
Undo.DestroyObjectImmediate(go);
}
}
}
private Ray RandomRay(Vector3 position, Vector3 normal, float radius, float falloff, AnimationCurve curve)
{
Vector3 a = Vector3.zero;
Quaternion rotation = Quaternion.LookRotation(normal, Vector3.up);
a.x = Mathf.Cos(Random.Range(0f, 360f));
a.y = Mathf.Sin(Random.Range(0f, 360f));
float r = Mathf.Sqrt(Random.Range(0f, 1f));
while(true)
{
// this isn't great
if(r < falloff || Random.Range(0f, 1f) > Mathf.Clamp(curve.Evaluate( 1f - ((r - falloff) / (1f - falloff))), 0f, 1f))
{
a = position + (rotation * (a.normalized * r * radius));
return new Ray(a + normal * 10f, -normal);
}
else
{
r = Mathf.Sqrt(Random.Range(0f, 1f));
}
}
}
private z_PrefabAndSettings GetPrefab()
{
List<z_PrefabAndSettings> pool = queued != null && queued.Count > 0 ? queued : prefabPalette.prefabs;
int count = pool == null ? 0 : pool.Count;
return count > 0 ? pool[(int) Random.Range(0, count)] : null;
}
private float GetPivotOffset(GameObject go)
{
MeshFilter mf = go.GetComponent<MeshFilter>();
// probuilder meshes that are prefabs might not have a mesh
// associated with them, so make sure they do before querying
// for bounds
object pb = go.GetComponent("pb_Object");
if(pb != null)
z_ReflectionUtil.Invoke(pb, "Awake");
if(mf == null || mf.sharedMesh == null)
return 0f;
Bounds bounds = mf.sharedMesh.bounds;
return (-bounds.center.y + bounds.extents.y) * go.transform.localScale.y;
}
private struct SphereBounds
{
public Vector3 position;
public float radius;
public SphereBounds(Vector3 p, float r)
{
position = p;
radius = r;
}
public bool Intersects(SphereBounds other)
{
return Vector3.Distance(position, other.position) < (radius + other.radius);
}
}
private static bool GetSphereBounds(GameObject go, out SphereBounds bounds)
{
bounds = new SphereBounds();
if(go == null)
return false;
Mesh mesh = null;
MeshFilter mf = go.GetComponentInChildren<MeshFilter>();
if(mf != null && mf.sharedMesh != null)
{
mesh = mf.sharedMesh;
}
else
{
SkinnedMeshRenderer smr = go.GetComponentInChildren<SkinnedMeshRenderer>();
if(smr != null && smr.sharedMesh != null)
mesh = smr.sharedMesh;
}
if(mesh != null)
{
Bounds meshBounds = mf.sharedMesh.bounds;
bounds.position = mf.transform.TransformPoint(meshBounds.center - (Vector3.up * meshBounds.extents.y));
bounds.radius = Mathf.Max(meshBounds.extents.x, meshBounds.extents.z);
return true;
}
return false;
}
/**
* Tests if go intersects with any painted objects.
*/
private bool TestIntersection(GameObject go)
{
SphereBounds bounds, it_bounds;
if(!GetSphereBounds(go, out bounds))
return false;
int c = instances == null ? 0 : instances.Count;
for(int i = 0; i < c; i++)
{
if(GetSphereBounds(instances[i], out it_bounds) && bounds.Intersects(it_bounds))
return true;
}
return false;
}
public override void DrawGizmos(z_BrushTarget target, z_BrushSettings settings)
{
base.DrawGizmos(target, settings);
// SphereBounds bounds;
// foreach(GameObject go in instances)
// {
// if(!GetSphereBounds(go, out bounds))
// continue;
// Handles.CircleCap(-1, bounds.position, Quaternion.Euler(Vector3.up * 90f), bounds.radius);
// Handles.CircleCap(-1, bounds.position, Quaternion.Euler(Vector3.right * 90f), bounds.radius);
// Handles.CircleCap(-1, bounds.position, Quaternion.Euler(Vector3.forward * 90f), bounds.radius);
// }
}
}
}

12
Assets/ProCore/Polybrush/Code/Editor/Brush Modes/z_BrushModePrefab.cs.meta


fileFormatVersion: 2
guid: 7afd235f90a2cb943996cef04118c5fa
timeCreated: 1447866851
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

123
Assets/ProCore/Polybrush/Code/Editor/Brush Modes/z_BrushModeRaiseLower.cs


using UnityEngine;
using UnityEditor;
using System.Collections;
using System.Collections.Generic;
namespace Polybrush
{
/**
* Brush mode for moving vertices in a direction.
*/
public class z_BrushModeRaiseLower : z_BrushModeSculpt
{
protected override string brushDirectionPref { get{ return z_Pref.raiseLowerDirection; } }
protected override string brushNormalIsStickyPref { get{ return "pushpull_brush_sticky"; } }
protected override string ignoreNonManifoldIndicesPref { get { return "pushpull_ignoreNonManifoldIndices"; } }
Vector3[] vertices = null;
Dictionary<int, Vector3> normalLookup = null;
List<List<int>> commonVertices = null;
int commonVertexCount;
[SerializeField] float brushStrength = 1f;
public override string UndoMessage { get { return "Push / Pull Vertices"; } }
protected override string DocsLink { get { return "http://procore3d.github.io/polybrush/modes/sculpt/"; } }
protected override string ModeSettingsHeader { get { return "Push / Pull Settings"; } }
private GUIContent gc_BrushEffect = new GUIContent("Brush Effect", "Defines the baseline distance that vertices will be moved when a brush is applied at full strength.");
public override void OnEnable()
{
base.OnEnable();
brushStrength = z_Pref.GetFloat(z_Pref.pushPullEffect);
}
public override void DrawGUI(z_BrushSettings settings)
{
base.DrawGUI(settings);
EditorGUI.BeginChangeCheck();
brushStrength = z_GUILayout.FloatField(gc_BrushEffect, brushStrength);
if(EditorGUI.EndChangeCheck())
z_Pref.SetFloat(z_Pref.pushPullEffect, brushStrength);
}
public override void OnBrushEnter(z_EditableObject target, z_BrushSettings settings)
{
base.OnBrushEnter(target, settings);
vertices = target.editMesh.vertices;
normalLookup = z_MeshUtility.GetSmoothNormalLookup(target.editMesh);
commonVertices = z_MeshUtility.GetCommonVertices(target.editMesh);
commonVertexCount = commonVertices.Count;
}
public override void OnBrushApply(z_BrushTarget target, z_BrushSettings settings)
{
int rayCount = target.raycastHits.Count;
if(rayCount < 1)
return;
Vector3 n = direction.ToVector3();
float scale = 1f / ( Vector3.Scale(target.transform.lossyScale, n).magnitude );
float sign = Event.current.control ? -1f : 1f;
float maxMoveDistance = settings.strength * STRENGTH_MODIFIER * sign * brushStrength;
int vertexCount = target.editableObject.vertexCount;
z_Mesh mesh = target.editableObject.editMesh;
for(int ri = 0; ri < rayCount; ri++)
{
z_RaycastHit hit = target.raycastHits[ri];
if(hit.weights == null || hit.weights.Length < vertexCount)
continue;
if( direction == z_Direction.BrushNormal )
{
if(brushNormalIsSticky)
n = brushNormalOnBeginApply[ri];
else
n = target.raycastHits[ri].normal;
scale = 1f / ( Vector3.Scale(target.transform.lossyScale, n).magnitude );
}
for(int i = 0; i < commonVertexCount; i++)
{
int index = commonVertices[i][0];
if(hit.weights[index] < .0001f || (ignoreNonManifoldIndices && nonManifoldIndices.Contains(index)))
continue;
if(direction == z_Direction.VertexNormal)
{
n = normalLookup[index];
scale = 1f / ( Vector3.Scale(target.transform.lossyScale, n).magnitude );
}
Vector3 pos = vertices[index] + n * (hit.weights[index] * maxMoveDistance * scale);
List<int> indices = commonVertices[i];
for(int it = 0; it < indices.Count; it++)
vertices[indices[it]] = pos;
}
}
mesh.vertices = vertices;
// different than setting weights on temp component,
// which is what z_BrushModeMesh.OnBrushApply does.
if(tempComponent != null)
tempComponent.OnVerticesMoved(mesh);
base.OnBrushApply(target, settings);
}
}
}

12
Assets/ProCore/Polybrush/Code/Editor/Brush Modes/z_BrushModeRaiseLower.cs.meta


fileFormatVersion: 2
guid: 17e06d3605d82ad408e50c561837d9f4
timeCreated: 1446217542
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

129
Assets/ProCore/Polybrush/Code/Editor/Brush Modes/z_BrushModeSculpt.cs


using UnityEngine;
using UnityEditor;
using System.Collections;
using System.Collections.Generic;
namespace Polybrush
{
/**
* Base class for brush modes that move vertices around. Implements an overlay preview.
*/
public abstract class z_BrushModeSculpt : z_BrushModeMesh
{
// Modifier to apply on top of strength. Translates to brush applications per second roughly.
public const float STRENGTH_MODIFIER = .01f;
// Allow child classes to store independent preference values.
protected virtual string brushDirectionPref { get { return z_Pref.sculptDirection; } }
// Allow child classes to store independent preference values.
protected virtual string brushNormalIsStickyPref { get { return z_Pref.brushNormalIsSticky; } }
// Allow child classes to store independent preference values.
protected virtual string ignoreNonManifoldIndicesPref { get { return "ignoreNonManifoldIndices"; } }
public Color[] gradient = new Color[3]
{
Color.green,
Color.yellow,
Color.black
};
// What direction to push vertices in.
public z_Direction direction = z_Direction.Up;
protected List<Vector3> brushNormalOnBeginApply = new List<Vector3>();
protected Vector3[] cached_normals;
public GUIContent gc_direction = new GUIContent("Direction", "How vertices are moved when the brush is applied. You can explicitly set an axis, or use the vertex normal.");
public GUIContent gc_ignoreOpenEdges = new GUIContent("Ignore Open Edges", "When on, edges that are not connected on both sides will be ignored by brush strokes.");
protected bool brushNormalIsSticky = false;
private GUIContent gc_brushNormalIsSticky = new GUIContent("Brush Normal is Sticky", "If enabled, vertices will be moved only on the direction of the brush normal at the time of first application.");
public override string UndoMessage { get { return "Sculpt Vertices"; } }
protected override string ModeSettingsHeader { get { return "Sculpt Settings"; } }
// If true vertices on the edge of a mesh will not be affected by brush strokes. It is up to inheriting
// classes to implement this preference (use `nonManifoldIndices` HashSet to check if a vertex index is
// non-manifold).
protected bool ignoreNonManifoldIndices = true;
protected HashSet<int> nonManifoldIndices = null;
public override void OnEnable()
{
base.OnEnable();
brushNormalIsSticky = z_Pref.GetBool( brushNormalIsStickyPref );
ignoreNonManifoldIndices = z_Pref.GetBool( ignoreNonManifoldIndicesPref );
direction = (z_Direction) z_Pref.GetInt( brushDirectionPref );
}
public override void OnBrushEnter(z_EditableObject target, z_BrushSettings settings)
{
base.OnBrushEnter(target, settings);
nonManifoldIndices = z_MeshUtility.GetNonManifoldIndices(target.editMesh);
}
public override void DrawGUI(z_BrushSettings settings)
{
base.DrawGUI(settings);
EditorGUI.BeginChangeCheck();
ignoreNonManifoldIndices = z_GUILayout.Toggle(gc_ignoreOpenEdges, ignoreNonManifoldIndices);
if(EditorGUI.EndChangeCheck())
z_Pref.SetBool(ignoreNonManifoldIndicesPref, ignoreNonManifoldIndices);
if(direction == z_Direction.BrushNormal)
{
EditorGUI.BeginChangeCheck();
brushNormalIsSticky = z_GUILayout.Toggle(gc_brushNormalIsSticky, brushNormalIsSticky);
if(EditorGUI.EndChangeCheck())
z_Pref.SetBool(brushNormalIsStickyPref, brushNormalIsSticky);
}
EditorGUI.BeginChangeCheck();
direction = (z_Direction) z_GUILayout.EnumPopup(gc_direction, direction);
if(EditorGUI.EndChangeCheck())
z_Pref.SetInt(brushDirectionPref, (int) direction);
}
protected void CacheBrushNormals(z_BrushTarget target)
{
brushNormalOnBeginApply.Clear();
for(int i = 0; i < target.raycastHits.Count; i++)
brushNormalOnBeginApply.Add(target.raycastHits[i].normal);
z_Mesh mesh = target.editableObject.editMesh;
cached_normals = new Vector3[mesh.vertexCount];
if(mesh.normals != null && mesh.normals.Length == mesh.vertexCount)
System.Array.Copy(mesh.normals, 0, cached_normals, 0, mesh.vertexCount);
}
public override void OnBrushBeginApply(z_BrushTarget target, z_BrushSettings settings)
{
CacheBrushNormals(target);
base.OnBrushBeginApply(target, settings);
}
protected override void CreateTempComponent(z_EditableObject target, z_BrushSettings settings)
{
z_OverlayRenderer ren = target.gameObject.AddComponent<z_OverlayRenderer>();
ren.SetMesh(target.editMesh);
ren.fullColor = z_Pref.GetColor(z_Pref.brushColor);
ren.gradient = z_Pref.GetGradient(z_Pref.brushGradient);
tempComponent = ren;
}
protected override void UpdateTempComponent(z_BrushTarget target, z_BrushSettings settings)
{
if(tempComponent != null)
((z_OverlayRenderer)tempComponent).SetWeights(target.GetAllWeights(), settings.strength);
}
}
}

12
Assets/ProCore/Polybrush/Code/Editor/Brush Modes/z_BrushModeSculpt.cs.meta


fileFormatVersion: 2
guid: 23c0c596c336a404983b526a10ecf007
timeCreated: 1445434544
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

115
Assets/ProCore/Polybrush/Code/Editor/Brush Modes/z_BrushModeSmooth.cs


using UnityEngine;
using UnityEditor;
using System.Collections;
using System.Collections.Generic;
namespace Polybrush
{
/**
* Brush mode for moving vertices in a direction.
*/
public class z_BrushModeSmooth : z_BrushModeSculpt
{
const float SMOOTH_STRENGTH_MODIFIER = .1f;
protected override string brushDirectionPref { get { return z_Pref.smoothDirection; } }
protected override string brushNormalIsStickyPref { get { return "smooth_brush_sticky"; } }
protected override string ignoreNonManifoldIndicesPref { get { return "smooth_ignoreNonManifoldIndices"; } }
Vector3[] vertices = null;
Dictionary<int, List<int>> neighborLookup = new Dictionary<int, List<int>>();
List<List<int>> commonVertices = null;
int commonVertexCount;
public override string UndoMessage { get { return "Smooth Vertices"; } }
protected override string ModeSettingsHeader { get { return "Smooth Settings"; } }
protected override string DocsLink { get { return "http://procore3d.github.io/polybrush/modes/smooth/"; } }
public override void OnEnable()
{
base.OnEnable();
}
public override void DrawGUI(z_BrushSettings settings)
{
base.DrawGUI(settings);
}
public override void OnBrushEnter(z_EditableObject target, z_BrushSettings settings)
{
base.OnBrushEnter(target, settings);
vertices = target.editMesh.vertices;
neighborLookup = z_MeshUtility.GetAdjacentVertices(target.editMesh);
commonVertices = z_MeshUtility.GetCommonVertices(target.editMesh);
commonVertexCount = commonVertices.Count;
}
public override void OnBrushApply(z_BrushTarget target, z_BrushSettings settings)
{
int rayCount = target.raycastHits.Count;
Vector3[] normals = (direction == z_Direction.BrushNormal) ? target.editableObject.editMesh.normals : null;
Vector3 v, t, avg, dirVec = direction.ToVector3();
Plane plane = new Plane(Vector3.up, Vector3.zero);
z_Mesh mesh = target.editableObject.editMesh;
int vertexCount = mesh.vertexCount;
// don't use target.GetAllWeights because brush normal needs
// to know which ray to use for normal
for(int ri = 0; ri < rayCount; ri++)
{
z_RaycastHit hit = target.raycastHits[ri];
if(hit.weights == null || hit.weights.Length < vertexCount)
continue;
for(int i = 0; i < commonVertexCount; i++)
{
int index = commonVertices[i][0];
if(hit.weights[index] < .0001f || (ignoreNonManifoldIndices && nonManifoldIndices.Contains(index)))
continue;
v = vertices[index];
if(direction == z_Direction.VertexNormal)
{
avg = z_Math.Average(vertices, neighborLookup[index]);
}
else
{
avg = z_Math.WeightedAverage(vertices, neighborLookup[index], hit.weights);
if(direction == z_Direction.BrushNormal)
{
if(brushNormalIsSticky)
dirVec = brushNormalOnBeginApply[ri];
else
dirVec = z_Math.WeightedAverage(normals, neighborLookup[index], hit.weights).normalized;
}
plane.SetNormalAndPosition(dirVec, avg);
avg = v - dirVec * plane.GetDistanceToPoint(v);
}
t = Vector3.Lerp(v, avg, hit.weights[index]);
List<int> indices = commonVertices[i];
Vector3 pos = v + (t-v) * settings.strength * SMOOTH_STRENGTH_MODIFIER;
for(int n = 0; n < indices.Count; n++)
vertices[indices[n]] = pos;
}
}
mesh.vertices = vertices;
if(tempComponent != null)
tempComponent.OnVerticesMoved(mesh);
base.OnBrushApply(target, settings);
}
}
}

12
Assets/ProCore/Polybrush/Code/Editor/Brush Modes/z_BrushModeSmooth.cs.meta


fileFormatVersion: 2
guid: 5d099a4e89428b34cb4b63a7c45d01b9
timeCreated: 1446041888
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

422
Assets/ProCore/Polybrush/Code/Editor/Brush Modes/z_BrushModeTexture.cs


// #define POLYBRUSH_DEBUG
using UnityEngine;
using UnityEditor;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
namespace Polybrush
{
/**
* Vertex texture painter brush mode.
* Similar to z_BrushModePaint, except it packs blend information into both the color32 and UV3/4 channels.
*/
public class z_BrushModeTexture : z_BrushModeMesh
{
// how many applications it should take to reach the full strength
const float STRENGTH_MODIFIER = 1f/8f;
z_PaintMode paintMode = z_PaintMode.Brush;
bool likelySupportsTextureBlending = true;
[System.NonSerialized]
z_SplatSet splat_cache = null,
splat_target = null,
splat_erase = null,
splat_current = null;
[System.NonSerialized] z_SplatWeight brushColor = null;
[System.NonSerialized] z_SplatWeight minWeights = null;
[SerializeField] int selectedAttributeIndex = -1;
private z_AttributeLayoutContainer meshAttributesContainer = null;
private z_AttributeLayout[] meshAttributes
{
get
{
return meshAttributesContainer != null ? meshAttributesContainer.attributes : null;
}
}
// temp vars
private z_Edge[] _fillModeEdges = new z_Edge[3];
private List<int> _fillModeAdjacentTris = null;
[SerializeField] int vertexCount = 0;
Dictionary<z_Edge, List<int>> triangleLookup = null;
public GUIContent[] modeIcons = new GUIContent[]
{
new GUIContent("Brush", "Brush" ),
new GUIContent("Fill", "Fill" ),
new GUIContent("Flood", "Flood" )
};
// The message that will accompany Undo commands for this brush. Undo/Redo is handled by z_Editor.
public override string UndoMessage { get { return "Paint Brush"; } }
protected override string ModeSettingsHeader { get { return "Texture Paint Settings"; } }
protected override string DocsLink { get { return "http://procore3d.github.io/polybrush/modes/texture/"; } }
public override void OnEnable()
{
base.OnEnable();
//modeIcons[0].image = z_IconUtility.GetIcon("Icon/Brush");
//modeIcons[1].image = z_IconUtility.GetIcon("Icon/Roller");
//modeIcons[2].image = z_IconUtility.GetIcon("Icon/Flood");
likelySupportsTextureBlending = false;
meshAttributesContainer = null;
brushColor = null;
foreach(GameObject go in Selection.gameObjects)
{
likelySupportsTextureBlending = CheckForTextureBlendSupport(go);
if(likelySupportsTextureBlending)
break;
}
}
// Inspector GUI shown in the Editor window. Base class shows z_BrushSettings by default
public override void DrawGUI(z_BrushSettings brushSettings)
{
base.DrawGUI(brushSettings);
GUILayout.BeginHorizontal();
GUILayout.FlexibleSpace();
paintMode = (z_PaintMode) GUILayout.Toolbar( (int) paintMode, modeIcons, "Command", GUILayout.Width(120));
GUILayout.FlexibleSpace();
GUILayout.EndHorizontal();
GUILayout.Space(4);
if(!likelySupportsTextureBlending)
{
EditorGUILayout.HelpBox("It doesn't look like any of the materials on this object support texture blending!\n\nSee the readme for information on creating custom texture blend shaders.", MessageType.Warning);
}
if(meshAttributes != null)
{
int prevSelectedAttributeIndex = selectedAttributeIndex;
selectedAttributeIndex = z_SplatWeightEditor.OnInspectorGUI(selectedAttributeIndex, ref brushColor, meshAttributes);
if(prevSelectedAttributeIndex != selectedAttributeIndex)
SetBrushColorWithAttributeIndex(selectedAttributeIndex);
#if POLYBRUSH_DEBUG
GUILayout.BeginHorizontal();
GUILayout.FlexibleSpace();
if(GUILayout.Button("MetaData", EditorStyles.miniButton))
{
Debug.Log(meshAttributes.ToString("\n"));
string str = z_EditorUtility.FindPolybrushMetaDataForShader(meshAttributesContainer.shader);
if(!string.IsNullOrEmpty(str))
{
TextAsset asset = AssetDatabase.LoadAssetAtPath<TextAsset>(str);
if(asset != null)
EditorGUIUtility.PingObject(asset);
else
Debug.LogWarning("No MetaData found for Shader \"" + meshAttributesContainer.shader.name + "\"");
}
else
{
Debug.LogWarning("No MetaData found for Shader \"" + meshAttributesContainer.shader.name + "\"");
}
}
GUILayout.EndHorizontal();
GUILayout.Space(4);
if(GUILayout.Button("rebuild targets"))
RebuildColorTargets(brushColor, brushSettings.strength);
GUILayout.Label(brushColor != null ? brushColor.ToString() : "brush color: null\n");
#endif
}
}
public override void OnBrushSettingsChanged(z_BrushTarget target, z_BrushSettings settings)
{
base.OnBrushSettingsChanged(target, settings);
RebuildColorTargets(brushColor, settings.strength);
}
/**
* Test a gameObject and it's mesh renderers for compatible shaders, and if one is found
* load it's attribute data into meshAttributes.
*/
private bool CheckForTextureBlendSupport(GameObject go)
{
z_AttributeLayoutContainer detectedMeshAttributes;
foreach(Material mat in z_Util.GetMaterials(go))
{
if(z_ShaderUtil.GetMeshAttributes(mat, out detectedMeshAttributes))
{
meshAttributesContainer = detectedMeshAttributes;
return true;
}
}
return false;
}
private void SetBrushColorWithAttributeIndex(int index)
{
if( brushColor == null ||
meshAttributes == null ||
index < 0 ||
index >= meshAttributes.Length)
return;
selectedAttributeIndex = index;
if(meshAttributes[index].mask > -1)
{
for(int i = 0; i < meshAttributes.Length; i++)
{
if(meshAttributes[i].mask == meshAttributes[index].mask)
brushColor.SetAttributeValue(meshAttributes[i], meshAttributes[i].min);
}
}
brushColor.SetAttributeValue(meshAttributes[index], meshAttributes[index].max);
}
private void RebuildColorTargets(z_SplatWeight blend, float strength)
{
if(blend == null || splat_cache == null || splat_target == null)
return;
minWeights = splat_target.GetMinWeights();
splat_target.LerpWeights(splat_cache, blend, strength);
splat_erase.LerpWeights(splat_cache, minWeights, strength);
}
private void RebuildCaches(z_Mesh m, float strength)
{
vertexCount = m.vertexCount;
triangleLookup = z_MeshUtility.GetAdjacentTriangles(m);
if(meshAttributes == null)
{
// clear caches
splat_cache = null;
splat_current = null;
splat_target = null;
splat_erase = null;
return;
}
splat_cache = new z_SplatSet(m, meshAttributes);
splat_current = new z_SplatSet(splat_cache);
splat_target = new z_SplatSet(vertexCount, meshAttributes);
splat_erase = new z_SplatSet(vertexCount, meshAttributes);
}
// Called when the mouse begins hovering an editable object.
public override void OnBrushEnter(z_EditableObject target, z_BrushSettings settings)
{
base.OnBrushEnter(target, settings);
if(target.editMesh == null)
return;
likelySupportsTextureBlending = CheckForTextureBlendSupport(target.gameObject);
if(likelySupportsTextureBlending && (brushColor == null || !brushColor.MatchesAttributes(meshAttributes)))
{
brushColor = new z_SplatWeight( z_SplatWeight.GetChannelMap(meshAttributes) );
SetBrushColorWithAttributeIndex( z_Math.Clamp(selectedAttributeIndex, 0, meshAttributes.Length - 1) );
}
RebuildCaches(target.editMesh, settings.strength);
RebuildColorTargets(brushColor, settings.strength);
}
// Called whenever the brush is moved. Note that @target may have a null editableObject.
public override void OnBrushMove(z_BrushTarget target, z_BrushSettings settings)
{
base.OnBrushMove(target, settings);
if(!z_Util.IsValid(target) || !likelySupportsTextureBlending)
return;
bool shift = Event.current.shift;
float[] weights;
if(paintMode == z_PaintMode.Brush)
{
weights = target.GetAllWeights();
}
else if(paintMode == z_PaintMode.Flood)
{
weights = new float[vertexCount];
for(int i = 0; i < vertexCount; i++)
weights[i] = 1f;
}
else
{
weights = new float[vertexCount];
int[] indices = target.editableObject.editMesh.GetTriangles();
int index = 0;
float weightTarget = shift ? 0f : 1f;
foreach(z_RaycastHit hit in target.raycastHits)
{
if(hit.triangle > -1)
{
index = hit.triangle * 3;
_fillModeEdges[0].x = indices[index+0];
_fillModeEdges[0].y = indices[index+1];
_fillModeEdges[1].x = indices[index+1];
_fillModeEdges[1].y = indices[index+2];
_fillModeEdges[2].x = indices[index+2];
_fillModeEdges[2].y = indices[index+0];
for(int i = 0; i < 3; i++)
{
if(triangleLookup.TryGetValue(_fillModeEdges[i], out _fillModeAdjacentTris))
{
for(int n = 0; n < _fillModeAdjacentTris.Count; n++)
{
index = _fillModeAdjacentTris[n] * 3;
weights[indices[index ]] = weightTarget;
weights[indices[index+1]] = weightTarget;
weights[indices[index+2]] = weightTarget;
}
}
}
}
}
}
if(selectedAttributeIndex < 0 || selectedAttributeIndex >= meshAttributes.Length)
SetBrushColorWithAttributeIndex(0);
int mask = meshAttributes[selectedAttributeIndex].mask;
splat_current.LerpWeights(splat_cache, shift ? splat_erase : splat_target, mask, weights);
splat_current.Apply(target.editableObject.editMesh);
target.editableObject.ApplyMeshAttributes();
}
// Called when the mouse exits hovering an editable object.
public override void OnBrushExit(z_EditableObject target)
{
base.OnBrushExit(target);
if(splat_cache != null)
{
splat_cache.Apply(target.editMesh);
target.ApplyMeshAttributes();
target.graphicsMesh.UploadMeshData(false);
}
likelySupportsTextureBlending = true;
}
// Called every time the brush should apply itself to a valid target. Default is on mouse move.
public override void OnBrushApply(z_BrushTarget target, z_BrushSettings settings)
{
if(!likelySupportsTextureBlending)
return;
splat_current.CopyTo(splat_cache);
splat_cache.Apply(target.editableObject.editMesh);
base.OnBrushApply(target, settings);
}
// set mesh splat_current back to their original state before registering for undo
public override void RegisterUndo(z_BrushTarget brushTarget)
{
if(splat_cache != null)
{
splat_cache.Apply(brushTarget.editableObject.editMesh);
brushTarget.editableObject.ApplyMeshAttributes();
}
base.RegisterUndo(brushTarget);
}
public override void DrawGizmos(z_BrushTarget target, z_BrushSettings settings)
{
z_Mesh mesh = target.editableObject.editMesh;
if(z_Util.IsValid(target) && paintMode == z_PaintMode.Fill)
{
Vector3[] vertices = mesh.vertices;
int[] indices = mesh.GetTriangles();
z_Handles.PushMatrix();
z_Handles.PushHandleColor();
Handles.matrix = target.transform.localToWorldMatrix;
int index = 0;
foreach(z_RaycastHit hit in target.raycastHits)
{
if(hit.triangle > -1)
{
Handles.color = Color.green;
index = hit.triangle * 3;
Handles.DrawLine(vertices[indices[index+0]] + hit.normal * .1f, vertices[indices[index+1]] + hit.normal * .1f);
Handles.DrawLine(vertices[indices[index+1]] + hit.normal * .1f, vertices[indices[index+2]] + hit.normal * .1f);
Handles.DrawLine(vertices[indices[index+2]] + hit.normal * .1f, vertices[indices[index+0]] + hit.normal * .1f);
_fillModeEdges[0].x = indices[index+0];
_fillModeEdges[0].y = indices[index+1];
_fillModeEdges[1].x = indices[index+1];
_fillModeEdges[1].y = indices[index+2];
_fillModeEdges[2].x = indices[index+2];
_fillModeEdges[2].y = indices[index+0];
for(int i = 0; i < 3; i++)
{
if(triangleLookup.TryGetValue(_fillModeEdges[i], out _fillModeAdjacentTris))
{
for(int n = 0; n < _fillModeAdjacentTris.Count; n++)
{
index = _fillModeAdjacentTris[n] * 3;
Handles.DrawLine(vertices[indices[index+0]] + hit.normal * .1f, vertices[indices[index+1]] + hit.normal * .1f);
Handles.DrawLine(vertices[indices[index+1]] + hit.normal * .1f, vertices[indices[index+2]] + hit.normal * .1f);
Handles.DrawLine(vertices[indices[index+2]] + hit.normal * .1f, vertices[indices[index+0]] + hit.normal * .1f);
}
}
}
}
}
z_Handles.PopHandleColor();
z_Handles.PopMatrix();
}
else
{
base.DrawGizmos(target, settings);
}
}
}
}

12
Assets/ProCore/Polybrush/Code/Editor/Brush Modes/z_BrushModeTexture.cs.meta


fileFormatVersion: 2
guid: 58e885a4808b3ed4b884ae57bc1a2d26
timeCreated: 1450794133
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

9
Assets/ProCore/Polybrush/Code/Editor/Classes.meta


fileFormatVersion: 2
guid: 84c813a34d1fec9479a07683c4c91902
folderAsset: yes
timeCreated: 1445006243
licenseType: Store
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

134
Assets/ProCore/Polybrush/Code/Editor/Classes/z_BrushSettings.cs


using UnityEngine;
namespace Polybrush
{
/**
* Collection of settings for a sculpting brush.
*/
[CreateAssetMenuAttribute(menuName = "Polybrush/Brush Settings Preset", fileName = "Brush Settings", order = 800)]
[System.Serializable]
public class z_BrushSettings : ScriptableObject, z_IHasDefault
{
public float brushRadiusMin = 0.001f;
public float brushRadiusMax = 10f;
/// The total affected radius of this brush.
[SerializeField] private float _radius = 1f;
/// At what point the strength of the brush begins to taper off.
[SerializeField] float _falloff = .5f;
/// How may times per-second a mouse click will apply a brush stroke.
[SerializeField] float _strength = 10f;
[SerializeField] AnimationCurve _curve = new AnimationCurve(
new Keyframe(0f, 1f),
new Keyframe(1f, 0f, -3f, -3f)
);
public AnimationCurve falloffCurve
{
get
{
return _curve;
}
set
{
_curve = allowNonNormalizedFalloff ? value : z_Util.ClampAnimationKeys(value, 0f, 1f, 1f, 0f);
}
}
/// If true, the falloff curve won't be clamped to keyframes at 0,0 and 1,1.
public bool allowNonNormalizedFalloff = false;
/// The total affected radius of this brush.
public float radius
{
get
{
return _radius;
}
set
{
_radius = Mathf.Clamp(value, brushRadiusMin, brushRadiusMax);
}
}
/// At what point the strength of the brush begins to taper off.
/// 0 means the strength tapers from the center of the brush to the edge.
/// 1 means the strength is 100% all the way through the brush.
/// .5 means the strength is 100% through 1/2 the radius then tapers to the edge.
public float falloff
{
get
{
return _falloff;
}
set
{
_falloff = Mathf.Clamp(value, 0f, 1f);
}
}
public float strength
{
get
{
return _strength;
}
set
{
_strength = Mathf.Clamp(value, 0f, 1f);
}
}
/**
* Radius value scaled to 0-1.
*/
public float normalizedRadius
{
get
{
return (_radius - brushRadiusMin) / (brushRadiusMax - brushRadiusMin);
}
}
/**
* Set the object's default values.
*/
public void SetDefaultValues()
{
brushRadiusMin = 0.001f;
brushRadiusMax = 5f;
radius = 1f;
falloff = .5f;
strength = 1f;
}
public z_BrushSettings DeepCopy()
{
z_BrushSettings copy = ScriptableObject.CreateInstance<z_BrushSettings>();
this.CopyTo(copy);
return copy;
}
/**
* Copy all properties to target
*/
public void CopyTo(z_BrushSettings target)
{
target.name = this.name;
target.brushRadiusMin = this.brushRadiusMin;
target.brushRadiusMax = this.brushRadiusMax;
target._radius = this._radius;
target._falloff = this._falloff;
target._strength = this._strength;
target._curve = new AnimationCurve(this._curve.keys);
target.allowNonNormalizedFalloff = this.allowNonNormalizedFalloff;
}
}
}

12
Assets/ProCore/Polybrush/Code/Editor/Classes/z_BrushSettings.cs.meta


fileFormatVersion: 2
guid: 0c229c73eab51b9478029375e5ca314a
timeCreated: 1445009323
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

100
Assets/ProCore/Polybrush/Code/Editor/Classes/z_BrushTarget.cs


using UnityEngine;
using System.Collections.Generic;
using System.Linq;
namespace Polybrush
{
/**
* Stores information about the object a brush is currently hovering.
*/
public class z_BrushTarget : z_IValid
{
// List of hit locations on this target mesh.
public List<z_RaycastHit> raycastHits = new List<z_RaycastHit>();
private float[] _weights = null;
// The GameObject the brush is currently hovering.
[SerializeField] z_EditableObject _editableObject = null;
// Getter for editableObject target
public z_EditableObject editableObject { get { return _editableObject; } }
// Convenience getter for editableObject.gameObject
public GameObject gameObject { get { return editableObject == null ? null : editableObject.gameObject; } }
// Convenience getter for editableObject.gameObject.transform
public Transform transform { get { return editableObject == null ? null : editableObject.gameObject.transform; } }
// Convenience getter for gameObject.transform.localToWorldMatrix
public Matrix4x4 localToWorldMatrix { get { return editableObject == null ? Matrix4x4.identity : editableObject.gameObject.transform.localToWorldMatrix; } }
// Convenience getter for editableObject.editMesh.vertexCount
public int vertexCount { get { return _editableObject.editMesh.vertexCount; } }
/**
* Constructor.
*/
public z_BrushTarget(z_EditableObject editableObject) : this(editableObject, new List<z_RaycastHit>()) {}
/**
* Explicit constructor.
*/
public z_BrushTarget(z_EditableObject editableObject, List<z_RaycastHit> hits)
{
this.raycastHits = hits;
this._editableObject = editableObject;
this._weights = new float[this._editableObject.editMesh.vertexCount];
}
~z_BrushTarget()
{}
public void ClearRaycasts()
{
foreach(z_RaycastHit hit in raycastHits)
hit.ReleaseWeights();
raycastHits.Clear();
}
/**
* Returns an array of weights where each index is the max of all raycast hits.
*/
public float[] GetAllWeights(bool rebuildCache = false)
{
z_Mesh mesh = editableObject.editMesh;
int vertexCount = mesh.vertexCount;
if(mesh == null)
return null;
if(!rebuildCache)
return _weights;
for(int i = 0; i < vertexCount; i++)
_weights[i] = 0f;
for(int i = 0; i < raycastHits.Count; i++)
{
if(raycastHits[i].weights != null)
{
float[] w = raycastHits[i].weights;
for(int n = 0; n < vertexCount; n++)
if(w[n] > _weights[n])
_weights[n] = w[n];
}
}
return _weights;
}
public bool IsValid { get { return editableObject.IsValid(); } }
public override string ToString()
{
return string.Format("valid: {0}\nvertices: {1}", IsValid, IsValid ? editableObject.vertexCount : 0);
}
}
}

12
Assets/ProCore/Polybrush/Code/Editor/Classes/z_BrushTarget.cs.meta


fileFormatVersion: 2
guid: 46a79edf648201540b38d44a61ac983f
timeCreated: 1445192091
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

47
Assets/ProCore/Polybrush/Code/Editor/Classes/z_ColorPalette.cs


using UnityEngine;
using System.Collections.Generic;
namespace Polybrush
{
/**
* A set of colors.
*/
[CreateAssetMenuAttribute(menuName = "Polybrush/Color Palette", fileName = "Color Palette", order = 801)]
[System.Serializable]
public class z_ColorPalette : ScriptableObject, z_IHasDefault
{
// The currently selected color.
public Color current = Color.white;
// All colors in this palette.
public List<Color> colors;
public void SetDefaultValues()
{
colors = new List<Color>()
{
new Color(0.000f, 0.122f, 0.247f, 1f),
new Color(0.000f, 0.455f, 0.851f, 1f),
new Color(0.498f, 0.859f, 1.000f, 1f),
new Color(0.224f, 0.800f, 0.800f, 1f),
new Color(0.239f, 0.600f, 0.439f, 1f),
new Color(0.180f, 0.800f, 0.251f, 1f),
new Color(0.004f, 1.000f, 0.439f, 1f),
new Color(1.000f, 0.863f, 0.000f, 1f),
new Color(1.000f, 0.522f, 0.106f, 1f),
new Color(1.000f, 0.255f, 0.212f, 1f),
new Color(0.522f, 0.078f, 0.294f, 1f),
new Color(0.941f, 0.071f, 0.745f, 1f),
new Color(0.694f, 0.051f, 0.788f, 1f),
new Color(0.067f, 0.067f, 0.067f, 1f),
new Color(0.667f, 0.667f, 0.667f, 1f),
new Color(0.867f, 0.867f, 0.867f, 1f)
};
}
public void CopyTo(z_ColorPalette target)
{
target.colors = new List<Color>(colors);
}
}
}

12
Assets/ProCore/Polybrush/Code/Editor/Classes/z_ColorPalette.cs.meta


fileFormatVersion: 2
guid: faf7db05d259ffb47b2b158a2e462d2a
timeCreated: 1447173764
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

4
Assets/ProCore/Polybrush/Code/Editor/Classes/z_Delegate.cs


namespace Polybrush
{
public delegate void Delegate<T>(T value);
}

12
Assets/ProCore/Polybrush/Code/Editor/Classes/z_Delegate.cs.meta


fileFormatVersion: 2
guid: 90ccea956493f2d489e82ceb6126f6bb
timeCreated: 1447251751
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

507
Assets/ProCore/Polybrush/Code/Editor/Classes/z_EditableObject.cs


using UnityEngine;
using UnityEditor;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using System.Linq;
namespace Polybrush
{
/**
* Stores a cache of the unmodified mesh and meshrenderer
* so that the z_Editor can work non-destructively. Also
* handles ProBuilder compatibility so that brush modes don't
* have to deal with it.
*/
public class z_EditableObject : IEquatable<z_EditableObject>, z_IValid
{
const string INSTANCE_MESH_GUID = null;
private static HashSet<string> UnityPrimitiveMeshNames = new HashSet<string>()
{
"Sphere",
"Capsule",
"Cylinder",
"Cube",
"Plane",
"Quad"
};
// The GameObject being modified.
public GameObject gameObject = null;
// The mesh that is
private Mesh _graphicsMesh = null;
public Mesh graphicsMesh { get { return _graphicsMesh; } }
[System.Obsolete("Use graphicsMesh or editMesh instead")]
public Mesh mesh { get { return _graphicsMesh; } }
private z_Mesh _editMesh = null;
public z_Mesh editMesh { get { return _editMesh; } }
// The original mesh. Can be the same as mesh.
public Mesh originalMesh { get; private set; }
// Where this mesh originated.
public z_ModelSource source { get; private set; }
// If mesh was an asset or model, save the original GUID
// public string sourceGUID { get; private set; }
// Marks this object as having been modified.
public bool modified = false;
private T GetAttribute<T>(System.Func<Mesh, T> getter) where T : IList
{
if(usingVertexStreams)
{
int vertexCount = originalMesh.vertexCount;
T arr = getter(this.graphicsMesh);
if(arr != null && arr.Count == vertexCount)
return arr;
}
return getter(originalMesh);
}
/**
* Return a mesh that is the combination of both additionalVertexStreams and the originalMesh.
* - Position
* - UV0
* - UV2
* - UV3
* - UV4
* - Color
* - Tangent
* If usingVertexStreams is false, null is returned.
*/
private z_Mesh GetCompositeMesh()
{
if(_editMesh == null)
_editMesh = new z_Mesh();
_editMesh.Clear();
_editMesh.name = originalMesh.name;
_editMesh.vertices = GetAttribute<Vector3[]>(x => { return x.vertices; } );
_editMesh.normals = GetAttribute<Vector3[]>(x => { return x.normals; } );
_editMesh.colors = GetAttribute<Color32[]>(x => { return x.colors32; } );
_editMesh.tangents = GetAttribute<Vector4[]>(x => { return x.tangents; } );
_editMesh.uv0 = GetAttribute<List<Vector4>>(x => { List<Vector4> l = new List<Vector4>(); x.GetUVs(0, l); return l; } );
_editMesh.uv1 = GetAttribute<List<Vector4>>(x => { List<Vector4> l = new List<Vector4>(); x.GetUVs(1, l); return l; } );
_editMesh.uv2 = GetAttribute<List<Vector4>>(x => { List<Vector4> l = new List<Vector4>(); x.GetUVs(2, l); return l; } );
_editMesh.uv3 = GetAttribute<List<Vector4>>(x => { List<Vector4> l = new List<Vector4>(); x.GetUVs(3, l); return l; } );
_editMesh.subMeshCount = originalMesh.subMeshCount;
for(int i = 0; i < _editMesh.subMeshCount; i++)
_editMesh.SetTriangles(originalMesh.GetTriangles(i), i);
return _editMesh;
}
public int vertexCount { get { return originalMesh.vertexCount; } }
// Convenience getter for gameObject.GetComponent<MeshFilter>().
public MeshFilter meshFilter { get; private set; }
// Convenience getter for gameObject.transform
public Transform transform { get { return gameObject.transform; } }
// Convenience getter for gameObject.renderer
public Renderer renderer { get { return gameObject.GetComponent<MeshRenderer>(); } }
// If this object's mesh has been edited, isDirty will be flagged meaning that the mesh should not be
// cleaned up when finished editing.
public bool isDirty = false;
// Is the mesh owned by ProBuilder?
public bool isProBuilderObject { get; private set; }
// Reference to the pb_Object component (if it exists)
[SerializeField] private object probuilderMesh = null;
// Is the mesh using additional vertex streams?
public bool usingVertexStreams { get; private set; }
// Container for additionalVertexStreams. @todo remove when Unity fixes
public z_AdditionalVertexStreams additionalVertexStreams;
// Did this mesh already have an additionalVertexStreams mesh?
private bool hadVertexStreams = true;
/// <summary>
/// Shorthand for checking if object and mesh are non-null.
/// </summary>
public bool IsValid
{
get
{
if(gameObject == null || graphicsMesh == null)
return false;
if(isProBuilderObject && probuilderMesh != null)
{
object vertexCount = z_ReflectionUtil.GetValue(probuilderMesh, z_ReflectionUtil.ProBuilderObjectType, "vertexCount");
if(vertexCount != null)
{
if(_editMesh != null && _editMesh.vertexCount != (int)vertexCount)
{
return false;
}
}
}
return true;
}
}
/**
* Public constructor for editable objects. Guarantees that a mesh
* is editable and takes care of managing the asset.
*/
public static z_EditableObject Create(GameObject go)
{
if(go == null)
return null;
MeshFilter mf = go.GetComponent<MeshFilter>();
SkinnedMeshRenderer sf = go.GetComponent<SkinnedMeshRenderer>();
if(!mf && !sf)
{
mf = go.GetComponentsInChildren<MeshFilter>().FirstOrDefault();
sf = go.GetComponentsInChildren<SkinnedMeshRenderer>().FirstOrDefault();
}
if((mf == null || mf.sharedMesh == null) && (sf == null || sf.sharedMesh == null))
return null;
return new z_EditableObject(go);
}
/**
* Internal constructor.
* \sa Create
*/
private z_EditableObject(GameObject go)
{
this.gameObject = go;
isProBuilderObject = z_ReflectionUtil.IsProBuilderObject(go);
Mesh advsMesh = null;
MeshRenderer meshRenderer = this.gameObject.GetComponent<MeshRenderer>();
meshFilter = this.gameObject.GetComponent<MeshFilter>();
SkinnedMeshRenderer skinFilter = this.gameObject.GetComponent<SkinnedMeshRenderer>();
usingVertexStreams = false;
this.originalMesh = meshFilter.sharedMesh;
if(originalMesh == null && skinFilter != null)
this.originalMesh = skinFilter.sharedMesh;
if( z_Pref.GetBool(z_Pref.additionalVertexStreams, false) && !isProBuilderObject)
{
if(meshRenderer != null || skinFilter != null)
{
additionalVertexStreams = gameObject.GetComponent<z_AdditionalVertexStreams>();
if(additionalVertexStreams == null)
additionalVertexStreams = gameObject.AddComponent<z_AdditionalVertexStreams>();
advsMesh = additionalVertexStreams.m_AdditionalVertexStreamMesh;
if(advsMesh == null)
{
advsMesh = new Mesh();
advsMesh.vertices = originalMesh.vertices;
advsMesh.name = string.Format("{0}({1})", originalMesh.name, additionalVertexStreams.GetInstanceID());
hadVertexStreams = false;
}
usingVertexStreams = true;
}
}
if(!usingVertexStreams)
{
// if editing a non-scene instance mesh, make it an instance
// (unity primitives are a special case - they *are* scene instances but they also aren't)
string guid = INSTANCE_MESH_GUID;
this.source = z_EditorUtility.GetMeshGUID(originalMesh, ref guid);
if(source != z_ModelSource.Scene || UnityPrimitiveMeshNames.Contains(originalMesh.name))
this._graphicsMesh = z_MeshUtility.DeepCopy(meshFilter.sharedMesh);
else
this._graphicsMesh = originalMesh;
}
else
{
this._graphicsMesh = advsMesh;
this.source = z_ModelSource.AdditionalVertexStreams;
}
// if it's a probuilder object rebuild the mesh without optimization
if( isProBuilderObject )
{
object pb = probuilderMesh = go.GetComponent("pb_Object");
if(pb != null)
{
z_ReflectionUtil.ProBuilder_ToMesh(pb);
z_ReflectionUtil.ProBuilder_Refresh(pb, (ushort) 0xFF);
}
if(setVerticesMethod == null)
{
setVerticesMethod = pb.GetType().GetMethod(
"SetVertices",
BindingFlags.Public | BindingFlags.Instance,
null,
SetVerticesArguments,
null);
}
if(setUvsMethod == null)
{
setUvsMethod = pb.GetType().GetMethod(
"SetUVs",
BindingFlags.Public | BindingFlags.Instance,
null,
SetUVsArguments,
null);
}
if(setTangentsMethod == null)
{
setTangentsMethod = pb.GetType().GetMethod(
"SetTangents",
BindingFlags.Public | BindingFlags.Instance,
null,
new Type[] { typeof(Vector4[]) },
null);
}
if(setColorsMethod == null)
{
setColorsMethod = pb.GetType().GetMethod(
"SetColors",
BindingFlags.Public | BindingFlags.Instance,
null,
new Type[] { typeof(Color[]) },
null);
}
}
_editMesh = GetCompositeMesh();
if(!isProBuilderObject)
SetMesh(graphicsMesh);
}
~z_EditableObject()
{
// clean up the composite mesh (if required)
// delayCall ensures Destroy is called on main thread
// if(editMesh != null)
// EditorApplication.delayCall += () => { GameObject.DestroyImmediate(editMesh); };
}
/**
* Sets the MeshFilter.sharedMesh or SkinnedMeshRenderer.sharedMesh to @mesh.
*/
private void SetMesh(Mesh m)
{
if( gameObject != null )
{
if(usingVertexStreams)
{
additionalVertexStreams.SetAdditionalVertexStreamsMesh(m);
}
else
{
MeshFilter meshFilter = gameObject.GetComponent<MeshFilter>();
if(meshFilter != null)
{
meshFilter.sharedMesh = m;
}
else
{
SkinnedMeshRenderer mr = gameObject.GetComponent<SkinnedMeshRenderer>();
if(mr != null)
mr.sharedMesh = m;
}
}
}
}
private static readonly Type[] SetVerticesArguments = new Type[] { typeof(Vector3[]) };
private static readonly Type[] SetUVsArguments = new Type[] { typeof(int), typeof(List<Vector4>) };
private static MethodInfo setVerticesMethod;
private static MethodInfo setColorsMethod;
private static MethodInfo setTangentsMethod;
private static MethodInfo setUvsMethod;
/**
* Applies mesh changes back to the pb_Object (if necessary). Optionally does a
* mesh rebuild.
* @rebuildMesh only applies to ProBuilder meshes.
* @optimize determines if the mesh collisions are rebuilt (if that option is enabled) or if
* the mehs is a probuilder object, the mesh is optimized (condensed to share verts, other
* otpimziations etc)
*/
public void Apply(bool rebuildMesh, bool optimize = false)
{
if(usingVertexStreams)
{
if( z_Pref.GetBool(z_Pref.rebuildNormals) )
z_MeshUtility.RecalculateNormals(editMesh);
editMesh.ApplyAttributesToUnityMesh(graphicsMesh);
graphicsMesh.UploadMeshData(false);
EditorUtility.SetDirty(gameObject.GetComponent<MeshRenderer>());
return;
}
// if it's a probuilder object rebuild the mesh without optimization
if( isProBuilderObject )
{
object pb = probuilderMesh;
if(pb != null)
{
// Set the pb_Object.vertices array so that pb_Editor.UpdateSelection
// can draw the wireframes correctly.
if(setVerticesMethod != null)
setVerticesMethod.Invoke(pb, new object[] { editMesh.vertices } );
if(!optimize)
goto NonProbuilderMeshRebuild;
Color[] colors = System.Array.ConvertAll(editMesh.colors, x => (Color) x);
if(setColorsMethod != null && colors != null && colors.Length == vertexCount)
setColorsMethod.Invoke(pb, new object[] { colors } );
Vector4[] tangents = editMesh.tangents;
if(setTangentsMethod != null && tangents != null && tangents.Length == vertexCount)
setTangentsMethod.Invoke(pb, new object[] { tangents } );
// Check if UV3/4 have been modified
List<Vector4> uv3 = editMesh.GetUVs(2);
List<Vector4> uv4 = editMesh.GetUVs(3);
if(setUvsMethod != null && uv3.Count == vertexCount)
setUvsMethod.Invoke(pb, new object[] { 2, uv3 } );
if(setUvsMethod != null && uv4.Count == vertexCount)
setUvsMethod.Invoke(pb, new object[] { 3, uv4 } );
if(rebuildMesh)
{
z_ReflectionUtil.ProBuilder_ToMesh(pb);
z_ReflectionUtil.ProBuilder_Refresh(pb, (ushort) (optimize ? 0xFF : (0x2 | 0x4 | 0x8)));
}
return;
}
}
NonProbuilderMeshRebuild:
if( z_Pref.GetBool(z_Pref.rebuildNormals) )
z_MeshUtility.RecalculateNormals(editMesh);
editMesh.ApplyAttributesToUnityMesh(graphicsMesh);
graphicsMesh.RecalculateBounds();
// expensive call, delay til optimize is enabled.
if(z_Pref.GetBool(z_Pref.rebuildCollisions) && optimize)
{
MeshCollider mc = gameObject.GetComponent<MeshCollider>();
if(mc != null)
{
mc.sharedMesh = null;
mc.sharedMesh = graphicsMesh;
}
}
}
/**
* Apply the mesh channel attributes to the graphics mesh.
*/
public void ApplyMeshAttributes(z_MeshChannel channel = z_MeshChannel.All)
{
editMesh.ApplyAttributesToUnityMesh(_graphicsMesh, channel);
if(usingVertexStreams)
_graphicsMesh.UploadMeshData(false);
}
/**
* Set the MeshFilter or SkinnedMeshRenderer back to originalMesh.
*/
public void Revert()
{
if(usingVertexStreams)
{
if(!hadVertexStreams)
{
GameObject.DestroyImmediate(graphicsMesh);
MeshRenderer mr = gameObject.GetComponent<MeshRenderer>();
mr.additionalVertexStreams = null;
}
return;
}
if( originalMesh == null ||
(source == z_ModelSource.Scene && !UnityPrimitiveMeshNames.Contains(originalMesh.name)) ||
isProBuilderObject
)
{
if( isProBuilderObject )
Apply(true, true);
return;
}
if(graphicsMesh != null)
GameObject.DestroyImmediate(graphicsMesh);
SetMesh(originalMesh);
}
public bool Equals(z_EditableObject rhs)
{
return rhs.GetHashCode() == this.GetHashCode();
}
public override bool Equals(object rhs)
{
if(rhs == null)
return this.gameObject == null ? true : false;
else if(this.gameObject == null)
return false;
if(rhs is z_EditableObject)
return rhs.Equals(this);
else if(rhs is GameObject)
return ((GameObject)rhs).GetHashCode() == gameObject.GetHashCode();
return false;
}
public override int GetHashCode()
{
return gameObject != null ? gameObject.GetHashCode() : base.GetHashCode();
}
}
}

12
Assets/ProCore/Polybrush/Code/Editor/Classes/z_EditableObject.cs.meta


fileFormatVersion: 2
guid: 5e4f91c03ccd126459fa1e1c72a15ee3
timeCreated: 1445102105
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

66
Assets/ProCore/Polybrush/Code/Editor/Classes/z_LocalPref.cs


using System;
using UnityEngine;
namespace Polybrush
{
public class z_LocalPref<T> where T : IEquatable<T>
{
public string key;
[SerializeField] private T _value;
public T prefValue
{
get
{
return _value;
}
set
{
if( !_value.Equals(value) )
{
_value = value;
if( typeof(T) == typeof(bool) )
z_Pref.SetBool(key, (bool) ((object) _value));
else if( typeof(T) == typeof(Color) )
z_Pref.SetColor(key, (Color) ((object) _value));
else if( typeof(T) == typeof(int) )
z_Pref.SetInt(key, (int) ((object) _value));
else if( typeof(T) == typeof(float) )
z_Pref.SetFloat(key, (float) ((object) _value));
else if( typeof(T) == typeof(Gradient) )
z_Pref.SetGradient(key, (Gradient) ((object) _value));
}
}
}
public z_LocalPref(string key, T initialValueIfNoKey = default(T))
{
this.key = key;
// box and unbox because due to casting. not ideal, but the alternative is writing
// z_LocalPref overloads for each type.
if( typeof(T) == typeof(bool) )
this._value = (T)((object)z_Pref.GetBool(key, (bool) (object) initialValueIfNoKey));
else if( typeof(T) == typeof(Color) )
this._value = (T)((object)z_Pref.GetColor(key, (Color) (object) initialValueIfNoKey));
else if( typeof(T) == typeof(int) )
this._value = (T)((object)z_Pref.GetInt(key, (int) (object) initialValueIfNoKey));
else if( typeof(T) == typeof(float) )
this._value = (T)((object)z_Pref.GetFloat(key, (float) (object) initialValueIfNoKey));
else if( typeof(T) == typeof(Gradient) )
this._value = (T)((object)z_Pref.GetGradient(key));
else
this._value = default(T);
}
public static implicit operator T(z_LocalPref<T> pref)
{
if(pref != null)
return pref._value;
return default(T);
}
}
}

12
Assets/ProCore/Polybrush/Code/Editor/Classes/z_LocalPref.cs.meta


fileFormatVersion: 2
guid: 35ad3294bfb27254f9e56bee1d8029da
timeCreated: 1479745154
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

30
Assets/ProCore/Polybrush/Code/Editor/Classes/z_PrefabAndSettings.cs


using UnityEngine;
namespace Polybrush
{
[System.Serializable]
public class z_PlacementSettings
{
public Vector2 rotationRange;
public Vector2 scaleRange;
public z_PlacementSettings()
{
rotationRange = new Vector2(0f, 360f);
scaleRange = new Vector2(.7f, 1.3f);
}
}
[System.Serializable]
public class z_PrefabAndSettings
{
public GameObject gameObject;
public z_PlacementSettings settings;
public z_PrefabAndSettings(GameObject go)
{
gameObject = go;
settings = new z_PlacementSettings();
}
}
}

12
Assets/ProCore/Polybrush/Code/Editor/Classes/z_PrefabAndSettings.cs.meta


fileFormatVersion: 2
guid: b220878ed9d9d584cb091fcb07d21e0a
timeCreated: 1481037324
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

20
Assets/ProCore/Polybrush/Code/Editor/Classes/z_PrefabPalette.cs


using UnityEngine;
using System.Collections.Generic;
namespace Polybrush
{
/**
* A set of Prefabs.
*/
[CreateAssetMenuAttribute(menuName = "Polybrush/Prefab Palette", fileName = "Prefab Palette", order = 802)]
[System.Serializable]
public class z_PrefabPalette : ScriptableObject, z_IHasDefault
{
public List<z_PrefabAndSettings> prefabs;
public void SetDefaultValues()
{
prefabs = new List<z_PrefabAndSettings>() {};
}
}
}

12
Assets/ProCore/Polybrush/Code/Editor/Classes/z_PrefabPalette.cs.meta


fileFormatVersion: 2
guid: dc38003c0e0db6641a4762d4f392de52
timeCreated: 1447944558
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

220
Assets/ProCore/Polybrush/Code/Editor/Classes/z_PreferenceDictionary.cs


#if UNITY_EDITOR
using UnityEngine;
using UnityEditor;
using System.Linq;
using System.Collections.Generic;
namespace Polybrush
{
/**
* Store Polybrush settings in a project-local manner.
*/
public class z_PreferenceDictionary : ScriptableObject, ISerializationCallbackReceiver, z_IHasDefault
{
Dictionary<string, bool> m_bool = new Dictionary<string, bool>();
Dictionary<string, int> m_int = new Dictionary<string, int>();
Dictionary<string, float> m_float = new Dictionary<string, float>();
Dictionary<string, string> m_string = new Dictionary<string, string>();
Dictionary<string, Color> m_Color = new Dictionary<string, Color>();
[SerializeField] List<string> m_bool_keys;
[SerializeField] List<string> m_int_keys;
[SerializeField] List<string> m_float_keys;
[SerializeField] List<string> m_string_keys;
[SerializeField] List<string> m_Color_keys;
[SerializeField] List<bool> m_bool_values;
[SerializeField] List<int> m_int_values;
[SerializeField] List<float> m_float_values;
[SerializeField] List<string> m_string_values;
[SerializeField] List<Color> m_Color_values;
/**
* Perform the ritual "Please Serialize My Dictionary" dance.
*/
public void OnBeforeSerialize()
{
m_bool_keys = m_bool.Keys.ToList();
m_int_keys = m_int.Keys.ToList();
m_float_keys = m_float.Keys.ToList();
m_string_keys = m_string.Keys.ToList();
m_Color_keys = m_Color.Keys.ToList();
m_bool_values = m_bool.Values.ToList();
m_int_values = m_int.Values.ToList();
m_float_values = m_float.Values.ToList();
m_string_values = m_string.Values.ToList();
m_Color_values = m_Color.Values.ToList();
}
/**
* Reconstruct preference dictionaries from serialized lists.
*/
public void OnAfterDeserialize()
{
for(int i = 0; i < m_bool_keys.Count; i++)
m_bool.Add(m_bool_keys[i], m_bool_values[i]);
for(int i = 0; i < m_int_keys.Count; i++)
m_int.Add(m_int_keys[i], m_int_values[i]);
for(int i = 0; i < m_float_keys.Count; i++)
m_float.Add(m_float_keys[i], m_float_values[i]);
for(int i = 0; i < m_string_keys.Count; i++)
m_string.Add(m_string_keys[i], m_string_values[i]);
for(int i = 0; i < m_Color_keys.Count; i++)
m_Color.Add(m_Color_keys[i], m_Color_values[i]);
}
/**
* Clear dictionary values.
*/
public void SetDefaultValues()
{
m_bool.Clear();
m_int.Clear();
m_float.Clear();
m_string.Clear();
m_Color.Clear();
EditorUtility.SetDirty(this);
}
/**
* Check if a key is contained within any type dictionary.
*/
public bool HasKey(string key)
{
return m_bool.ContainsKey(key) ||
m_int.ContainsKey(key) ||
m_float.ContainsKey(key) ||
m_string.ContainsKey(key) ||
m_Color.ContainsKey(key);
}
/**
* Fetch a value from the stored preferences. If key is not found, a default value is returned.
*/
public bool GetBool(string key, bool fallback = default(bool))
{
bool value;
if(m_bool.TryGetValue(key, out value))
return value;
return fallback;
}
/**
* Fetch a value from the stored preferences. If key is not found, a default value is returned.
*/
public int GetInt(string key, int fallback = default(int))
{
int value;
if(m_int.TryGetValue(key, out value))
return value;
return fallback;
}
/**
* Fetch a value from the stored preferences. If key is not found, a default value is returned.
*/
public float GetFloat(string key, float fallback = default(float))
{
float value;
if(m_float.TryGetValue(key, out value))
return value;
return fallback;
}
/**
* Fetch a value from the stored preferences. If key is not found, a default value is returned.
*/
public string GetString(string key, string fallback = default(string))
{
string value;
if(m_string.TryGetValue(key, out value))
return value;
return fallback;
}
/**
* Fetch a value from the stored preferences. If key is not found, a default value is returned.
*/
public Color GetColor(string key, Color fallback = default(Color))
{
Color value;
if(m_Color.TryGetValue(key, out value))
return value;
return fallback;
}
/**
* Set a value for key in the saved prefs.
*/
public void SetBool(string key, bool value)
{
if(m_bool.ContainsKey(key))
m_bool[key] = value;
else
m_bool.Add(key, value);
EditorUtility.SetDirty(this);
}
/**
* Set a value for key in the saved prefs.
*/
public void SetInt(string key, int value)
{
if(m_int.ContainsKey(key))
m_int[key] = value;
else
m_int.Add(key, value);
EditorUtility.SetDirty(this);
}
/**
* Set a value for key in the saved prefs.
*/
public void SetFloat(string key, float value)
{
if(m_float.ContainsKey(key))
m_float[key] = value;
else
m_float.Add(key, value);
EditorUtility.SetDirty(this);
}
/**
* Set a value for key in the saved prefs.
*/
public void SetString(string key, string value)
{
if(m_string.ContainsKey(key))
m_string[key] = value;
else
m_string.Add(key, value);
EditorUtility.SetDirty(this);
}
/**
* Set a value for key in the saved prefs.
*/
public void SetColor(string key, Color value)
{
if(m_Color.ContainsKey(key))
m_Color[key] = value;
else
m_Color.Add(key, value);
EditorUtility.SetDirty(this);
}
}
}
#endif

12
Assets/ProCore/Polybrush/Code/Editor/Classes/z_PreferenceDictionary.cs.meta


fileFormatVersion: 2
guid: 35fc1a6584efa41f38b85fc9dd9d264e
timeCreated: 1479395024
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

77
Assets/ProCore/Polybrush/Code/Editor/Classes/z_RaycastHit.cs


using UnityEngine;
using System.Collections.Generic;
namespace Polybrush
{
/**
* A simplified version of UnityEngine.RaycastHit that only contains information we're interested in.
*/
public class z_RaycastHit
{
const int MAX_POOL_SIZE = 16;
private static Queue<float[]> weightPool = new Queue<float[]>();
/// Distance from the Raycast origin to the point of impact.
public float distance;
/// The position in model space where a raycast intercepted a triangle.
public Vector3 position;
/// The normal in model space of the triangle that this raycast hit.
public Vector3 normal;
/// The triangle index of the hit face.
public int triangle;
/// The vertices affected by this ray will have their weights stored here.
public float[] weights;
/**
* Constructor.
* \notes Tautological comments aren't very helpful.
*/
public z_RaycastHit(float InDistance, Vector3 InPosition, Vector3 InNormal, int InTriangle)
{
this.distance = InDistance;
this.position = InPosition;
this.normal = InNormal;
this.triangle = InTriangle;
this.weights = null;
}
~z_RaycastHit()
{
if(weights != null && weightPool.Count < MAX_POOL_SIZE)
weightPool.Enqueue(weights);
}
public void ReleaseWeights()
{
if(weights != null)
{
weightPool.Enqueue(weights);
weights = null;
}
}
public void SetVertexCount(int vertexCount)
{
if(weightPool.Count > 0)
weights = weightPool.Dequeue();
if(weights == null || weights.Length < vertexCount)
{
z_Debug.Log(string.Format("new alloc float[{0}]kb pool.size = {1}", (sizeof(float) * vertexCount) / 1024, weightPool.Count), "#FF0000FF");
weights = new float[vertexCount];
}
else
{
z_Debug.Log(string.Format("re-use float[{0}]kb pool.size = {1}", (sizeof(float) * vertexCount) / 1024, weightPool.Count), "green");
}
}
/**
* Prints a summary of this struct.
*/
public override string ToString()
{
return string.Format("p{0}, n{1}, w[{2}]", position, normal, weights == null ? "null" : weights.Length.ToString());
}
}
}

12
Assets/ProCore/Polybrush/Code/Editor/Classes/z_RaycastHit.cs.meta


fileFormatVersion: 2
guid: 2e9d8bd2456d3b9428d454b4229e82ec
timeCreated: 1445006621
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

437
Assets/ProCore/Polybrush/Code/Editor/Classes/z_ReflectionUtil.cs


using UnityEditor;
using UnityEngine;
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Linq;
namespace Polybrush
{
/// <summary>
/// Static helper methods for working with reflection. Mostly used for ProBuilder compatibility.
/// </summary>
static class z_ReflectionUtil
{
static EditorWindow m_PbEditor = null;
public static bool enableWarnings = true;
const BindingFlags k_AllFlags = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;
static MethodInfo m_ProBuilderOptimize = null;
static MethodInfo m_ProBuilderRefreshNoArgs = null;
static MethodInfo m_ProBuilderRefresh = null;
static MethodInfo m_ProBuilderToMeshNoArgs = null;
static Type m_ProBuilderObjectType = null;
static Type m_ProBuilderEditorType = null;
static object[] m_RefreshArgs = new object[1];
static Dictionary<string, Type> m_CachedTypes = new Dictionary<string, Type>();
static readonly string[] k_EditorMeshUtilityTypeNames = new string[]
{
"ProBuilder.EditorCore.pb_EditorMeshUtility",
"ProBuilder2.EditorCommon.pb_EditorMeshUtility",
"ProBuilder2.EditorCommon.pb_Editor_Mesh_Utility",
};
static readonly string[] k_EditorTypeNames = new string[]
{
"ProBuilder.EditorCore.pb_Editor",
"ProBuilder2.EditorCommon.pb_Editor",
};
static readonly string[] k_PbObjectNames = new string[]
{
"pb_Object",
"ProBuilder.Core.pb_Object"
};
internal static Type ProBuilderObjectType
{
get
{
for (int i = 0, c = k_PbObjectNames.Length; i < c && m_ProBuilderObjectType == null; i++)
m_ProBuilderObjectType = GetTypeCached(k_PbObjectNames[i]);
return m_ProBuilderObjectType;
}
}
internal static Type ProBuilderEditorType
{
get
{
for (int i = 0, c = k_EditorTypeNames.Length; i < c && m_ProBuilderEditorType == null; i++)
m_ProBuilderEditorType = GetTypeCached(k_EditorTypeNames[i]);
return m_ProBuilderEditorType;
}
}
static void Warning(string text)
{
if(enableWarnings)
Debug.LogWarning(text);
}
/// <summary>
/// Reference to the ProBuilder Editor window if it is avaiable.
/// </summary>
internal static EditorWindow ProBuilderEditorWindow
{
get
{
if(m_PbEditor == null)
{
EditorWindow[] windows = Resources.FindObjectsOfTypeAll<EditorWindow>();
m_PbEditor = windows.FirstOrDefault(x => x.GetType().ToString().Contains("pb_Editor"));
}
return m_PbEditor;
}
}
/// <summary>
/// Tests if ProBuilder is available in the project.
/// </summary>
/// <returns></returns>
internal static bool ProBuilderExists()
{
return ProBuilderObjectType != null;
}
/// <summary>
/// Tests if a GameObject is a ProBuilder mesh or not.
/// </summary>
/// <param name="gameObject"></param>
/// <returns></returns>
internal static bool IsProBuilderObject(GameObject gameObject)
{
return gameObject != null && gameObject.GetComponent("pb_Object") != null;
}
/// <summary>
/// Get a component with type name.
/// </summary>
/// <param name="gameObject"></param>
/// <param name="componentTypeName"></param>
/// <returns></returns>
internal static object GetComponent(this GameObject gameObject, string componentTypeName)
{
return gameObject.GetComponent(componentTypeName);
}
/// <summary>
/// Fetch a type with name and optional assembly name. `type` should include namespace.
/// </summary>
/// <param name="type"></param>
/// <param name="assembly"></param>
/// <returns></returns>
public static Type GetType(string type, string assembly = null)
{
Type t = Type.GetType(type);
if(t == null)
{
IEnumerable<Assembly> assemblies = AppDomain.CurrentDomain.GetAssemblies();
if(assembly != null)
assemblies = assemblies.Where(x => x.FullName.Contains(assembly));
foreach(Assembly ass in assemblies)
{
t = ass.GetType(type);
if(t != null)
return t;
}
}
return t;
}
/// <summary>
/// Same as GetType except this function caches the result for quick lookups.
/// </summary>
/// <param name="type"></param>
/// <param name="assembly"></param>
/// <returns></returns>
static Type GetTypeCached(string type, string assembly = null)
{
Type res = null;
if( m_CachedTypes.TryGetValue(type, out res) )
return res;
res = GetType(type);
m_CachedTypes.Add(type, res);
return res;
}
/// <summary>
/// Call a method with args.
/// </summary>
/// <param name="target"></param>
/// <param name="method"></param>
/// <param name="flags"></param>
/// <param name="args"></param>
/// <returns></returns>
public static object Invoke(object target,
string method,
BindingFlags flags = k_AllFlags,
params object[] args)
{
if(target == null)
{
Warning("Invoke failed, target is null and no type was provided.");
return null;
}
return Invoke(target, target.GetType(), method, null, flags, args);
}
public static object Invoke(object target,
string type,
string method,
BindingFlags flags = k_AllFlags,
string assembly = null,
params object[] args)
{
Type t = GetType(type, assembly);
if(t == null && target != null)
t = target.GetType();
if(t != null)
return Invoke(target, t, method, null, flags, args);
else
Warning("Invoke failed, type is null: " + type);
return null;
}
public static object Invoke(object target,
Type type,
string method,
Type[] methodParams = null,
BindingFlags flags = k_AllFlags,
params object[] args)
{
MethodInfo mi = null;
if(methodParams == null)
mi = type.GetMethod(method, flags);
else
mi = type.GetMethod(method, flags, null, methodParams, null);
if(mi == null)
{
Warning("Failed to find method " + method + " in type " + type);
return null;
}
return mi.Invoke(target, args);
}
/// <summary>
/// Fetch a value using GetProperty or GetField.
/// </summary>
/// <param name="target"></param>
/// <param name="type"></param>
/// <param name="member"></param>
/// <param name="flags"></param>
/// <returns></returns>
public static object GetValue(object target, string type, string member, BindingFlags flags = k_AllFlags)
{
Type t = GetType(type);
if(t == null)
{
Warning(string.Format("Could not find type \"{0}\"!", type));
return null;
}
else
return GetValue(target, t, member, flags);
}
public static object GetValue(object target, Type type, string member, BindingFlags flags = k_AllFlags)
{
PropertyInfo pi = type.GetProperty(member, flags);
if(pi != null)
return pi.GetValue(target, null);
FieldInfo fi = type.GetField(member, flags);
if(fi != null)
return fi.GetValue(target);
Warning(string.Format("Could not find member \"{0}\" matching type {1}!", member, type));
return null;
}
public static bool SetValue(object target, string member, object value, BindingFlags flags = k_AllFlags)
{
if(target == null)
return false;
PropertyInfo pi = target.GetType().GetProperty(member, flags);
if(pi != null)
pi.SetValue(target, value, flags, null, null, null);
FieldInfo fi = target.GetType().GetField(member, flags);
if(fi != null)
fi.SetValue(target, value);
return pi != null || fi != null;
}
public static MethodInfo ProBuilder_OptimizeMethodInfo()
{
if(m_ProBuilderOptimize == null)
{
Type editorMeshUtilityType = null;
for(int i = 0, c = k_EditorMeshUtilityTypeNames.Length; i < c && editorMeshUtilityType == null; i++)
editorMeshUtilityType = z_ReflectionUtil.GetType(k_EditorMeshUtilityTypeNames[i]);
if(editorMeshUtilityType != null)
{
// 2.5.1
m_ProBuilderOptimize = editorMeshUtilityType.GetMethod("Optimize",
BindingFlags.Public | BindingFlags.Static,
null,
new Type[] { ProBuilderObjectType, typeof(bool) },
null );
if(m_ProBuilderOptimize == null)
{
m_ProBuilderOptimize = editorMeshUtilityType.GetMethod("Optimize",
BindingFlags.Public | BindingFlags.Static,
null,
new Type[] { ProBuilderObjectType },
null );
}
}
}
return m_ProBuilderOptimize;
}
/// <summary>
/// Fallback for ProBuilder 2.6.1 and lower (Refresh() with no params).
/// </summary>
/// <returns></returns>
static MethodInfo ProBuilder_RefreshMethodInfo()
{
if(m_ProBuilderRefreshNoArgs == null)
{
m_ProBuilderRefreshNoArgs = ProBuilderObjectType.GetMethod(
"Refresh",
BindingFlags.Public | BindingFlags.Instance);
}
return m_ProBuilderRefreshNoArgs;
}
static MethodInfo ProBuilder_RefreshWithMaskMethodInfo()
{
if(m_ProBuilderRefresh == null)
{
Type refreshMaskType = GetTypeCached("ProBuilder.Core.RefreshMask");
if(refreshMaskType == null)
refreshMaskType = GetTypeCached("ProBuilder2.Common.RefreshMask");
if(refreshMaskType == null)
return null;
m_ProBuilderRefresh = ProBuilderObjectType.GetMethod(
"Refresh",
BindingFlags.Public | BindingFlags.Instance,
null,
new Type[] { refreshMaskType },
null);
}
return m_ProBuilderRefresh;
}
/// <summary>
/// Calls pb_EditorUtility.Optimize
/// </summary>
/// <param name="pb"></param>
public static void ProBuilder_Optimize(object pb)
{
MethodInfo mi = ProBuilder_OptimizeMethodInfo();
if(mi == null)
return;
ParameterInfo[] pi = mi.GetParameters();
if(pi == null)
return;
object[] args = new object[pi.Length];
args[0] = pb;
// HasDefaultValue not available until .NET 4.5
for(int i = 1; i < pi.Length; i++)
args[i] = pi[i].DefaultValue;
mi.Invoke(null, args);
}
public static void ProBuilder_Refresh(object pb, ushort mask = 0xFF)
{
MethodInfo refresh = ProBuilder_RefreshWithMaskMethodInfo();
if(refresh != null)
{
m_RefreshArgs[0] = mask;
refresh.Invoke(pb, m_RefreshArgs);
}
else
{
refresh = ProBuilder_RefreshMethodInfo();
if(refresh != null)
refresh.Invoke(pb, null);
else
Debug.LogWarning("ProBuilder_Refresh failed to find an appropriate `Refresh` method on `pb_Object` type");
}
}
static MethodInfo ProBuilderToMeshNoArgsMethodInfo
{
get
{
if (m_ProBuilderToMeshNoArgs == null)
{
m_ProBuilderToMeshNoArgs = ProBuilderObjectType.GetMethod(
"ToMesh",
BindingFlags.Public | BindingFlags.Instance,
null,
Type.EmptyTypes,
null);
}
return m_ProBuilderToMeshNoArgs;
}
}
public static void ProBuilder_ToMesh(object pb, MeshTopology topology = MeshTopology.Quads)
{
if (ProBuilderToMeshNoArgsMethodInfo == null)
{
Debug.LogWarning("ProBuilder_ToMesh failed to find an appropriate `ToMesh` method on `pb_Object` type");
return;
}
ProBuilderToMeshNoArgsMethodInfo.Invoke(pb, null);
}
}
}

12
Assets/ProCore/Polybrush/Code/Editor/Classes/z_ReflectionUtil.cs.meta


fileFormatVersion: 2
guid: 21b133d648d79e64683b26f62d8dc8f0
timeCreated: 1446125742
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

9
Assets/ProCore/Polybrush/Code/Editor/Enum.meta


fileFormatVersion: 2
guid: c8f40df97ded62c4d8a89c4693dde412
folderAsset: yes
timeCreated: 1453310067
licenseType: Store
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

42
Assets/ProCore/Polybrush/Code/Editor/Enum/z_BrushTool.cs


namespace Polybrush
{
/**
* Tool enum for brush modes.
*/
public enum z_BrushTool
{
None = 0,
RaiseLower = 1,
Smooth = 2,
Paint = 3,
Prefab = 4,
Texture = 5,
Settings = 6
}
public static class z_BrushToolUtility
{
public static System.Type GetModeType(this z_BrushTool tool)
{
switch(tool)
{
case z_BrushTool.RaiseLower:
return typeof(z_BrushModeRaiseLower);
case z_BrushTool.Smooth:
return typeof(z_BrushModeSmooth);
case z_BrushTool.Paint:
return typeof(z_BrushModePaint);
case z_BrushTool.Prefab:
return typeof(z_BrushModePrefab);
case z_BrushTool.Texture:
return typeof(z_BrushModeTexture);
}
return null;
}
}
}

12
Assets/ProCore/Polybrush/Code/Editor/Enum/z_BrushTool.cs.meta


fileFormatVersion: 2
guid: a8302f6a0a5f20740a575a0144b2cecd
timeCreated: 1446559304
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

9
Assets/ProCore/Polybrush/Code/Editor/Interface.meta


fileFormatVersion: 2
guid: c4365c893ae140845bbc29f318f7b966
folderAsset: yes
timeCreated: 1447947573
licenseType: Store
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

80
Assets/ProCore/Polybrush/Code/Editor/Interface/z_About.cs


using UnityEditor;
using UnityEngine;
using System.Text.RegularExpressions;
namespace Polybrush
{
class z_About : EditorWindow
{
static string CHANGELOG_PATH { get { return z_EditorUtility.RootFolder + "Documentation/changelog.md"; } }
const string VERSION_NUMBER_PATTERN = "(?<=#\\sPolybrush\\s)([0-9]{1,2}\\.[0-9]{1,2}\\.[0-9]{1,2})";
string versionNumber = "Major.Minor.Patch";
void OnEnable()
{
changelog = System.IO.File.ReadAllText(CHANGELOG_PATH);
Match versionMatch = Regex.Match(changelog, VERSION_NUMBER_PATTERN);
if(versionMatch.Success) versionNumber = versionMatch.Value;
// Match vcsMatch = Regex.Match(changelog, GIT_REVISION_PATTERN);
// if(vcsMatch.Success) revisionNumber = vcsMatch.Value;
}
string changelog;
GUIStyle centeredLargeLabel = null, centeredExtraLargeLabel = null;
bool initialized = false;
Vector2 scroll = Vector2.zero;
void BeginHorizontalCenter()
{
GUILayout.BeginHorizontal();
GUILayout.FlexibleSpace();
}
void EndHorizontalCenter()
{
GUILayout.FlexibleSpace();
GUILayout.EndHorizontal();
}
void OnGUI()
{
if(!initialized)
{
centeredLargeLabel = new GUIStyle( EditorStyles.largeLabel );
centeredLargeLabel.alignment = TextAnchor.MiddleCenter;
centeredExtraLargeLabel = new GUIStyle( EditorStyles.largeLabel );
centeredExtraLargeLabel.fontSize += 18;
centeredExtraLargeLabel.alignment = TextAnchor.MiddleCenter;
EditorStyles.largeLabel.richText = true;
}
GUILayout.Space(12);
GUILayout.Label("Polybrush " + versionNumber, centeredExtraLargeLabel);
GUILayout.Space(12);
BeginHorizontalCenter();
if(GUILayout.Button(" Documentation "))
Application.OpenURL(z_Pref.DocumentationLink);
if(GUILayout.Button(" Website "))
Application.OpenURL(z_Pref.WebsiteLink);
EndHorizontalCenter();
GUILayout.Space(12);
GUILayout.Label("<b>Changelog</b>", EditorStyles.largeLabel);
scroll = GUILayout.BeginScrollView(scroll);
GUILayout.Label( changelog, EditorStyles.wordWrappedLabel );
GUILayout.EndScrollView();
}
}
}

12
Assets/ProCore/Polybrush/Code/Editor/Interface/z_About.cs.meta


fileFormatVersion: 2
guid: 7e3cb83f07bc26e4ca2b08e512e856e2
timeCreated: 1452608875
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

49
Assets/ProCore/Polybrush/Code/Editor/Interface/z_AdditionalVertexStreamsEditor.cs


using UnityEngine;
using UnityEditor;
namespace Polybrush
{
[CanEditMultipleObjects]
[CustomEditor(typeof(z_AdditionalVertexStreams))]
public class z_AdditionalVertexStreamsEditor : Editor
{
public override void OnInspectorGUI()
{
var addlVertexStreamsMesh = target as z_AdditionalVertexStreams;
if(addlVertexStreamsMesh == null)
return;
MeshRenderer mr = addlVertexStreamsMesh.gameObject.GetComponent<MeshRenderer>();
GUILayout.Label("Additional Vertex Streams");
if(targets.Length > 1)
EditorGUI.showMixedValue = true;
EditorGUILayout.ObjectField(mr.additionalVertexStreams, typeof(Mesh), true);
EditorGUI.showMixedValue = false;
if(GUILayout.Button("Delete"))
{
foreach(z_AdditionalVertexStreams addlVertStreamMesh in targets)
{
if(addlVertStreamMesh == null)
continue;
mr = addlVertStreamMesh.GetComponent<MeshRenderer>();
if(mr != null)
mr.additionalVertexStreams = null;
if(addlVertStreamMesh.m_AdditionalVertexStreamMesh != null)
{
Undo.DestroyObjectImmediate(addlVertStreamMesh);
Undo.RecordObject(mr, "Delete AdditionalVertexStreams");
}
}
}
}
}
}

12
Assets/ProCore/Polybrush/Code/Editor/Interface/z_AdditionalVertexStreamsEditor.cs.meta


fileFormatVersion: 2
guid: acd81b6a6e8325346b5ebcc09e91f1d4
timeCreated: 1470769760
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

76
Assets/ProCore/Polybrush/Code/Editor/Interface/z_AttributeLayoutContainerEditor.cs


using UnityEditor;
using UnityEngine;
namespace Polybrush
{
[CustomEditor(typeof(z_AttributeLayoutContainer), true)]
public class z_AttributeLayoutContainerEditor : Editor
{
private static readonly Color LIGHT_GRAY = new Color(.13f, .13f, .13f, .3f);
private static readonly Color DARK_GRAY = new Color(.3f, .3f, .3f, .3f);
SerializedProperty p_shader,
p_attributes;
void OnEnable()
{
if(target == null)
{
GameObject.DestroyImmediate(this);
return;
}
p_shader = serializedObject.FindProperty("shader");
p_attributes = serializedObject.FindProperty("attributes");
}
public override void OnInspectorGUI()
{
serializedObject.Update();
EditorGUILayout.PropertyField(p_shader);
for(int i = 0; i < p_attributes.arraySize; i++)
{
SerializedProperty attrib = p_attributes.GetArrayElementAtIndex(i);
GUI.backgroundColor = i % 2 == 0 ? LIGHT_GRAY : DARK_GRAY;
GUILayout.BeginVertical(z_GUI.backgroundColorStyle);
GUI.backgroundColor = Color.white;
SerializedProperty target = attrib.FindPropertyRelative("propertyTarget");
SerializedProperty channel = attrib.FindPropertyRelative("channel");
SerializedProperty index = attrib.FindPropertyRelative("index");
SerializedProperty range = attrib.FindPropertyRelative("range");
SerializedProperty mask = attrib.FindPropertyRelative("mask");
EditorGUILayout.PropertyField(target);
EditorGUILayout.PropertyField(channel);
EditorGUILayout.IntPopup(index, z_ComponentIndexUtility.ComponentIndexPopupDescriptions, z_ComponentIndexUtility.ComponentIndexPopupValues);
bool old = EditorGUIUtility.wideMode;
EditorGUIUtility.wideMode = true;
EditorGUILayout.PropertyField(range);
EditorGUIUtility.wideMode = old;
EditorGUILayout.IntPopup(mask, z_AttributeLayout.DefaultMaskDescriptions, z_AttributeLayout.DefaultMaskValues, z_GUI.TempContent("Group"));
GUILayout.BeginHorizontal();
GUILayout.FlexibleSpace();
if(GUILayout.Button("Delete", EditorStyles.miniButton))
p_attributes.DeleteArrayElementAtIndex(i);
GUILayout.EndHorizontal();
GUILayout.EndVertical();
}
if(GUILayout.Button("Add Attribute"))
p_attributes.arraySize++;
serializedObject.ApplyModifiedProperties();
}
}
}

12
Assets/ProCore/Polybrush/Code/Editor/Interface/z_AttributeLayoutContainerEditor.cs.meta


fileFormatVersion: 2
guid: c7ee11be922e67848a5eb1f3f724a1b1
timeCreated: 1463587890
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

148
Assets/ProCore/Polybrush/Code/Editor/Interface/z_AttributeLayoutJsonEditor.cs


using UnityEngine;
using UnityEditor;
using System.Linq;
namespace Polybrush
{
/**
* Custom inspector for .pbs.json files.
*/
[CustomEditor(typeof(TextAsset), true)]
public class z_AttributeLayoutJsonEditor : Editor
{
[SerializeField] z_AttributeLayoutContainer container = null;
[SerializeField] Editor editor = null;
[SerializeField] bool modified = false;
[MenuItem("Assets/Create/Polybrush/Shader Metadata", true, 50)]
static bool VerifyCreateShaderMetaData()
{
return Selection.objects.Any(x => x != null && x is Shader);
}
[MenuItem("Assets/Create/Polybrush/Shader Metadata", false, 50)]
static void CreateShaderMetaData()
{
string path = "";
foreach(Shader shader in Selection.objects)
{
z_AttributeLayout[] attributes = new z_AttributeLayout[]
{
new z_AttributeLayout(z_MeshChannel.Color, z_ComponentIndex.R, Vector2.up, 0, "_Texture1"),
new z_AttributeLayout(z_MeshChannel.Color, z_ComponentIndex.G, Vector2.up, 0, "_Texture2"),
new z_AttributeLayout(z_MeshChannel.Color, z_ComponentIndex.B, Vector2.up, 0, "_Texture3"),
new z_AttributeLayout(z_MeshChannel.Color, z_ComponentIndex.A, Vector2.up, 0, "_Texture4"),
};
path = z_EditorUtility.SaveMeshAttributesData(shader, attributes, true);
}
AssetDatabase.Refresh();
TextAsset asset = AssetDatabase.LoadAssetAtPath<TextAsset>(path);
if(asset != null)
EditorGUIUtility.PingObject(asset);
}
private void ReloadJson()
{
editor = null;
container = null;
modified = false;
AssetDatabase.Refresh();
}
public override void OnInspectorGUI()
{
TextAsset asset = target as TextAsset;
if( asset == null || !asset.name.EndsWith(".pbs") )
{
// sfor whatever reason this doesn't work
// DrawDefaultInspector();
DrawTextAssetInspector();
return;
}
if(editor == null)
{
container = ScriptableObject.CreateInstance<z_AttributeLayoutContainer>();
JsonUtility.FromJsonOverwrite(asset.text, container);
editor = Editor.CreateEditor(container);
}
GUI.enabled = true;
EditorGUI.BeginChangeCheck();
editor.OnInspectorGUI();
if( EditorGUI.EndChangeCheck() )
modified = true;
GUILayout.BeginHorizontal();
GUILayout.FlexibleSpace();
GUI.enabled = modified;
if(GUILayout.Button("Revert"))
ReloadJson();
if(GUILayout.Button("Apply"))
{
z_EditorUtility.SaveMeshAttributesData(container, true);
ReloadJson();
}
GUILayout.EndHorizontal();
GUI.enabled = false;
}
private static GUIStyle m_TextStyle;
/**
* Copy/paste of Unity TextAssetInspector, since DrawDefaultInspector doesn't work with TextAssets.
* Not using reflection because this is such a small function that it makes more sense to just c/p
* and avoid the issues of Unity possibly changing names or signatures in the future.
*/
private void DrawTextAssetInspector()
{
if (m_TextStyle == null)
m_TextStyle = "ScriptText";
bool enabled = GUI.enabled;
GUI.enabled = true;
TextAsset textAsset = this.target as TextAsset;
if (textAsset != null)
{
string text;
if (base.targets.Length > 1)
{
text = string.Format("{0} Text Assets", base.targets.Length);
}
else
{
text = textAsset.ToString();
if (text.Length > 7000)
{
text = text.Substring(0, 7000) + "...\n\n<...etc...>";
}
}
Rect rect = GUILayoutUtility.GetRect(z_GUI.TempContent(text), m_TextStyle);
rect.x = 0f;
rect.y -= 3f;
rect.width = EditorGUIUtility.currentViewWidth - 1; // GUIClip.visibleRect.width + 1f;
GUI.Box(rect, text, m_TextStyle);
}
GUI.enabled = enabled;
}
}
}

12
Assets/ProCore/Polybrush/Code/Editor/Interface/z_AttributeLayoutJsonEditor.cs.meta


fileFormatVersion: 2
guid: eb84e94bb099a054c800b2926705afae
timeCreated: 1463585524
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

52
Assets/ProCore/Polybrush/Code/Editor/Interface/z_BlendMaterialInspector.cs


using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using System.Linq;
using Polybrush;
using System.Reflection;
// Can't namespace material editors.
// namespace Polybrush
// {
public class z_BlendMaterialInspector : MaterialEditor
{
System.Type sf_editor;
public override void OnEnable()
{
base.OnEnable();
sf_editor = z_ReflectionUtil.GetType("ShaderForge.SF_Editor", "ShaderForge");
}
public override void OnInspectorGUI()
{
base.serializedObject.Update();
if(sf_editor != null && GUILayout.Button("Open in ShaderForge"))
{
try
{
SerializedProperty shader_property = serializedObject.FindProperty ("m_Shader");
Shader shader = (Shader) shader_property.objectReferenceValue;
string path = AssetDatabase.GetAssetPath(shader);
string non_modified_path = path.Replace(".shader", z_PostProcessTextureBlend.BLEND_SRC_SUFFIX + ".shader");
Shader source = AssetDatabase.LoadAssetAtPath<Shader>(non_modified_path);
z_ReflectionUtil.Invoke(null,
sf_editor,
"Init",
new System.Type[] { typeof(Shader) },
BindingFlags.Public | BindingFlags.Static,
new object[] { source }) ;
}
catch(System.Exception e)
{
Debug.LogWarning("Could not find source for blend shader, or something else went wrong.\n" + e.ToString());
}
}
base.OnInspectorGUI();
}
}
// }

12
Assets/ProCore/Polybrush/Code/Editor/Interface/z_BlendMaterialInspector.cs.meta


fileFormatVersion: 2
guid: ea9f0220b4084f040b500b24c9ec1b0a
timeCreated: 1451407759
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

197
Assets/ProCore/Polybrush/Code/Editor/Interface/z_BrushSettingsEditor.cs


using UnityEngine;
using UnityEditor;
namespace Polybrush
{
/**
* The default editor for z_BrushSettings.
*/
[CustomEditor(typeof(z_BrushSettings))]
public class z_BrushSettingsEditor : Editor
{
public bool showSettingsBounds = false;
private GUIStyle settingsButtonStyle,
settingsBackgroundStyle,
settingsBackgroundBorderStyle;
private GUIContent gc_Radius;
private GUIContent gc_Falloff;
private GUIContent gc_FalloffCurve;
private GUIContent gc_Strength;
private GUIContent gc_RadiusMin, gc_RadiusMax;
private GUIContent gc_AllowUnclampedFalloff;
private GUIContent gc_BrushSettingsMinMax;
private static Color settings_background_color;
private static Color settings_border_color;
private static readonly Rect RECT_ONE = new Rect(0,0,1,1);
SerializedProperty radius,
falloff,
strength,
brushRadiusMin,
brushRadiusMax,
brushStrengthMin,
brushStrengthMax,
curve,
allowNonNormalizedFalloff;
public void OnEnable()
{
settings_background_color = EditorGUIUtility.isProSkin ? z_GUI.BOX_BACKGROUND_DARK : z_GUI.BOX_BACKGROUND_LIGHT;
settings_border_color = EditorGUIUtility.isProSkin ? z_GUI.BOX_OUTLINE_DARK : z_GUI.BOX_OUTLINE_LIGHT;
if(serializedObject == null)
GameObject.DestroyImmediate(this);
settingsButtonStyle = new GUIStyle();
settingsButtonStyle.imagePosition = ImagePosition.ImageOnly;
const int PAD = 2, MARGIN_HORIZONTAL = 4, MARGIN_VERTICAL = 0;
settingsButtonStyle.alignment = TextAnchor.MiddleCenter;
settingsButtonStyle.margin = new RectOffset(MARGIN_HORIZONTAL, MARGIN_HORIZONTAL, MARGIN_VERTICAL, MARGIN_VERTICAL);
settingsButtonStyle.padding = new RectOffset(PAD, PAD, 4, PAD);
settingsBackgroundStyle = new GUIStyle();
settingsBackgroundStyle.normal.background = EditorGUIUtility.whiteTexture;
settingsBackgroundStyle.margin = new RectOffset(0,0,0,0);
settingsBackgroundStyle.padding = new RectOffset(2,2,4,4);
settingsBackgroundBorderStyle = new GUIStyle();
settingsBackgroundBorderStyle.normal.background = EditorGUIUtility.whiteTexture;
settingsBackgroundBorderStyle.margin = new RectOffset(4,4,0,6);
settingsBackgroundBorderStyle.padding = new RectOffset(1,1,1,1);
/// User settable
radius = serializedObject.FindProperty("_radius");
falloff = serializedObject.FindProperty("_falloff");
curve = serializedObject.FindProperty("_curve");
strength = serializedObject.FindProperty("_strength");
/// Bounds
brushRadiusMin = serializedObject.FindProperty("brushRadiusMin");
brushRadiusMax = serializedObject.FindProperty("brushRadiusMax");
allowNonNormalizedFalloff = serializedObject.FindProperty("allowNonNormalizedFalloff");
gc_Radius = new GUIContent("Outer Radius", "Radius: The distance from the center of a brush to it's outer edge.\n\nShortcut: 'Ctrl + Mouse Wheel'");
gc_Falloff = new GUIContent("Inner Radius", "Inner Radius: The distance from the center of a brush at which the strength begins to linearly taper to 0. This value is normalized, 1 means the entire brush gets full strength, 0 means the very center point of a brush is full strength and the edges are 0.\n\nShortcut: 'Shift + Mouse Wheel'");
gc_FalloffCurve = new GUIContent("Falloff Curve", "Falloff: Sets the Falloff Curve.");
gc_Strength = new GUIContent("Strength", "Strength: The effectiveness of this brush. The actual applied strength also depends on the Falloff setting.\n\nShortcut: 'Ctrl + Shift + Mouse Wheel'");
gc_RadiusMin = new GUIContent("Brush Radius Min", "The minimum value the brush radius slider can access");
gc_RadiusMax = new GUIContent("Brush Radius Max", "The maximum value the brush radius slider can access");
gc_AllowUnclampedFalloff = new GUIContent("Unclamped Falloff", "If enabled, the falloff curve will not be limited to values between 0 and 1.");
gc_BrushSettingsMinMax = new GUIContent("Brush Radius Min / Max", "Set the minimum and maximum brush radius values");
}
private bool approx(float lhs, float rhs)
{
return Mathf.Abs(lhs-rhs) < .0001f;
}
public override void OnInspectorGUI()
{
serializedObject.Update();
z_GUI.PushGUISkin(z_GUI.PolybrushSkin);
// Manually show the settings header in z_Editor so that the preset selector can be included in the block
// if(z_GUILayout.HeaderWithDocsLink(z_GUI.TempContent("Brush Settings")))
// Application.OpenURL("http://procore3d.github.io/polybrush/brushSettings/");
showSettingsBounds = z_GUILayout.Foldout(showSettingsBounds, gc_BrushSettingsMinMax);
if(showSettingsBounds)
{
z_GUI.PushBackgroundColor(settings_border_color);
GUILayout.BeginVertical(settingsBackgroundBorderStyle);
z_GUI.PushBackgroundColor(settings_background_color);
GUILayout.BeginVertical(settingsBackgroundStyle);
z_GUI.PopBackgroundColor();
z_GUI.PopBackgroundColor();
brushRadiusMin.floatValue = z_GUILayout.FloatField(gc_RadiusMin, brushRadiusMin.floatValue);
brushRadiusMin.floatValue = Mathf.Clamp(brushRadiusMin.floatValue, .0001f, Mathf.Infinity);
brushRadiusMax.floatValue = z_GUILayout.FloatField(gc_RadiusMax, brushRadiusMax.floatValue);
brushRadiusMax.floatValue = Mathf.Clamp(brushRadiusMax.floatValue, brushRadiusMin.floatValue + .001f, Mathf.Infinity);
allowNonNormalizedFalloff.boolValue = z_GUILayout.Toggle(gc_AllowUnclampedFalloff, allowNonNormalizedFalloff.boolValue);
GUILayout.EndVertical();
GUILayout.EndVertical();
}
GUILayout.BeginHorizontal();
GUILayout.Label(gc_Radius, "IconLabel");
radius.floatValue = GUILayout.HorizontalSlider(radius.floatValue, brushRadiusMin.floatValue, brushRadiusMax.floatValue);
radius.floatValue = EditorGUILayout.FloatField(radius.floatValue, "textfield", GUILayout.MaxWidth(64));
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal();
GUILayout.Label(gc_Strength, "IconLabel");
strength.floatValue = GUILayout.HorizontalSlider(strength.floatValue, 0f, 1f);
strength.floatValue = EditorGUILayout.FloatField(strength.floatValue, "textfield", GUILayout.MaxWidth(64));
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal();
GUILayout.Label(gc_Falloff, "IconLabel");
falloff.floatValue = GUILayout.HorizontalSlider(falloff.floatValue, 0f, 1f);
falloff.floatValue = EditorGUILayout.FloatField(falloff.floatValue, "textfield", GUILayout.MaxWidth(64));
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal();
GUILayout.Label(gc_FalloffCurve, "IconLabel");
if(allowNonNormalizedFalloff.boolValue)
curve.animationCurveValue = EditorGUILayout.CurveField(curve.animationCurveValue, GUILayout.MinHeight(22));
else
curve.animationCurveValue = EditorGUILayout.CurveField(curve.animationCurveValue, Color.green, RECT_ONE, GUILayout.MinHeight(22));
GUILayout.EndHorizontal();
Keyframe[] keys = curve.animationCurveValue.keys;
if( (approx(keys[0].time, 0f) && approx(keys[0].value, 0f) && approx(keys[1].time, 1f) && approx(keys[1].value, 1f)) )
{
Keyframe[] rev = new Keyframe[keys.Length];
for(int i = 0 ; i < keys.Length; i++)
rev[keys.Length - i -1] = new Keyframe(1f - keys[i].time, keys[i].value, -keys[i].outTangent, -keys[i].inTangent);
curve.animationCurveValue = new AnimationCurve(rev);
}
serializedObject.ApplyModifiedProperties();
z_GUI.PopGUISkin();
SceneView.RepaintAll();
}
public static z_BrushSettings AddNew()
{
string path = z_EditorUtility.FindFolder(z_Pref.ProductName + "/" + "Brush Settings");
if(string.IsNullOrEmpty(path))
path = "Assets";
path = AssetDatabase.GenerateUniqueAssetPath(path + "/New Brush.asset");
if(!string.IsNullOrEmpty(path))
{
z_BrushSettings settings = ScriptableObject.CreateInstance<z_BrushSettings>();
settings.SetDefaultValues();
AssetDatabase.CreateAsset(settings, path);
AssetDatabase.Refresh();
EditorGUIUtility.PingObject(settings);
return settings;
}
return null;
}
}
}

12
Assets/ProCore/Polybrush/Code/Editor/Interface/z_BrushSettingsEditor.cs.meta


fileFormatVersion: 2
guid: f772fa0751cd24f40a634c8c34f805e1
timeCreated: 1445951161
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

366
Assets/ProCore/Polybrush/Code/Editor/Interface/z_ColorPaletteEditor.cs


using UnityEngine;
using UnityEditor;
using UnityEditorInternal;
namespace Polybrush
{
[CustomEditor(typeof(z_ColorPalette))]
public class z_ColorPaletteEditor : Editor
{
public class DragState
{
public enum Status
{
Ready,
Dragging,
DragInvalid
}
private Status _status = Status.Ready;
private Status queued_status = Status.Ready;
public SerializedProperty swatch;
private int _sourceIndex;
private int _destinationIndex;
private int queued_destinationIndex, queued_sourceIndex;
public Vector2 offset;
public Status status {
get {
return _status;
}
set {
queued_status = value;
wantsUpdate = true;
}
}
public int sourceIndex {
get {
return _sourceIndex;
}
set {
queued_sourceIndex = value;
wantsUpdate = true;
}
}
public int destinationIndex {
get {
return _destinationIndex;
}
set {
queued_destinationIndex = value;
wantsUpdate = true;
}
}
private bool wantsUpdate = false;
private bool isBetweenRepaint = true;
public void Init(int index, SerializedProperty swatch, Vector2 mouseOffset)
{
this.sourceIndex = index;
this.destinationIndex = index;
this.swatch = swatch;
this.status = Status.Dragging;
this.offset = mouseOffset;
this.isBetweenRepaint = true;
this.wantsUpdate = true;
}
public void Reset()
{
this.status = DragState.Status.Ready;
this.swatch = null;
this.sourceIndex = -1;
this.destinationIndex = -1;
}
public void Update(Event e)
{
if(e.type == EventType.Layout)
isBetweenRepaint = true;
else if(e.type == EventType.Repaint)
isBetweenRepaint = false;
if(!wantsUpdate || isBetweenRepaint)
return;
wantsUpdate = false;
_status = queued_status;
_sourceIndex = queued_sourceIndex;
_destinationIndex = queued_destinationIndex;
z_Editor.DoRepaint();
}
public override string ToString()
{
return string.Format("{0}: {1} -> {2}", status, sourceIndex, destinationIndex);
}
}
private SerializedProperty currentProperty;
private SerializedProperty colorsProperty;
public Delegate<Color> onSelectIndex = null;
public Delegate<z_ColorPalette> onSaveAs = null;
DragState drag = new DragState();
const int DRAG_OVER_NULL = -1;
const int DRAG_OVER_TRASH = -42;
GUIContent gc_AddColorSwatch = new GUIContent( (Texture2D) null, "Add Selected Color to Palette");
private void OnEnable()
{
currentProperty = serializedObject.FindProperty("current");
colorsProperty = serializedObject.FindProperty("colors");
gc_AddColorSwatch.image = z_IconUtility.GetIcon("Icon/AddColor");
}
private void SetCurrent(Color color)
{
if(onSelectIndex != null)
onSelectIndex(color);
currentProperty.colorValue = color;
}
int IncrementIndex(int index, int rowSize)
{
index++;
if(index % rowSize == 0)
{
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal();
}
return index;
}
public override void OnInspectorGUI()
{
z_GUI.PushGUISkin(z_GUI.PolybrushSkin);
Event e = Event.current;
serializedObject.Update();
Color current = currentProperty.colorValue;
z_GUI.PushUnitySkin();
EditorGUI.BeginChangeCheck();
current = EditorGUILayout.ColorField(current);
if(EditorGUI.EndChangeCheck())
SetCurrent(current);
z_GUI.PopGUISkin();
int swatchSize = 18;
int viewWidth = (int) EditorGUIUtility.currentViewWidth - 12;
int swatchesPerRow = viewWidth / (swatchSize + 4);
swatchSize += (viewWidth % (swatchSize + 4)) / swatchesPerRow;
GUILayout.BeginHorizontal();
int mouseOverIndex = DRAG_OVER_NULL;
int index = 0;
int arraySize = colorsProperty.arraySize;
int arraySizeWithAdd = colorsProperty.arraySize + 1;
for(int i = 0; i < arraySizeWithAdd; i++)
{
bool isColorSwatch = i < arraySize;
bool isActiveDrag = drag.status == DragState.Status.Dragging && drag.destinationIndex == i && i != arraySizeWithAdd - 1;
SerializedProperty swatch = isColorSwatch ? colorsProperty.GetArrayElementAtIndex(i) : null;
Rect swatchRect = new Rect(-1f, -1f, 0f, 0f);
if(isActiveDrag)
{
GUILayout.Space(swatchSize + 4);
index = IncrementIndex(index, swatchesPerRow);
}
if(isColorSwatch)
{
GUI.backgroundColor = swatch.colorValue;
if(drag.status != DragState.Status.Dragging || i != drag.sourceIndex)
{
GUILayout.Label("", "ColorSwatch",
GUILayout.MinWidth(swatchSize),
GUILayout.MaxWidth(swatchSize),
GUILayout.MinHeight(swatchSize),
GUILayout.MaxHeight(swatchSize) );
swatchRect = GUILayoutUtility.GetLastRect();
index = IncrementIndex(index, swatchesPerRow);
}
}
else
{
if( drag.status != DragState.Status.Dragging )
{
GUI.backgroundColor = current;
if( GUILayout.Button(gc_AddColorSwatch, "ColorSwatch",
GUILayout.MinWidth(swatchSize),
GUILayout.MaxWidth(swatchSize),
GUILayout.MinHeight(swatchSize),
GUILayout.MaxHeight(swatchSize) ))
{
colorsProperty.arraySize++;
SerializedProperty added = colorsProperty.GetArrayElementAtIndex(colorsProperty.arraySize - 1);
added.colorValue = current;
}
}
else
{
GUILayout.FlexibleSpace();
GUILayout.Label(z_IconUtility.GetIcon("Icon/Trashcan"));
}
swatchRect = GUILayoutUtility.GetLastRect();
index = IncrementIndex(index, swatchesPerRow);
}
GUI.backgroundColor = Color.white;
if( swatchRect.Contains(e.mousePosition) )
{
if(drag.status == DragState.Status.Dragging)
mouseOverIndex = i >= drag.destinationIndex ? i + 1 : i;
else
mouseOverIndex = i;
if(i == arraySize)
mouseOverIndex = DRAG_OVER_TRASH;
if(e.type == EventType.MouseDrag)
{
if( drag.status == DragState.Status.Ready && isColorSwatch )
{
e.Use();
drag.Init(mouseOverIndex, colorsProperty.GetArrayElementAtIndex(mouseOverIndex), swatchRect.position - e.mousePosition);
}
else if(drag.status == DragState.Status.Dragging)
{
drag.destinationIndex = mouseOverIndex;
}
}
else if(e.type == EventType.MouseUp && drag.status != DragState.Status.Dragging && isColorSwatch)
{
if( onSelectIndex != null )
{
SetCurrent(swatch.colorValue);
}
}
}
}
GUILayout.EndHorizontal();
// If drag was previously over the trash bin but has moved, reset the index to be over the last array entry
// instead.
if( e.type == EventType.MouseDrag &&
drag.status == DragState.Status.Dragging &&
mouseOverIndex == DRAG_OVER_NULL &&
drag.destinationIndex == DRAG_OVER_TRASH)
{
drag.destinationIndex = arraySize;
}
bool dragIsOverTrash = drag.destinationIndex == DRAG_OVER_TRASH;
if(drag.status == DragState.Status.Dragging && drag.swatch != null)
{
Rect r = new Rect(e.mousePosition.x + drag.offset.x, e.mousePosition.y + drag.offset.y, swatchSize, swatchSize);
GUI.backgroundColor = drag.swatch.colorValue;
GUI.Label(r, "", dragIsOverTrash ? "ColorSwatchGhost" : "ColorSwatch");
GUI.backgroundColor = Color.white;
z_Editor.DoRepaint();
Repaint();
}
switch( e.type )
{
case EventType.MouseUp:
{
if(drag.status == DragState.Status.Dragging)
{
if(drag.destinationIndex != DRAG_OVER_NULL)
{
if(dragIsOverTrash)
colorsProperty.DeleteArrayElementAtIndex(drag.sourceIndex);
else
colorsProperty.MoveArrayElement(drag.sourceIndex, drag.destinationIndex > drag.sourceIndex ? drag.destinationIndex - 1 : drag.destinationIndex);
}
}
drag.Reset();
z_Editor.DoRepaint();
Repaint();
}
break;
}
serializedObject.ApplyModifiedProperties();
drag.Update(e);
z_GUI.PopGUISkin();
}
private void DrawHeader(Rect rect)
{
EditorGUI.LabelField(rect, serializedObject.targetObject.name);
}
private void DrawListElement(Rect rect, int index, bool isActive, bool isFocused)
{
SerializedProperty col = colorsProperty.GetArrayElementAtIndex(index);
Rect r = new Rect(rect.x, rect.y + 2, rect.width, rect.height - 5);
EditorGUI.PropertyField(r, col);
}
private void OnAddItem(ReorderableList list)
{
ReorderableList.defaultBehaviours.DoAddButton(list);
SerializedProperty col = colorsProperty.GetArrayElementAtIndex(list.index);
col.colorValue = Color.white;
}
public static z_ColorPalette AddNew()
{
string path = z_EditorUtility.FindFolder(z_Pref.ProductName + "/" + "Color Palettes");
if(string.IsNullOrEmpty(path))
path = "Assets";
path = AssetDatabase.GenerateUniqueAssetPath(path + "/New Color Palette.asset");
if(!string.IsNullOrEmpty(path))
{
z_ColorPalette palette = ScriptableObject.CreateInstance<z_ColorPalette>();
palette.SetDefaultValues();
AssetDatabase.CreateAsset(palette, path);
AssetDatabase.Refresh();
EditorGUIUtility.PingObject(palette);
return palette;
}
return null;
}
}
}

12
Assets/ProCore/Polybrush/Code/Editor/Interface/z_ColorPaletteEditor.cs.meta


fileFormatVersion: 2
guid: 7d469acee0fe93841a4ef5f2994d4d5f
timeCreated: 1447945862
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

1001
Assets/ProCore/Polybrush/Code/Editor/Interface/z_Editor.cs
文件差异内容过多而无法显示
查看文件

12
Assets/ProCore/Polybrush/Code/Editor/Interface/z_Editor.cs.meta


fileFormatVersion: 2
guid: e4c5d778300bf074c818ef8ea6e3062b
timeCreated: 1445005468
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

113
Assets/ProCore/Polybrush/Code/Editor/Interface/z_GlobalSettingsEditor.cs


using UnityEngine;
using UnityEditor;
using System.Reflection;
namespace Polybrush
{
internal class z_GlobalSettingsEditor : Editor
{
private static bool initialized = false;
private static readonly GUIContent gc_rebuildNormals = new GUIContent("Rebuild Normals", "After a mesh modification the normals will be recalculated.");
private static readonly GUIContent gc_rebuildCollisions = new GUIContent("Rebuild MeshCollider", "After a mesh modification the mesh collider will be recalculated.");
public static readonly GUIContent gc_lockBrushToFirst = new GUIContent("Lock Brush to First", "When applying a brush this prevents any other mesh from intercepting the stroke. Disable this if you want to apply across multiple meshes.");
// private static readonly GUIContent gc_ignoreUnselected = new GUIContent("Ignore Unselected", "When a Polybrush tool is engaged, the mouse will always interact first with any selected GameObjects.");
private static readonly GUIContent gc_lockBrushSettings = new GUIContent("Anchor Brush Settings", "Locks the Brush Settings to the top of the window.");
private static readonly GUIContent gc_hideWireframe = new GUIContent("Hide Wireframe", "Hides the object wireframe when a brush is hovering.");
private static readonly GUIContent gc_fullStrengthColor = new GUIContent("Brush Handle Color", "The color that the brush handle will render.");
private static readonly GUIContent gc_BrushGradient = new GUIContent("Brush Gradient", "The color gradient used to mark a brush's strength through the falloff.");
public static readonly GUIContent gc_vertexBillboardSize = new GUIContent("Vertex Render Size", "The size at which selected vertices will be rendered.");
private static readonly GUIContent gc_additionalVertexStreams = new GUIContent("Addl. Vertex Streams", "Instead of applying changes directly to the mesh, modifications will be stored in an additionalVertexStreams mesh. This option can be more performance friendly in some cases.");
private static bool rebuildNormals { get { return z_Pref.GetBool(z_Pref.rebuildNormals); } set { z_Pref.SetBool(z_Pref.rebuildNormals, value); } }
private static bool rebuildCollisions { get { return z_Pref.GetBool(z_Pref.rebuildCollisions); } set { z_Pref.SetBool(z_Pref.rebuildCollisions, value); } }
private static bool hideWireframe { get { return z_Pref.GetBool(z_Pref.hideWireframe); } set { z_Pref.SetBool(z_Pref.hideWireframe, value); } }
private static bool lockBrushSettings { get { return z_Pref.GetBool(z_Pref.lockBrushSettings); } set { z_Pref.SetBool(z_Pref.lockBrushSettings, value); } }
private static bool additionalVertexStreams { get { return z_Pref.GetBool(z_Pref.additionalVertexStreams); } set { z_Pref.SetBool(z_Pref.additionalVertexStreams, value); } }
public static bool lockBrushToFirst
{
get { return z_Pref.GetBool(z_Pref.lockBrushToFirst); }
set {
z_Pref.SetBool(z_Pref.lockBrushToFirst, value);
z_Editor.instance.lockBrushToFirst = value;
}
}
public static bool ignoreUnselected
{
get { return z_Pref.GetBool(z_Pref.ignoreUnselected); }
set {
z_Pref.SetBool(z_Pref.ignoreUnselected, value);
z_Editor.instance.ignoreUnselected = value;
}
}
private static Color fullStrengthColor { get { return z_Pref.GetColor(z_Pref.brushColor); } set { z_Pref.SetColor(z_Pref.brushColor, value); } }
private static Color brushGradient { get { return z_Pref.GetColor(z_Pref.brushGradient); } set { z_Pref.SetColor(z_Pref.brushGradient, value); } }
// vertexBillboardSize uses EditorPrefs because z_OverlayRenderer needs access, and it's not possible to query the z_PreferenceDictionary from
// runtime code
private static float vertexBillboardSize { get { return EditorPrefs.GetFloat(z_Pref.vertexBillboardSize, 1.4f); } set { EditorPrefs.SetFloat(z_Pref.vertexBillboardSize, value); } }
private static Gradient gradient;
static void GetPreferences()
{
gradient = z_Pref.GetGradient(z_Pref.brushGradient);
}
static void SetPreferences()
{
z_Pref.SetGradient(z_Pref.brushGradient, gradient);
}
internal static void OnGUI()
{
if(!initialized)
GetPreferences();
if( z_GUILayout.HeaderWithDocsLink(z_GUI.TempContent("General Settings", "")) )
Application.OpenURL("http://procore3d.github.io/polybrush/settings/");
rebuildNormals = z_GUILayout.Toggle(gc_rebuildNormals, rebuildNormals);
rebuildCollisions = z_GUILayout.Toggle(gc_rebuildCollisions, rebuildCollisions);
lockBrushToFirst = z_GUILayout.Toggle(gc_lockBrushToFirst, lockBrushToFirst);
lockBrushSettings = z_GUILayout.Toggle(gc_lockBrushSettings, lockBrushSettings);
additionalVertexStreams = z_GUILayout.Toggle(gc_additionalVertexStreams, additionalVertexStreams);
hideWireframe = z_GUILayout.Toggle(gc_hideWireframe, hideWireframe);
GUILayout.Label(gc_fullStrengthColor);
z_GUI.PushUnitySkin();
fullStrengthColor = z_GUILayout.ColorField(GUIContent.none, fullStrengthColor);
z_GUI.PopGUISkin();
GUILayout.BeginHorizontal();
GUILayout.Label(gc_vertexBillboardSize);
vertexBillboardSize = GUILayout.HorizontalSlider(vertexBillboardSize, 0f, 4f);
vertexBillboardSize = EditorGUILayout.FloatField(vertexBillboardSize, "textfield", GUILayout.MaxWidth(64));
GUILayout.EndHorizontal();
try
{
EditorGUI.BeginChangeCheck();
gradient = z_GUILayout.GradientField(gc_BrushGradient, gradient);
if(EditorGUI.EndChangeCheck())
SetPreferences();
}
catch
{
// internal editor gripe about something unimportant
}
if(GUILayout.Button("Reset Defaults"))
if(EditorUtility.DisplayDialog("Reset Polybrush Preferences", "This will clear any saved Polybrush preference items. Are you sure you want to continue?", "Yes", "No"))
z_Pref.ClearPrefs();
}
}
}

12
Assets/ProCore/Polybrush/Code/Editor/Interface/z_GlobalSettingsEditor.cs.meta


fileFormatVersion: 2
guid: aea1ecf64f1c5024dbb8fae10037861a
timeCreated: 1450627902
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

38
Assets/ProCore/Polybrush/Code/Editor/Interface/z_MeshFilterEditor.cs


using UnityEngine;
using UnityEditor;
namespace Polybrush
{
[CustomEditor(typeof(MeshFilter)), CanEditMultipleObjects]
public class z_MeshFilterEditor : Editor
{
public override void OnInspectorGUI()
{
serializedObject.Update();
SerializedProperty mesh = serializedObject.FindProperty("m_Mesh");
if(mesh != null)
EditorGUILayout.PropertyField(mesh);
Mesh m = (Mesh) mesh.objectReferenceValue;
if(m != null)
{
string dontcare = null;
z_ModelSource source = z_EditorUtility.GetMeshGUID(m, ref dontcare);
if( source == z_ModelSource.Scene &&
!(z_ReflectionUtil.IsProBuilderObject(((MeshFilter)serializedObject.targetObject).gameObject)) )
{
if(GUILayout.Button(new GUIContent("Save to Asset", "Save this instance mesh to an Asset so that you can use it as a prefab.")))
{
z_EditorUtility.SaveMeshAsset(m);
}
}
}
serializedObject.ApplyModifiedProperties();
}
}
}

12
Assets/ProCore/Polybrush/Code/Editor/Interface/z_MeshFilterEditor.cs.meta


fileFormatVersion: 2
guid: cb3c884ba48120949a6c4f0ee96c0c30
timeCreated: 1445439956
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

207
Assets/ProCore/Polybrush/Code/Editor/Interface/z_PrefabPaletteEditor.cs


using UnityEngine;
using UnityEditor;
using System.Collections.Generic;
using System.Linq;
namespace Polybrush
{
[CustomEditor(typeof(z_PrefabPalette))]
public class z_PrefabPaletteEditor : Editor
{
private SerializedProperty prefabs;
private HashSet<int> selected = new HashSet<int>();
public Delegate<IEnumerable<int>> onSelectionChanged = null;
private void OnEnable()
{
prefabs = serializedObject.FindProperty("prefabs");
}
public static z_PrefabPalette AddNew()
{
string path = z_EditorUtility.FindFolder(z_Pref.ProductName + "/" + "Prefab Palettes");
if(string.IsNullOrEmpty(path))
path = "Assets";
path = AssetDatabase.GenerateUniqueAssetPath(path + "/New Prefab Palette.asset");
if(!string.IsNullOrEmpty(path))
{
z_PrefabPalette palette = ScriptableObject.CreateInstance<z_PrefabPalette>();
palette.SetDefaultValues();
AssetDatabase.CreateAsset(palette, path);
AssetDatabase.Refresh();
EditorGUIUtility.PingObject(palette);
return palette;
}
return null;
}
public override void OnInspectorGUI()
{
OnInspectorGUI_Internal(64);
}
private bool IsDeleteKey(Event e)
{
return e.keyCode == KeyCode.Backspace;
}
public void OnInspectorGUI_Internal(int thumbSize)
{
serializedObject.Update();
int count = prefabs != null ? prefabs.arraySize : 0;
const int margin_x = 8; // group pad
const int margin_y = 4; // group pad
const int pad = 2; // texture pad
const int selected_rect_height = 10; // the little green bar and height padding
int actual_width = (int) Mathf.Ceil(thumbSize + pad/2);
int container_width = (int) Mathf.Floor(EditorGUIUtility.currentViewWidth) - (margin_x * 2);
int usable_width = container_width - pad * 2;
int columns = (int) Mathf.Floor(usable_width / actual_width);
int fill = (int) Mathf.Floor(((usable_width % actual_width)) / columns);
int size = thumbSize + fill;
int rows = count / columns + (count % columns == 0 ? 0 : 1);
if(rows < 1) rows = 1;
int height = rows * (size + selected_rect_height);
Rect r = EditorGUILayout.GetControlRect(false, height);
r.x = margin_x + pad;
r.y += margin_y;
r.width = size;
r.height = size;
Rect border = new Rect( margin_x, r.y, container_width, height );
// GUI.color = EditorGUIUtility.isProSkin ? z_GUI.BOX_OUTLINE_DARK : z_GUI.BOX_OUTLINE_LIGHT;
// EditorGUI.DrawPreviewTexture(border, EditorGUIUtility.whiteTexture);
// border.x += 1;
// border.y += 1;
// border.width -= 2;
// border.height -= 2;
// GUI.color = EditorGUIUtility.isProSkin ? z_GUI.BOX_BACKGROUND_DARK : z_GUI.BOX_BACKGROUND_LIGHT;
// EditorGUI.DrawPreviewTexture(border, EditorGUIUtility.whiteTexture);
// GUI.color = Color.white;
GUI.Box(border, "");
bool listNeedsPruning = false;
if(count < 1)
{
if( GUI.skin.name.Contains("polybrush"))
GUI.Label(border, "Drag Prefabs Here!", "dragprefablabel");
else
GUI.Label(border, "Drag Prefabs Here!", EditorStyles.centeredGreyMiniLabel);
}
for(int i = 0; i < count; i++)
{
SerializedProperty it = prefabs.GetArrayElementAtIndex(i);
SerializedProperty prefab = it.FindPropertyRelative("gameObject");
if( prefab == null || prefab.objectReferenceValue == null )
{
listNeedsPruning = true;
continue;
}
if(i > 0 && i % columns == 0)
{
r.x = pad + margin_x;
r.y += r.height + selected_rect_height;
}
if( z_GUILayout.AssetPreviewButton(r, prefab.objectReferenceValue, selected.Contains(i)) )
{
if(Event.current.shift || Event.current.control)
{
if(!selected.Add(i))
selected.Remove(i);
}
else
{
selected.Clear();
selected.Add(i);
}
if(onSelectionChanged != null)
onSelectionChanged( selected );
GUI.changed = true;
}
r.x += r.width + pad;
}
if(listNeedsPruning)
{
DeleteWhere(prefabs, (index, prop) =>
{
if(prop == null) return true;
SerializedProperty g = prop.FindPropertyRelative("gameObject");
return g == null || g.objectReferenceValue == null;
});
}
Event e = Event.current;
if( border.Contains(e.mousePosition) &&
(e.type == EventType.DragUpdated || e.type == EventType.DragPerform) &&
DragAndDrop.objectReferences.Length > 0 )
{
DragAndDrop.visualMode = DragAndDropVisualMode.Copy;
if(e.type == EventType.DragPerform)
{
DragAndDrop.AcceptDrag();
IEnumerable<GameObject> dragAndDropReferences = DragAndDrop.objectReferences.Where(x => x is GameObject).Cast<GameObject>();
foreach(GameObject go in dragAndDropReferences)
{
prefabs.InsertArrayElementAtIndex(prefabs.arraySize);
SerializedProperty last = prefabs.GetArrayElementAtIndex(prefabs.arraySize - 1);
SerializedProperty gameObject = last.FindPropertyRelative("gameObject");
gameObject.objectReferenceValue = go;
}
}
}
if(e.type == EventType.KeyUp)
{
if( IsDeleteKey(e) )
{
DeleteWhere(prefabs, (i, v) => { return selected.Contains(i); } );
selected.Clear();
if(onSelectionChanged != null)
onSelectionChanged(null);
z_Editor.DoRepaint();
}
}
serializedObject.ApplyModifiedProperties();
}
private void DeleteWhere(SerializedProperty array, System.Func<int, SerializedProperty, bool> lamdba)
{
int arraySize = array.arraySize;
for(int i = arraySize - 1; i > -1; i--)
{
if( lamdba(i, array.GetArrayElementAtIndex(i)) )
array.DeleteArrayElementAtIndex(i);
}
}
}
}

12
Assets/ProCore/Polybrush/Code/Editor/Interface/z_PrefabPaletteEditor.cs.meta


fileFormatVersion: 2
guid: f5ee19724a0020345861aee152efba68
timeCreated: 1447946477
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

125
Assets/ProCore/Polybrush/Code/Editor/Interface/z_PreferenceDictionaryEditor.cs


using UnityEngine;
using UnityEditor;
using System.Collections;
using System.Collections.Generic;
namespace Polybrush
{
[CustomEditor(typeof(z_PreferenceDictionary))]
public class z_PreferenceDictionaryEditor : Editor
{
static Color RowEven = new Color(.40f, .40f, .40f, .3f);
static Color RowOdd = new Color(.60f, .60f, .60f, .3f);
bool showBool = true,
showInt = true,
showFloat = true,
showString = true,
showColor = true;
Vector2 scroll = Vector2.zero;
public override void OnInspectorGUI()
{
if(target == null)
return;
z_PreferenceDictionary dic = target as z_PreferenceDictionary;
if(dic == null)
return;
Dictionary<string, bool> m_bool = (Dictionary<string, bool>) z_ReflectionUtil.GetValue(dic, typeof(z_PreferenceDictionary), "m_bool");
Dictionary<string, int> m_int = (Dictionary<string, int>) z_ReflectionUtil.GetValue(dic, typeof(z_PreferenceDictionary), "m_int");
Dictionary<string, float> m_float = (Dictionary<string, float>) z_ReflectionUtil.GetValue(dic, typeof(z_PreferenceDictionary), "m_float");
Dictionary<string, string> m_string = (Dictionary<string, string>) z_ReflectionUtil.GetValue(dic, typeof(z_PreferenceDictionary), "m_string");
Dictionary<string, Color> m_Color = (Dictionary<string, Color>) z_ReflectionUtil.GetValue(dic, typeof(z_PreferenceDictionary), "m_Color");
scroll = EditorGUILayout.BeginScrollView(scroll);
GUILayout.Label("Bool Values", EditorStyles.boldLabel);
int i = 0;
if(showBool)
{
foreach(var kvp in m_bool)
{
GUI.backgroundColor = i++ % 2 == 0 ? RowEven : RowOdd;
GUILayout.BeginHorizontal(z_GUI.backgroundColorStyle);
GUILayout.Label(kvp.Key);
GUILayout.FlexibleSpace();
GUILayout.Label(kvp.Value.ToString());
GUILayout.EndHorizontal();
}
GUI.backgroundColor = Color.white;
}
GUILayout.Label("Int Values", EditorStyles.boldLabel);
if(showInt)
{
foreach(var kvp in m_int)
{
GUI.backgroundColor = i++ % 2 == 0 ? RowEven : RowOdd;
GUILayout.BeginHorizontal(z_GUI.backgroundColorStyle);
GUILayout.Label(kvp.Key);
GUILayout.FlexibleSpace();
GUILayout.Label(kvp.Value.ToString());
GUILayout.EndHorizontal();
}
GUI.backgroundColor = Color.white;
}
GUILayout.Label("Float Values", EditorStyles.boldLabel);
if(showFloat)
{
foreach(var kvp in m_float)
{
GUI.backgroundColor = i++ % 2 == 0 ? RowEven : RowOdd;
GUILayout.BeginHorizontal(z_GUI.backgroundColorStyle);
GUILayout.Label(kvp.Key);
GUILayout.FlexibleSpace();
GUILayout.Label(kvp.Value.ToString());
GUILayout.EndHorizontal();
}
GUI.backgroundColor = Color.white;
}
GUILayout.Label("String Values", EditorStyles.boldLabel);
if(showString)
{
foreach(var kvp in m_string)
{
GUI.backgroundColor = i++ % 2 == 0 ? RowEven : RowOdd;
GUILayout.BeginHorizontal(z_GUI.backgroundColorStyle);
GUILayout.Label(kvp.Key);
GUILayout.FlexibleSpace();
GUILayout.Label(kvp.Value.ToString());
GUILayout.EndHorizontal();
}
GUI.backgroundColor = Color.white;
}
GUILayout.Label("Color Values", EditorStyles.boldLabel);
if(showColor)
{
foreach(var kvp in m_Color)
{
GUI.backgroundColor = i++ % 2 == 0 ? RowEven : RowOdd;
GUILayout.BeginHorizontal(z_GUI.backgroundColorStyle);
GUILayout.Label(kvp.Key);
GUILayout.FlexibleSpace();
GUILayout.Label(kvp.Value.ToString());
GUILayout.EndHorizontal();
}
GUI.backgroundColor = Color.white;
}
EditorGUILayout.EndScrollView();
}
}
}

12
Assets/ProCore/Polybrush/Code/Editor/Interface/z_PreferenceDictionaryEditor.cs.meta


fileFormatVersion: 2
guid: 74dab3151fd644d4185f95c2122838ea
timeCreated: 1479398631
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

34
Assets/ProCore/Polybrush/Code/Editor/Interface/z_SplatWeightEditor.cs


using UnityEngine;
using UnityEditor;
using System.Collections;
using System.Linq;
namespace Polybrush
{
/**
* The default editor for z_SplatWeight.
*/
[CustomEditor(typeof(z_SplatWeight))]
public class z_SplatWeightEditor : Editor
{
static int thumbSize = 64;
/**
* Editor for blend. Returns true if blend has been modified.
*/
public static int OnInspectorGUI(int index, ref z_SplatWeight blend, z_AttributeLayout[] attribs)
{
// if(blend == null && attribs != null)
// blend = new z_SplatWeight( z_SplatWeight.GetChannelMap(attribs) );
// bool mismatchedOrNullAttributes = blend == null || !blend.MatchesAttributes(attribs);
Rect r = GUILayoutUtility.GetLastRect();
int yPos = (int) Mathf.Ceil(r.y + r.height);
index = z_GUILayout.ChannelField(index, attribs, thumbSize, yPos);
return index;
}
}
}

12
Assets/ProCore/Polybrush/Code/Editor/Interface/z_SplatWeightEditor.cs.meta


fileFormatVersion: 2
guid: 6cfdebd44cc775543b4c91a25ca46ad8
timeCreated: 1453400637
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

59
Assets/ProCore/Polybrush/Code/Editor/Interface/z_ZoomOverrideEditor.cs


using UnityEngine;
using UnityEditor;
using System.Collections.Generic;
namespace Polybrush
{
[CustomEditor(typeof(z_ZoomOverride), true)]
public class z_ZoomOverrideEditor : Editor
{
void OnEnable()
{
if(z_Editor.instance == null)
GameObject.DestroyImmediate(this.target);
}
public override void OnInspectorGUI() {}
bool HasFrameBounds()
{
z_ZoomOverride ren = (z_ZoomOverride) target;
return ren.mesh != null && ren.GetWeights().Length == ren.mesh.vertexCount;
}
Bounds OnGetFrameBounds()
{
z_ZoomOverride ren = (z_ZoomOverride) target;
Mesh m = ren.mesh;
Vector3[] vertices = m.vertices;
float[] weights = ren.GetWeights();
Bounds bounds = new Bounds(Vector3.zero, Vector3.zero);
int appliedWeights = 0;
Transform transform = ((z_ZoomOverride)target).transform;
for(int i = 0; i < m.vertexCount; i++)
{
if(weights[i] > 0.0001f)
{
if(appliedWeights > 0)
bounds.Encapsulate( transform.TransformPoint(vertices[i]));
else
bounds.center = transform.TransformPoint(vertices[i]);
appliedWeights++;
}
}
if(appliedWeights < 1)
bounds = ren.transform.GetComponent<MeshRenderer>().bounds;
else if(appliedWeights == 1 || bounds.size.magnitude < .1f)
bounds.size = Vector3.one * .5f;
return bounds;
}
}
}

12
Assets/ProCore/Polybrush/Code/Editor/Interface/z_ZoomOverrideEditor.cs.meta


fileFormatVersion: 2
guid: df0a89f5a90a7074da09d000b1cab8c9
timeCreated: 1447343170
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

9
Assets/ProCore/Polybrush/Code/Editor/Utility.meta


fileFormatVersion: 2
guid: 67d22621905b737479d12ab8687e0d5f
folderAsset: yes
timeCreated: 1447947227
licenseType: Store
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

部分文件因为文件数量过多而无法显示

正在加载...
取消
保存