protected override void UpdateTempComponent(z_BrushTarget target, z_BrushSettings settings)
		{
			if(tempComponent != null && target.weights != null)
			{
				((z_OverlayRenderer)tempComponent).SetWeights(target.weights, settings.strength);
			}
		}
Esempio n. 2
0
		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);
				}
			}
		}
Esempio n. 10
0
		void OnBrushBeginApply(z_BrushTarget brushTarget, z_BrushSettings settings)
		{
			z_SceneUtility.PushGIWorkflowMode();
			mode.RegisterUndo(brushTarget);
			undoQueue.Add(brushTarget.gameObject);
			mode.OnBrushBeginApply(brushTarget, brushSettings);
		}
Esempio n. 11
0
		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;
		}
Esempio n. 16
0
		/// Called when the mouse begins a drag across a valid target.
		public virtual void OnBrushBeginApply(z_BrushTarget target, z_BrushSettings settings) {}
Esempio n. 17
0
		/// 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);
		}
Esempio n. 18
0
		/// 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);
		}
Esempio n. 20
0
		/// 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);
		}
Esempio n. 23
0
		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) {}
Esempio n. 26
0
		/// 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;
		}