protected override void UpdateTempComponent(z_BrushTarget target, z_BrushSettings settings) { if(tempComponent != null && target.weights != null) { ((z_OverlayRenderer)tempComponent).SetWeights(target.weights, settings.strength); } }
protected virtual void UpdateTempComponent(z_BrushTarget target, z_BrushSettings settings) { if(!z_Util.IsValid(target)) return; tempComponent.SetWeights(target.weights, settings.strength); }
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 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.mesh, UndoMessage); modifiedMeshes.Add(brushTarget.editableObject.mesh); } brushTarget.editableObject.isDirty = true; }
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 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 OnBrushSettingsChanged(z_BrushTarget target, z_BrushSettings settings) { base.OnBrushSettingsChanged(target, settings); RebuildColorTargets(brushColor, 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); } } }
void OnBrushBeginApply(z_BrushTarget brushTarget, z_BrushSettings settings) { z_SceneUtility.PushGIWorkflowMode(); mode.RegisterUndo(brushTarget); undoQueue.Add(brushTarget.gameObject); mode.OnBrushBeginApply(brushTarget, brushSettings); }
public abstract void RegisterUndo(z_BrushTarget brushTarget);
/// set mesh colors back to their original state before registering for undo public override void RegisterUndo(z_BrushTarget brushTarget) { brushTarget.mesh.colors32 = colors_cache; 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.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); } }
/// 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( (EditorApplication.timeSinceStartup - lastBrushApplication) > Mathf.Max(.06f, (1f - settings.strength)) ) { lastBrushApplication = EditorApplication.timeSinceStartup; foreach(z_RaycastHit hit in target.raycastHits) PlaceGameObject(hit, gameObject, 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; }
/// Called when the mouse begins a drag across a valid target. public virtual void OnBrushBeginApply(z_BrushTarget target, z_BrushSettings 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 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(); }
/// 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 abstract void OnBrushApply(z_BrushTarget target, z_BrushSettings settings);
/// set mesh colors back to their original state before registering for undo public override void RegisterUndo(z_BrushTarget brushTarget) { colors_cache.Apply(brushTarget.mesh); base.RegisterUndo(brushTarget); }
/// 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.mesh.colors32 = colors_cache; base.OnBrushApply(target, settings); }
public override void OnBrushBeginApply(z_BrushTarget brushTarget, z_BrushSettings brushSettings) { _pbEditor = z_ReflectionUtil.pbEditor; base.OnBrushBeginApply(brushTarget, brushSettings); }
public override void OnBrushSettingsChanged(z_BrushTarget target, z_BrushSettings settings) { base.OnBrushSettingsChanged(target, settings); }
/// Handle Undo locally since it doesn't follow the same pattern as mesh modifications. public override void RegisterUndo(z_BrushTarget brushTarget) {}
/// 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); }
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); Debug.DrawRay( target.transform.TransformPoint(ray.origin), target.transform.TransformDirection(ray.direction), Color.red); z_RaycastHit rand_hit; if( z_SceneUtility.MeshRaycast(ray, target.editableObject.meshFilter, 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.transform.position = inst.transform.position + inst.transform.up * pivotOffset; if(hitTransformIsParent) inst.transform.SetParent(target.transform); Undo.RegisterCreatedObjectUndo(inst, UndoMessage); } }
/// 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; switch(paintMode) { case z_PaintMode.Fill: System.Array.Copy(colors_cache, colors, vertexCount); 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 ? 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]]; if(triangleLookup.ContainsKey(hit.triangle)) { foreach(int i in triangleLookup[hit.triangle]) { index = i * 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: foreach(KeyValuePair<int, float> weight in target.weights) colors[weight.Key] = z_Util.Lerp( colors_cache[weight.Key], shift ? erase_colors[weight.Key] : target_colors[weight.Key], weight.Value); break; } target.mesh.colors32 = colors; }