public override void OnBrushApply(z_BrushTarget target, z_BrushSettings settings) { Vector3[] vertices = target.editableObject.vertices; Vector3 v, n = direction.ToVector3(); float scale = 1f / ( Vector3.Scale(target.transform.lossyScale, n).magnitude ); float sign = Event.current.shift ? -1f : 1f; float maxMoveDistance = settings.strength * STRENGTH_MODIFIER * sign * brushStrength; foreach(KeyValuePair<int, float> weight in target.weights) { if(ignoreNonManifoldIndices && nonManifoldIndices.Contains(weight.Key)) continue; v = vertices[weight.Key]; if(direction == z_Direction.Normal) { n = normalLookup[weight.Key]; scale = 1f / ( Vector3.Scale(target.transform.lossyScale, n).magnitude ); } vertices[weight.Key] = v + n * weight.Value * maxMoveDistance * scale; } target.editableObject.mesh.vertices = vertices; if(tempComponent != null) tempComponent.OnVerticesMoved(); base.OnBrushApply(target, settings); }
public static void DrawScatterBrush(Vector3 point, Vector3 normal, z_BrushSettings settings, Matrix4x4 localToWorldMatrix) { Vector3 p = localToWorldMatrix.MultiplyPoint3x4(point); Vector3 n = localToWorldMatrix.MultiplyVector(normal).normalized; float r = settings.radius; Vector3 a = Vector3.zero; Quaternion rotation = Quaternion.LookRotation(normal, Vector3.up); for(int i = 0; i < 10; i++) { a.x = Mathf.Cos(Random.Range(0f, 360f)); a.y = Mathf.Sin(Random.Range(0f, 360f)); a = a.normalized * Random.Range(0f, r); Vector3 v = localToWorldMatrix.MultiplyPoint3x4(point + rotation * a); Handles.DrawLine(v, v + (n * .5f)); Handles.CubeCap(i + 2302, v, Quaternion.identity, .01f); } /// radius Handles.DrawWireDisc(p, n, settings.radius); }
protected override void UpdateTempComponent(z_BrushTarget target, z_BrushSettings settings) { if(tempComponent != null && target.weights != null) { ((z_OverlayRenderer)tempComponent).SetWeights(target.weights, settings.strength); } }
/// 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) EditorUtility.SetSelectedWireframeHidden(target.renderer, true); CreateTempComponent(target, settings); }
public override void DrawGUI(z_BrushSettings settings) { base.DrawGUI(settings); if(direction == z_Direction.Normal) relax = EditorGUILayout.Toggle(gc_relax, relax); }
protected virtual void UpdateTempComponent(z_BrushTarget target, z_BrushSettings settings) { if(!z_Util.IsValid(target)) return; tempComponent.SetWeights(target.weights, settings.strength); }
public static void DrawBrush( Vector3 point, Vector3 normal, z_BrushSettings brushSettings, Matrix4x4 matrix, Color innerColor, Color outerColor) { PushHandleColor(); Vector3 p = matrix.MultiplyPoint3x4(point); Vector3 n = matrix.MultiplyVector(normal).normalized; /// radius Handles.color = outerColor; Handles.DrawWireDisc(p, n, brushSettings.radius); /// falloff Handles.color = innerColor; Handles.DrawWireDisc(p, n, brushSettings.radius * brushSettings.falloff); Handles.color = new Color( Mathf.Abs(n.x), Mathf.Abs(n.y), Mathf.Abs(n.z), 1f); Handles.DrawLine(p, p + n.normalized * HandleUtility.GetHandleSize(p)); PopHandleColor(); }
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; }
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 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); }
public override void DrawGUI(z_BrushSettings settings) { base.DrawGUI(settings); EditorGUI.BeginChangeCheck(); brushStrength = EditorGUILayout.FloatField(gc_BrushEffect, brushStrength); if(EditorGUI.EndChangeCheck()) EditorPrefs.SetFloat(BRUSH_EFFECT_PREF, brushStrength); }
// 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); }
protected override void CreateTempComponent(z_EditableObject target, z_BrushSettings settings) { z_OverlayRenderer ren = target.gameObject.AddComponent<z_OverlayRenderer>(); ren.SetMesh(target.mesh); ren.fullColor = z_Pref.GetColor(z_Pref.brushColor); ren.gradient = z_Pref.GetGradient(z_Pref.brushGradient); tempComponent = ren; }
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); }
// 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); }
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(BRUSH_EFFECT_PREF, brushStrength); } }
public override void OnBrushEnter(z_EditableObject target, z_BrushSettings settings) { base.OnBrushEnter(target, settings); neighborLookup = z_MeshUtility.GetAdjacentVertices(target.mesh); int vertexCount = target.mesh.vertexCount; cached_vertices = new Vector3[vertexCount]; cached_normals = new Vector3[vertexCount]; System.Array.Copy(target.mesh.vertices, cached_vertices, vertexCount); System.Array.Copy(target.mesh.normals, cached_normals, vertexCount); }
/** * 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; }
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; }
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 DrawGUI(z_BrushSettings settings) { base.DrawGUI(settings); GUILayout.Label(ModeSettingsHeader, z_GUI.headerTextStyle); ignoreNonManifoldIndices = EditorGUILayout.Toggle(gc_ignoreOpenEdges, ignoreNonManifoldIndices); EditorGUI.BeginChangeCheck(); direction = (z_Direction) EditorGUILayout.EnumPopup(gc_direction, direction); if(EditorGUI.EndChangeCheck()) EditorPrefs.SetInt(z_Pref.sculptDirection, (int) direction); }
public void SetBrushSettings(z_BrushSettings settings) { if(settings == null) return; if(brushSettings != null && brushSettings != settings) GameObject.DestroyImmediate(brushSettings); brushSettingsAsset = settings; brushSettings = settings.DeepCopy(); brushSettings.hideFlags = HideFlags.HideAndDontSave; RefreshAvailableBrushes(); Repaint(); }
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); // } }
/// 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.Label("Placement Settings", z_GUI.headerTextStyle); placeWithPivot = EditorGUILayout.Toggle("Use Pivot", placeWithPivot); GUILayout.Space(4); gameObject = (GameObject) EditorGUILayout.ObjectField("GameObject", gameObject, typeof(GameObject), true); GUILayout.BeginVertical( paletteStyle ); prefabPaletteEditor.OnInspectorGUI(); GUILayout.EndHorizontal(); }
// 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", z_GUI.headerTextStyle); 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 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); } } }
// 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); }
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); }
// 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(); }
public override void OnBrushApply(z_BrushTarget target, z_BrushSettings settings) { Vector3[] vertices = target.editableObject.vertices; Vector3 v, t, avg, dirVec = direction.ToVector3(); Plane plane = new Plane(Vector3.up, Vector3.zero); foreach(KeyValuePair<int, float> weight in target.weights) { if(weight.Value < .0001f || (ignoreNonManifoldIndices && nonManifoldIndices.Contains(weight.Key))) continue; v = vertices[weight.Key]; if(direction == z_Direction.Normal && relax) avg = z_Math.Average(cached_vertices, neighborLookup[weight.Key]); else avg = z_Math.WeightedAverage(cached_vertices, neighborLookup[weight.Key], target.weights); if(direction != z_Direction.Normal || !relax) { if(direction == z_Direction.Normal) dirVec = z_Math.WeightedAverage(cached_normals, neighborLookup[weight.Key], target.weights).normalized; plane.SetNormalAndPosition(dirVec, avg); avg = v - dirVec * plane.GetDistanceToPoint(v); } t = Vector3.Lerp(v, avg, weight.Value); vertices[weight.Key] = v + (t-v) * settings.strength * SMOOTH_STRENGTH_MODIFIER; } target.editableObject.mesh.vertices = vertices; if(tempComponent != null) tempComponent.OnVerticesMoved(); base.OnBrushApply(target, settings); }
// 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); } } } }
/// 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.Label("Paint Settings", z_GUI.headerTextStyle); GUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); paintMode = (z_PaintMode) GUILayout.Toolbar( (int) paintMode, modeIcons, "Command", null); GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); GUILayout.Space(4); // GUILayout.Label( brushColor.ToString() ); // GUILayout.Label( meshAttributes.ToString("\n")); // 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); else brushColor = z_SplatWeightEditor.OnInspectorGUI(brushColor, textures); }
// 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; } }
// 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", null); 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 } }
private void AddNewBrush() { brushSettings = z_BrushSettingsEditor.AddNew(); RefreshAvailableBrushes(); }
public void SetBrush(z_BrushSettings settings) { if(settings == null) return; brushSettings = settings; RefreshAvailableBrushes(); Repaint(); }
public override void OnBrushEnter(z_EditableObject target, z_BrushSettings settings) { base.OnBrushEnter(target, settings); nonManifoldIndices = z_MeshUtility.GetNonManifoldIndices(target.mesh); }
void OnBrushEnter(z_EditableObject editableObject, z_BrushSettings settings) { mode.OnBrushEnter(editableObject, settings); }
void OnBrushEnter(z_BrushTarget target, z_BrushSettings settings) { mode.OnBrushEnter(target.editableObject, settings); }
public override void OnBrushBeginApply(z_BrushTarget brushTarget, z_BrushSettings brushSettings) { _pbEditor = z_ReflectionUtil.pbEditor; base.OnBrushBeginApply(brushTarget, brushSettings); }
void OnGUI() { Event e = Event.current; z_GUI.PushGUISkin(z_GUI.PolybrushSkin); if(e.type == EventType.ContextClick) OpenContextMenu(); GUILayout.Space(8); EditorGUI.BeginChangeCheck(); int toolbarIndex = (int) tool - 1; toolbarIndex = GUILayout.Toolbar(toolbarIndex, modeIcons, "Mode"); if(EditorGUI.EndChangeCheck()) { z_BrushTool newTool = (z_BrushTool) (toolbarIndex + 1); SetTool( newTool == tool ? z_BrushTool.None : (z_BrushTool)toolbarIndex + 1 ); } // Call current mode GUI if(mode != null && tool != z_BrushTool.Settings) { if(!z_Pref.GetBool(z_Pref.lockBrushSettings)) { z_GUI.PopGUISkin(); scroll = EditorGUILayout.BeginScrollView(scroll); z_GUI.PushGUISkin(z_GUI.PolybrushSkin); } // Show the settings header in z_Editor so that the preset selector can be included in the block. // Can't move preset selector to z_BrushSettingsEditor because it's a CustomEditor for z_BrushSettings, //commented out code was ommited here if(z_GUILayout.HeaderWithDocsLink(z_GUI.TempContent("Brush Settings"))) Application.OpenURL("http://procore3d.github.io/polybrush/brushSettings/"); /** * Brush preset selector */ GUILayout.BeginHorizontal(); EditorGUI.BeginChangeCheck(); currentBrushIndex = EditorGUILayout.Popup(currentBrushIndex, availableBrushes_str, "Popup"); if(EditorGUI.EndChangeCheck()) { if(currentBrushIndex >= availableBrushes.Count) SetBrushSettings(z_BrushSettingsEditor.AddNew()); else SetBrushSettings(availableBrushes[currentBrushIndex]); } if(GUILayout.Button( gc_SaveBrushSettings, GUILayout.Width(40) )) { if(brushSettings != null && brushSettingsAsset != null) { // integer 0, 1 or 2 corresponding to ok, cancel and alt buttons int res = EditorUtility.DisplayDialogComplex("Save Brush Settings", "Overwrite brush preset or save as a new preset? ", "Save", "Save As", "Cancel"); if(res == 0) { brushSettings.CopyTo(brushSettingsAsset); EditorGUIUtility.PingObject(brushSettingsAsset); } else if(res == 1) { z_BrushSettings dup = z_BrushSettingsEditor.AddNew(); string name = dup.name; brushSettings.CopyTo(dup); dup.name = name; // want to retain the unique name generated by AddNew() SetBrushSettings(dup); EditorGUIUtility.PingObject(brushSettingsAsset); } } else { Debug.LogWarning("Something went wrong saving brush settings."); } } GUILayout.EndHorizontal(); EditorGUI.BeginChangeCheck(); brushEditor.OnInspectorGUI(); if(z_Pref.GetBool(z_Pref.lockBrushSettings)) { z_GUI.PopGUISkin(); scroll = EditorGUILayout.BeginScrollView(scroll); z_GUI.PushGUISkin(z_GUI.PolybrushSkin); //commented out code was ommited here /** * Mirroring */ if(z_GUILayout.HeaderWithDocsLink(z_GUI.TempContent("Brush Mirroring"))) Application.OpenURL("http://procore3d.github.io/polybrush/brushMirroring/"); GUILayout.BeginHorizontal(); brushMirror = (z_BrushMirror) z_GUILayout.BitMaskField((uint)brushMirror, System.Enum.GetNames(typeof(z_BrushMirror)), "Set Brush Mirroring"); mirrorSpace = (z_MirrorCoordinateSpace) GUILayout.Toolbar((int) mirrorSpace, mirrorSpaceGuiContent, "Command"); GUILayout.EndHorizontal(); mode.DrawGUI(brushSettings); // When using non-conforming heights in a GUIStyle the GUI will sometimes // clip the content too early - this pads the size so that doesn't happen. GUILayout.Space(16); if(EditorGUI.EndChangeCheck()) mode.OnBrushSettingsChanged(brushTarget, brushSettings); EditorGUILayout.EndScrollView(); } else { if(tool == z_BrushTool.Settings) { z_GlobalSettingsEditor.OnGUI(); } else { // ...yo dawg, heard you like FlexibleSpace GUILayout.BeginVertical(); GUILayout.FlexibleSpace(); GUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); GUILayout.Label("Select an Edit Mode", z_GUI.headerTextStyle); GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); GUILayout.FlexibleSpace(); GUILayout.EndVertical(); } } #if POLYBRUSH_DEBUG z_GUI.PushUnitySkin(); GUILayout.Label("DEBUG", EditorStyles.boldLabel); GUILayout.Label("target: " + (z_Util.IsValid(brushTarget) ? brushTarget.editableObject.gameObject.name : "null")); GUILayout.Label("vertex: " + (z_Util.IsValid(brushTarget) ? brushTarget.editableObject.vertexCount : 0)); GUILayout.Label("applying: " + applyingBrush); GUILayout.Label("lockBrushToFirst: " + lockBrushToFirst); GUILayout.Label("lastHoveredGameObject: " + lastHoveredGameObject); GUILayout.Space(6); foreach(var kvp in hovering) { z_BrushTarget t = kvp.Value; z_EditableObject dbg_editable = t.editableObject; GUILayout.Label("Vertex Streams: " + dbg_editable.usingVertexStreams); GUILayout.Label("Original: " + (dbg_editable.originalMesh == null ? "null" : dbg_editable.originalMesh.name)); GUILayout.Label("Active: " + (dbg_editable.editMesh == null ? "null" : dbg_editable.editMesh.name)); GUILayout.Label("Graphics: " + (dbg_editable.graphicsMesh == null ? "null" : dbg_editable.graphicsMesh.name)); } z_GUI.PopGUISkin(); #endif z_GUI.PopGUISkin(); if(wantsRepaint) { wantsRepaint = false; Repaint(); } } void OpenContextMenu() { GenericMenu menu = new GenericMenu(); menu.AddItem (new GUIContent("Open as Floating Window", ""), z_Pref.GetBool(z_Pref.floatingEditorWindow, false), () => { SetWindowFloating(true); } ); menu.AddItem (new GUIContent("Open as Dockable Window", ""), !z_Pref.GetBool(z_Pref.floatingEditorWindow, false), () => { SetWindowFloating(false); } ); menu.ShowAsContext (); } void OnProBuilderEditLevelChanged(int i) { // Top = 0, // Geometry = 1, // Texture = 2, // Plugin = 4 if(i > 0 && tool != z_BrushTool.None) SetTool(z_BrushTool.None); } void SetTool(z_BrushTool brushTool) { if(brushTool == tool && mode != null) return; if(z_ReflectionUtil.ProBuilderEditorWindow != null && brushTool != z_BrushTool.None) z_ReflectionUtil.Invoke(z_ReflectionUtil.ProBuilderEditorWindow, "SetEditLevel", BindingFlags.Public | BindingFlags.Instance, 0); if(mode != null) { // Exiting edit mode if(lastHoveredGameObject != null) { OnBrushExit( lastHoveredGameObject ); FinalizeAndResetHovering(); } mode.OnDisable(); } else { if(z_ReflectionUtil.ProBuilderEditorWindow != null && brushTool != z_BrushTool.None) z_ReflectionUtil.Invoke(z_ReflectionUtil.ProBuilderEditorWindow, "SetEditLevel", BindingFlags.Public | BindingFlags.Instance, 0); } lastHoveredGameObject = null; System.Type modeType = brushTool.GetModeType(); if(modeType != null) { mode = modes.FirstOrDefault(x => x != null && x.GetType() == modeType); if(mode == null) mode = (z_BrushMode) ScriptableObject.CreateInstance( modeType ); } tool = brushTool; if(tool != z_BrushTool.None) { Tools.current = Tool.None; mode.OnEnable(); } Repaint(); }
/// 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; colors.CopyTo(colors_cache); colors_cache.Apply(target.mesh); base.OnBrushApply(target, settings); }
// 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); }
// 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); }
public override void DrawGizmos(z_BrushTarget target, z_BrushSettings settings) { if(z_Util.IsValid(target) && paintMode == z_PaintMode.Fill) { Vector3[] vertices = target.mesh.vertices; int[] indices = target.mesh.triangles; 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]].GetColor32(0); 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); if(triangleLookup.ContainsKey(hit.triangle)) { foreach(int i in triangleLookup[hit.triangle]) { Handles.color = target_colors[indices[index]].GetColor32(0); index = i * 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); } }
public override void OnBrushSettingsChanged(z_BrushTarget target, z_BrushSettings settings) { base.OnBrushSettingsChanged(target, settings); 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; switch(paintMode) { case z_PaintMode.Fill: colors_cache.CopyTo(colors); int[] indices = target.mesh.triangles; int index = 0; foreach(z_RaycastHit hit in target.raycastHits) { if(hit.triangle > -1) { index = hit.triangle * 3; colors[indices[index + 0]] = shift ? z_SplatWeight.Channel0 : target_colors[indices[index + 0]]; colors[indices[index + 1]] = shift ? z_SplatWeight.Channel0 : target_colors[indices[index + 1]]; colors[indices[index + 2]] = shift ? z_SplatWeight.Channel0 : target_colors[indices[index + 2]]; if(triangleLookup.ContainsKey(hit.triangle)) { foreach(int i in triangleLookup[hit.triangle]) { index = i * 3; colors[indices[index + 0]] = shift ? z_SplatWeight.Channel0 : target_colors[indices[index + 0]]; colors[indices[index + 1]] = shift ? z_SplatWeight.Channel0 : target_colors[indices[index + 1]]; colors[indices[index + 2]] = shift ? z_SplatWeight.Channel0 : target_colors[indices[index + 2]]; } } } } break; default: foreach(KeyValuePair<int, float> weight in target.weights) colors[weight.Key] = z_SplatWeight.Lerp( colors_cache[weight.Key], shift ? erase_colors[weight.Key] : target_colors[weight.Key], weight.Value); break; } colors.Apply(target.mesh); }
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.shift ? -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); }
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 = (GameObject)GameObject.Instantiate( prefab, target.transform.TransformPoint(rand_hit.position), 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); } instances.Add(inst); Undo.RegisterCreatedObjectUndo(inst, UndoMessage); } }
private void RebuildCaches(Mesh m, z_BrushSettings settings) { vertexCount = m.vertexCount; colors_cache = new z_SplatSet(m, meshAttributes); colors = new z_SplatSet(vertexCount, meshAttributes); target_colors = new z_SplatSet(vertexCount, meshAttributes); erase_colors = new z_SplatSet(vertexCount, meshAttributes); triangleLookup = z_MeshUtility.GetAdjacentTriangles(m); for(int i = 0; i < colors_cache.Length; i++) { target_colors[i] = z_SplatWeight.Lerp(colors_cache[i], brushColor, settings.strength); erase_colors[i] = z_SplatWeight.Lerp(colors_cache[i], z_SplatWeight.Channel0, settings.strength); } }
/** * Returns a dictionary of the indices of all affected vertices and the weight with * which modifications should be applied. */ public static void GetWeightedVerticesWithBrush(z_BrushTarget target, z_BrushSettings settings) { if( target.editableObject == null) return; Dictionary<int, float> weights = target.weights; if(target.raycastHits.Count < 1) { for(int i = 0; i < target.mesh.vertexCount; i++) weights[i] = 0f; return; } bool uniformScale = z_Math.VectorIsUniform(target.transform.lossyScale); float scale = uniformScale ? 1f / target.transform.lossyScale.x : 1f; int vertexCount = target.mesh.vertexCount; Transform transform = target.transform; Vector3[] vertices = target.editableObject.vertices; if(!uniformScale) { Vector3[] world = new Vector3[vertexCount]; for(int i = 0; i < vertexCount; i++) world[i] = transform.TransformPoint(vertices[i]); vertices = world; } float radius = settings.radius * scale, falloff_mag = Mathf.Max((radius - radius * settings.falloff), 0.00001f); Vector3 hitPosition = Vector3.zero; z_RaycastHit hit = target.raycastHits[0]; hitPosition = uniformScale ? hit.position : transform.TransformPoint(hit.position); // apply first brush hit, then add values on subsequent hits for(int i = 0; i < vertexCount; i++) { float dist = Vector3.Distance(hitPosition, vertices[i]); weights[i] = Mathf.Clamp(settings.falloffCurve.Evaluate(1f - Mathf.Clamp((radius - dist) / falloff_mag, 0f, 1f)), 0f, 1f); } for(int n = 1; n < target.raycastHits.Count; n++) { hit = target.raycastHits[n]; hitPosition = uniformScale ? hit.position : transform.TransformPoint(hit.position); for(int i = 0; i < vertexCount; i++) { float dist = Vector3.Distance(hitPosition, vertices[i]); weights[i] += Mathf.Clamp(settings.falloffCurve.Evaluate(1f - Mathf.Clamp((radius - dist) / falloff_mag, 0f, 1f)), 0f, 1f); } } }
// 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(); }
void OnBrushBeginApply(z_BrushTarget brushTarget, z_BrushSettings settings) { z_SceneUtility.PushGIWorkflowMode(); mode.RegisterUndo(brushTarget); undoQueue.Add(brushTarget.gameObject); mode.OnBrushBeginApply(brushTarget, brushSettings); }
/// 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.mesh == null) return; MeshRenderer mr = target.gameObject.GetComponent<MeshRenderer>(); Material mat = mr == null ? null : mr.sharedMaterials.FirstOrDefault(x => x != null && z_ShaderUtil.SupportsTextureBlending(x.shader)); likelySupportsTextureBlending = mat != null; if(likelySupportsTextureBlending) { textures = z_ShaderUtil.GetBlendTextures(mat); z_MeshChannel[] c = z_ShaderUtil.GetUsedMeshAttributes(mat); if(c != null) meshAttributes = c; } if( textures != null && brushColor.Length != textures.Length ) brushColor.Resize(textures.Length); RebuildCaches(target.mesh, settings); }
public override void OnBrushEnter(z_EditableObject target, z_BrushSettings settings) { base.OnBrushEnter(target, settings); normalLookup = z_MeshUtility.GetSmoothNormalLookup(target.mesh); }
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); } }
/** * Calculates the per-vertex weight for each raycast hit and fills in brush target weights. */ public static void CalculateWeightedVertices(z_BrushTarget target, z_BrushSettings settings) { if (target.editableObject == null) { return; } bool uniformScale = z_Math.VectorIsUniform(target.transform.lossyScale); float scale = uniformScale ? 1f / target.transform.lossyScale.x : 1f; z_Mesh mesh = target.editableObject.editMesh; List <List <int> > common = z_MeshUtility.GetCommonVertices(mesh); Transform transform = target.transform; int vertexCount = mesh.vertexCount; Vector3[] vertices = mesh.vertices; if (!uniformScale) { Vector3[] world = new Vector3[vertexCount]; for (int i = 0; i < vertexCount; i++) { world[i] = transform.TransformPoint(vertices[i]); } vertices = world; } AnimationCurve curve = settings.falloffCurve; float radius = settings.radius * scale, falloff_mag = Mathf.Max((radius - radius * settings.falloff), 0.00001f); Vector3 hitPosition = Vector3.zero; z_RaycastHit hit; for (int n = 0; n < target.raycastHits.Count; n++) { hit = target.raycastHits[n]; hit.SetVertexCount(vertexCount); hitPosition = uniformScale ? hit.position : transform.TransformPoint(hit.position); int c = common.Count; for (int i = 0; i < c; i++) { int commonArrayCount = common[i].Count; Vector3 a = hitPosition, b = vertices[common[i][0]]; float x = a.x - b.x, y = a.y - b.y, z = a.z - b.z; float dist = Mathf.Sqrt(x * x + y * y + z * z); if (dist > radius) { for (int j = 0; j < commonArrayCount; j++) { hit.weights[common[i][j]] = 0f; } } else { float weight = Mathf.Clamp(curve.Evaluate(1f - Mathf.Clamp((radius - dist) / falloff_mag, 0f, 1f)), 0f, 1f); for (int j = 0; j < commonArrayCount; j++) { hit.weights[common[i][j]] = weight; } } } } target.GetAllWeights(true); }