protected override float GetPropertyValue(ParticleProperty property, int index) { if (index >= 0 && index < cloth.invMasses.Length) { switch (property) { case ClothParticleProperty.Mass: return(1.0f / (cloth.invMasses[index] * cloth.areaContribution[index])); case ClothParticleProperty.Radius: return(cloth.principalRadii[index][0]); case ParticleProperty.Layer: return(Oni.GetGroupFromPhase(cloth.phases[index])); case ClothParticleProperty.SkinBackstop: return((cloth.IsSkinned) ? cloth.SkinConstraints.GetFirstBatch().skinRadiiBackstop[index * 3 + 2] : 0); case ClothParticleProperty.SkinBackstopRadius: return((cloth.IsSkinned) ? cloth.SkinConstraints.GetFirstBatch().skinRadiiBackstop[index * 3 + 1] : 0); case ClothParticleProperty.SkinRadius: return((cloth.IsSkinned) ? cloth.SkinConstraints.GetFirstBatch().skinRadiiBackstop[index * 3] : 0); case ClothParticleProperty.SkinStiffness: return((cloth.IsSkinned) ? cloth.SkinConstraints.GetFirstBatch().skinStiffnesses[index] : 0); } } return(0); }
protected override void SetPropertyValue(ParticleProperty property, int index, float value) { switch (property) { case ParticleProperty.MASS: cloth.mass[index] = value; float areaMass = cloth.mass[index] * cloth.areaContribution[index]; if (areaMass > 0) { cloth.invMasses[index] = 1 / areaMass; } else { cloth.invMasses[index] = 0; } break; case ParticleProperty.RADIUS: { cloth.solidRadii[index] = value; } break; case ParticleProperty.SKIN_BACKSTOP: cloth.SkinConstraints.skinRadiiBackstop[index * 2 + 1] = value; break; case ParticleProperty.SKIN_RADIUS: cloth.SkinConstraints.skinRadiiBackstop[index * 2] = value; break; } }
protected override void SetPropertyValue(ParticleProperty property, int index, float value) { if (index >= 0 && index < cloth.invMasses.Length) { switch (property) { case TearableClothParticleProperty.Mass: cloth.invMasses[index] = 1.0f / (Mathf.Max(value, 0.00001f) * cloth.areaContribution[index]); break; case TearableClothParticleProperty.Radius: cloth.solidRadii[index] = value; break; case ParticleProperty.Layer: cloth.phases[index] = Oni.MakePhase((int)value, cloth.SelfCollisions?Oni.ParticlePhase.SelfCollide:0);; break; case TearableClothParticleProperty.TearResistance: if (cloth is ObiTearableCloth) { cloth.tearResistance[index] = value; } break; } } }
protected override float GetPropertyValue(ParticleProperty property, int index) { switch (property) { case ParticleProperty.MASS: { return(emitter.mass[index]); } } return(0); }
protected override void SetPropertyValue(ParticleProperty property, int index, float value) { if (index >= 0 && index < emitter.invMasses.Length) { switch (property) { case ParticleProperty.Mass: emitter.invMasses[index] = 1.0f / Mathf.Max(value, 0.00001f); break; } } }
protected override float GetPropertyValue(ParticleProperty property, int index) { if (index >= 0 && index < emitter.invMasses.Length) { switch (property) { case ParticleProperty.Mass: { return(1.0f / emitter.invMasses[index]); } } } return(0); }
protected override float GetPropertyValue(ParticleProperty property, int index) { switch (property) { case TearableClothParticleProperty.Mass: return(1.0f / (cloth.invMasses[index] * cloth.areaContribution[index])); case TearableClothParticleProperty.Radius: return(cloth.solidRadii[index]); case TearableClothParticleProperty.TearResistance: return(cloth.tearResistance[index]); } return(0); }
protected override void SetPropertyValue(ParticleProperty property, int index, float value) { if (index >= 0 && index < cloth.invMasses.Length) { switch (property) { case ClothParticleProperty.Mass: cloth.invMasses[index] = 1.0f / (Mathf.Max(value, 0.00001f) * cloth.areaContribution[index]); break; case ClothParticleProperty.Radius: cloth.principalRadii[index] = Vector3.one * value; break; case ParticleProperty.Layer: cloth.phases[index] = Oni.MakePhase((int)value, cloth.SelfCollisions?Oni.ParticlePhase.SelfCollide:0);; break; case ClothParticleProperty.SkinBackstop: if (cloth.IsSkinned) { cloth.SkinConstraints.GetFirstBatch().skinRadiiBackstop[index * 3 + 2] = value; } break; case ClothParticleProperty.SkinBackstopRadius: if (cloth.IsSkinned) { cloth.SkinConstraints.GetFirstBatch().skinRadiiBackstop[index * 3 + 1] = value; } break; case ClothParticleProperty.SkinRadius: if (cloth.IsSkinned) { cloth.SkinConstraints.GetFirstBatch().skinRadiiBackstop[index * 3] = value; } break; case ClothParticleProperty.SkinStiffness: if (cloth.IsSkinned) { cloth.SkinConstraints.GetFirstBatch().skinStiffnesses[index] = value; } break; } } }
public void Cannot_Get_Property_Not_In_Valid_Readable_Hash_Set() { var property1 = new ParticleProperty(typeof(bool), "Something"); var property2 = new ParticleProperty(typeof(bool), "Something2"); var allocator = new ParticleAllocator(10); allocator.RegisterProperty(property1.Type, property1.Name); allocator.RegisterProperty(property2.Type, property2.Name); var reservation = allocator.Reserve(5); var collection = new ParticleCollection(reservation) { ValidPropertiesToSet = new HashSet <ParticleProperty>(new[] { property1 }) }; Assert.ThrowsAny <Exception>(() => collection.GetReadOnlyPropertyValues <bool>(property2.Name)); }
public void Properties_Marked_As_Valid_For_Reading_Can_Be_Retrieved_As_Read_Only() { var property = new ParticleProperty(typeof(bool), "Something"); var allocator = new ParticleAllocator(10); allocator.RegisterProperty(property.Type, property.Name); var reservation = allocator.Reserve(5); var collection = new ParticleCollection(reservation) { ValidPropertiesToRead = new HashSet <ParticleProperty>(new[] { property }) }; var result = collection.GetReadOnlyPropertyValues <bool>(property.Name); result.Length.ShouldBe(reservation.Length); }
protected override void SetPropertyValue(ParticleProperty property, int index, float value) { switch (property) { case ParticleProperty.MASS: emitter.mass[index] = value; float areaMass = emitter.mass[index]; //* rope.areaContribution[index]; if (areaMass > 0) { emitter.invMasses[index] = 1 / areaMass; } else { emitter.invMasses[index] = 0; } break; } }
protected override float GetPropertyValue(ParticleProperty property, int index) { switch (property) { case ParticleProperty.MASS: return(cloth.mass[index]); case ParticleProperty.RADIUS: return(cloth.solidRadii[index]); case ParticleProperty.SKIN_BACKSTOP: return(cloth.SkinConstraints.skinRadiiBackstop[index * 2 + 1]); case ParticleProperty.SKIN_RADIUS: return(cloth.SkinConstraints.skinRadiiBackstop[index * 2]); } return(0); }
protected override float GetPropertyValue(ParticleProperty property, int index) { if (index >= 0 && index < emitter.invMasses.Length) { switch (property) { case ParticleProperty.Mass: return(1.0f / emitter.invMasses[index]); case ParticleProperty.Radius: return(emitter.principalRadii[index][0]); case EmitterParticleProperty.RotationalMass: return(1.0f / emitter.invRotationalMasses[index]); } } return(0); }
protected override float GetPropertyValue(ParticleProperty property, int index) { if (index >= 0 && index < bone.invMasses.Length) { switch (property) { case ParticleProperty.Mass: return(1.0f / bone.invMasses[index]); case ParticleProperty.Radius: return(bone.solidRadii[index]); case BoneParticleProperty.Frozen: return(bone.frozen[index] ? 1 : 0); } } return(0); }
protected override void SetPropertyValue(ParticleProperty property, int index, float value) { if (index >= 0 && index < emitter.invMasses.Length) { switch (property) { case ParticleProperty.Mass: emitter.invMasses[index] = 1.0f / Mathf.Max(value, 0.00001f); break; case ParticleProperty.Radius: emitter.principalRadii[index] = Vector3.one * value; break; case EmitterParticleProperty.RotationalMass: emitter.invRotationalMasses[index] = 1.0f / Mathf.Max(value, 0.00001f); break; } } }
protected override void SetPropertyValue(ParticleProperty property, int index, float value) { switch (property) { case TearableClothParticleProperty.Mass: cloth.invMasses[index] = 1.0f / (Mathf.Max(value, 0.00001f) * cloth.areaContribution[index]); break; case TearableClothParticleProperty.Radius: cloth.solidRadii[index] = value; break; case TearableClothParticleProperty.TearResistance: if (cloth is ObiTearableCloth) { cloth.tearResistance[index] = value; } break; } }
protected override void SetPropertyValue(ParticleProperty property, int index, float value) { if (index >= 0 && index < bone.invMasses.Length) { switch (property) { case ParticleProperty.Mass: bone.invMasses[index] = 1.0f / Mathf.Max(value, 0.00001f); break; case ParticleProperty.Radius: bone.solidRadii[index] = value; break; case BoneParticleProperty.Frozen: bone.frozen[index] = value >= 1; break; } } }
protected override void SetPropertyValue(ParticleProperty property, int index, float value) { switch (property) { case ClothParticleProperty.Mass: cloth.invMasses[index] = 1.0f / (Mathf.Max(value, 0.00001f) * cloth.areaContribution[index]); break; case ClothParticleProperty.Radius: cloth.solidRadii[index] = value; break; case ClothParticleProperty.SkinBackstop: if (cloth.IsSkinned) { ((ObiSkinConstraintBatch)cloth.SkinConstraints.GetBatches()[0]).skinRadiiBackstop[index * 3 + 2] = value; } break; case ClothParticleProperty.SkinBackstopRadius: if (cloth.IsSkinned) { ((ObiSkinConstraintBatch)cloth.SkinConstraints.GetBatches()[0]).skinRadiiBackstop[index * 3 + 1] = value; } break; case ClothParticleProperty.SkinRadius: if (cloth.IsSkinned) { ((ObiSkinConstraintBatch)cloth.SkinConstraints.GetBatches()[0]).skinRadiiBackstop[index * 3] = value; } break; case ClothParticleProperty.SkinStiffness: if (cloth.IsSkinned) { ((ObiSkinConstraintBatch)cloth.SkinConstraints.GetBatches()[0]).skinStiffnesses[index] = value; } break; } }
protected override float GetPropertyValue(ParticleProperty property, int index) { if (index >= 0 && index < cloth.invMasses.Length) { switch (property) { case TearableClothParticleProperty.Mass: return(1.0f / (cloth.invMasses[index] * cloth.areaContribution[index])); case TearableClothParticleProperty.Radius: return(cloth.solidRadii[index]); case ParticleProperty.Layer: return(Oni.GetGroupFromPhase(cloth.phases[index])); case TearableClothParticleProperty.TearResistance: return(cloth.tearResistance[index]); } } return(0); }
protected override float GetPropertyValue(ParticleProperty property, int index) { if (index >= 0 && index < rod.invMasses.Length) { switch (property) { case RodParticleProperty.Mass: return(1.0f / rod.invMasses[index]); case RodParticleProperty.RotationalMass: return(1.0f / rod.invRotationalMasses[index]); case RodParticleProperty.Radius: return(rod.principalRadii[index][0]); case RodParticleProperty.Layer: return(Oni.GetGroupFromPhase(rod.phases[index])); } } return(0); }
protected override float GetPropertyValue(ParticleProperty property, int index) { if (index >= 0 && index < rope.invMasses.Length) { switch (property) { case ParticleProperty.Mass: return(1.0f / rope.invMasses[index]); case ParticleProperty.Radius: return(rope.solidRadii[index]); case ParticleProperty.Layer: return(Oni.GetGroupFromPhase(rope.phases[index])); case TearableRopeParticleProperty.TearResistance: return(rope.tearResistance[index]); } } return(0); }
protected override float GetPropertyValue(ParticleProperty property, int index) { switch (property) { case ClothParticleProperty.Mass: return(1.0f / (cloth.invMasses[index] * cloth.areaContribution[index])); case ClothParticleProperty.Radius: return(cloth.solidRadii[index]); case ClothParticleProperty.SkinBackstop: return((cloth.IsSkinned) ? ((ObiSkinConstraintBatch)cloth.SkinConstraints.GetBatches()[0]).skinRadiiBackstop[index * 3 + 2] : 0); case ClothParticleProperty.SkinBackstopRadius: return((cloth.IsSkinned) ? ((ObiSkinConstraintBatch)cloth.SkinConstraints.GetBatches()[0]).skinRadiiBackstop[index * 3 + 1] : 0); case ClothParticleProperty.SkinRadius: return((cloth.IsSkinned) ? ((ObiSkinConstraintBatch)cloth.SkinConstraints.GetBatches()[0]).skinRadiiBackstop[index * 3] : 0); case ClothParticleProperty.SkinStiffness: return((cloth.IsSkinned) ? ((ObiSkinConstraintBatch)cloth.SkinConstraints.GetBatches()[0]).skinStiffnesses[index] : 0); } return(0); }
protected override void SetPropertyValue(ParticleProperty property, int index, float value) { if (index >= 0 && index < rope.invMasses.Length) { switch (property) { case ParticleProperty.Mass: rope.invMasses[index] = 1.0f / Mathf.Max(value, 0.00001f); break; case ParticleProperty.Radius: rope.solidRadii[index] = value; break; case ParticleProperty.Layer: rope.phases[index] = Oni.MakePhase((int)value, rope.SelfCollisions?Oni.ParticlePhase.SelfCollide:0);; break; case TearableRopeParticleProperty.TearResistance: rope.tearResistance[index] = value; break; } } }
protected override void SetPropertyValue(ParticleProperty property, int index, float value) { if (index >= 0 && index < rod.invMasses.Length) { switch (property) { case RodParticleProperty.Mass: rod.invMasses[index] = 1.0f / Mathf.Max(value, 0.00001f); break; case RodParticleProperty.RotationalMass: rod.invRotationalMasses[index] = 1.0f / Mathf.Max(value, 0.00001f); break; case RodParticleProperty.Radius: rod.principalRadii[index] = Vector3.one * value; break; case RodParticleProperty.Layer: rod.phases[index] = Oni.MakePhase((int)value, rod.SelfCollisions?Oni.ParticlePhase.SelfCollide:0); break; } } }
protected abstract float GetPropertyValue(ParticleProperty property, int index);
protected override void SetPropertyValue(ParticleProperty property,int index, float value) { switch(property){ case ParticleProperty.MASS: cloth.mass[index] = value; float areaMass = cloth.mass[index] * cloth.areaContribution[index]; if (areaMass > 0){ cloth.invMasses[index] = 1 / areaMass; }else{ cloth.invMasses[index] = 0; } break; case ParticleProperty.RADIUS:{ cloth.solidRadii[index] = value; }break; case ParticleProperty.SKIN_BACKSTOP: cloth.SkinConstraints.skinRadiiBackstop[index*2+1] = value; break; case ParticleProperty.SKIN_RADIUS: cloth.SkinConstraints.skinRadiiBackstop[index*2] = value; break; } }
protected override float GetPropertyValue(ParticleProperty property, int index) { switch(property){ case ParticleProperty.MASS: return cloth.mass[index]; case ParticleProperty.RADIUS: return cloth.solidRadii[index]; case ParticleProperty.SKIN_BACKSTOP: return cloth.SkinConstraints.skinRadiiBackstop[index*2+1]; case ParticleProperty.SKIN_RADIUS: return cloth.SkinConstraints.skinRadiiBackstop[index*2]; } return 0; }
/** * Draws a window with cloth tools: */ void DrawUIWindow(int windowID) { //------------------------------- // Visualization options //------------------------------- GUILayout.BeginHorizontal(); backfaces = GUILayout.Toggle(backfaces, "backfaces"); GUILayout.EndHorizontal(); GUILayout.Box("", separatorLine); //------------------------------- // Tools //------------------------------- bool customMenu = (CustomUIName() != null); GUILayout.BeginHorizontal(); if (GUILayout.Toggle(tool == EditionTool.SELECT, "Select", GUI.skin.FindStyle("ButtonLeft")) && tool != EditionTool.SELECT) { tool = EditionTool.SELECT; ForceWindowRelayout(); } if (GUILayout.Toggle(tool == EditionTool.SELECTBRUSH, "Brush", GUI.skin.FindStyle("ButtonMid")) && tool != EditionTool.SELECTBRUSH) { tool = EditionTool.SELECTBRUSH; ForceWindowRelayout(); } if (GUILayout.Toggle(tool == EditionTool.PAINT, "Paint", customMenu? GUI.skin.FindStyle("ButtonMid"):GUI.skin.FindStyle("ButtonRight")) && tool != EditionTool.PAINT) { tool = EditionTool.PAINT; ForceWindowRelayout(); } if (customMenu) { if (GUILayout.Toggle(tool == EditionTool.CUSTOM, CustomUIName(), GUI.skin.FindStyle("ButtonRight")) && tool != EditionTool.CUSTOM) { tool = EditionTool.CUSTOM; ForceWindowRelayout(); } } GUILayout.EndHorizontal(); EditorGUI.BeginChangeCheck(); currentProperty = (ParticleProperty)EditorGUILayout.EnumPopup(currentProperty, GUI.skin.FindStyle("DropDown")); if (EditorGUI.EndChangeCheck()) { ParticlePropertyChanged(); } switch (tool) { case EditionTool.SELECT: DrawSelectionToolUI(); break; case EditionTool.SELECTBRUSH: GUILayout.BeginHorizontal(); GUILayout.Label("Radius"); brushRadius = EditorGUILayout.Slider(brushRadius, 5, 200); GUILayout.EndHorizontal(); DrawSelectionToolUI(); break; case EditionTool.PAINT: DrawPaintToolUI(); break; case EditionTool.CUSTOM: DrawCustomUI(); break; } //------------------------------- //Playback functions //------------------------------- GUILayout.Box("", separatorLine); GUILayout.BeginHorizontal(); GUI.enabled = !EditorApplication.isPlaying; if (GUILayout.Button(EditorGUIUtility.Load("RewindButton.psd") as Texture2D, GUILayout.MaxHeight(24), GUILayout.Width(42))) { actor.ResetActor(); if (actor.InSolver) { actor.RemoveFromSolver(null); } accumulatedTime = 0; } if (GUILayout.Button(EditorGUIUtility.Load("StopButton.psd") as Texture2D, GUILayout.MaxHeight(24), GUILayout.Width(42))) { isPlaying = false; } if (GUILayout.Button(EditorGUIUtility.Load("PlayButton.psd") as Texture2D, GUILayout.MaxHeight(24), GUILayout.Width(42))) { if (!actor.InSolver) { actor.AddToSolver(null); } lastFrameTime = Time.realtimeSinceStartup; isPlaying = true; } if (GUILayout.Button(EditorGUIUtility.Load("StepButton.psd") as Texture2D, GUILayout.MaxHeight(24), GUILayout.Width(42))) { isPlaying = false; if (!actor.InSolver) { actor.AddToSolver(null); } if (actor.InSolver) { actor.solver.AccumulateSimulationTime(Time.fixedDeltaTime); actor.solver.SimulateStep(Time.fixedDeltaTime); actor.solver.EndFrame(Time.fixedDeltaTime); } } GUI.enabled = true; GUILayout.EndHorizontal(); }
protected abstract void SetPropertyValue(ParticleProperty property, int index, float value);
/** * Draws a window with cloth tools: */ void DrawUIWindow(int windowID) { //------------------------------- // Visualization options //------------------------------- GUILayout.BeginHorizontal(); backfaces = GUILayout.Toggle(backfaces,"backfaces"); GUILayout.EndHorizontal(); GUILayout.Box("",separatorLine); //------------------------------- // Tools //------------------------------- bool customMenu = (CustomUIName() != null); GUILayout.BeginHorizontal(); if (GUILayout.Toggle(tool == EditionTool.SELECT,"Select",GUI.skin.FindStyle("ButtonLeft")) && tool != EditionTool.SELECT){ tool = EditionTool.SELECT; ForceWindowRelayout(); } if (GUILayout.Toggle(tool == EditionTool.SELECTBRUSH,"Brush",GUI.skin.FindStyle("ButtonMid")) && tool != EditionTool.SELECTBRUSH){ tool = EditionTool.SELECTBRUSH; ForceWindowRelayout(); } if (GUILayout.Toggle(tool == EditionTool.PAINT,"Paint",customMenu? GUI.skin.FindStyle("ButtonMid"):GUI.skin.FindStyle("ButtonRight")) && tool != EditionTool.PAINT){ tool = EditionTool.PAINT; ForceWindowRelayout(); } if (customMenu){ if (GUILayout.Toggle(tool == EditionTool.CUSTOM,CustomUIName(),GUI.skin.FindStyle("ButtonRight")) && tool != EditionTool.CUSTOM){ tool = EditionTool.CUSTOM; ForceWindowRelayout(); } } GUILayout.EndHorizontal(); EditorGUI.BeginChangeCheck(); currentProperty = (ParticleProperty) EditorGUILayout.EnumPopup(currentProperty,GUI.skin.FindStyle("DropDown")); if (EditorGUI.EndChangeCheck()){ ParticlePropertyChanged(); } switch(tool){ case EditionTool.SELECT: DrawSelectionToolUI(); break; case EditionTool.SELECTBRUSH: GUILayout.BeginHorizontal(); GUILayout.Label("Radius"); brushRadius = EditorGUILayout.Slider(brushRadius,5,200); GUILayout.EndHorizontal(); DrawSelectionToolUI(); break; case EditionTool.PAINT: DrawPaintToolUI(); break; case EditionTool.CUSTOM: DrawCustomUI(); break; } //------------------------------- //Playback functions //------------------------------- GUILayout.Box("",separatorLine); GUILayout.BeginHorizontal(); GUI.enabled = !EditorApplication.isPlaying; if (GUILayout.Button(EditorGUIUtility.Load("RewindButton.psd") as Texture2D,GUILayout.MaxHeight(24),GUILayout.Width(42))){ actor.ResetActor(); if (actor.InSolver) actor.RemoveFromSolver(null); accumulatedTime = 0; } if (GUILayout.Button(EditorGUIUtility.Load("StopButton.psd") as Texture2D,GUILayout.MaxHeight(24),GUILayout.Width(42))){ isPlaying = false; } if (GUILayout.Button(EditorGUIUtility.Load("PlayButton.psd") as Texture2D,GUILayout.MaxHeight(24),GUILayout.Width(42))){ if (!actor.InSolver) actor.AddToSolver(null); lastFrameTime = Time.realtimeSinceStartup; isPlaying = true; } if (GUILayout.Button(EditorGUIUtility.Load("StepButton.psd") as Texture2D,GUILayout.MaxHeight(24),GUILayout.Width(42))){ isPlaying = false; if (!actor.InSolver) actor.AddToSolver(null); if (actor.InSolver){ actor.solver.AccumulateSimulationTime(Time.fixedDeltaTime); actor.solver.SimulateStep(Time.fixedDeltaTime); actor.solver.EndFrame(Time.fixedDeltaTime); } } GUI.enabled = true; GUILayout.EndHorizontal(); }
void DrawPropertyControls() { GUILayout.BeginHorizontal(); // Property dropdown: EditorGUI.BeginChangeCheck(); currentProperty = (ParticleProperty)EditorGUILayout.Popup(currentProperty, particlePropertyNames.ToArray()); if (EditorGUI.EndChangeCheck()) { newProperty = GetPropertyValue(currentProperty, lastSelectedParticle); ParticlePropertyChanged(); } // Property value: EditorGUI.showMixedValue = false; float selectionProperty = GetPropertyValue(currentProperty, lastSelectedParticle); for (int i = 0; i < selectionStatus.Length; i++) { if (selectionStatus[i] && !Mathf.Approximately(GetPropertyValue(currentProperty, i), selectionProperty)) { EditorGUI.showMixedValue = true; } } EditorGUI.BeginChangeCheck(); newProperty = EditorGUILayout.FloatField(newProperty, GUILayout.Width(88)); if (EditorGUI.EndChangeCheck()) { // If we are not in paint mode, allow instant change of particle properties: if (!paintBrush) { Undo.RecordObject(actor, "Set particle property"); for (int i = 0; i < selectionStatus.Length; i++) { if (!selectionStatus[i]) { continue; } SetPropertyValue(currentProperty, i, newProperty); } ParticlePropertyChanged(); } } EditorGUI.showMixedValue = false; GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); if (GUILayout.Button(new GUIContent(Resources.Load <Texture2D>("FillButton"), "Fill property value"), GUILayout.MaxHeight(24), GUILayout.Width(42))) { Undo.RecordObject(actor, "Property fill"); for (int i = 0; i < selectionStatus.Length; i++) { // Skip unselected particles, if selection mask is on. if (selectionMask && !selectionStatus[i]) { continue; } SetPropertyValue(currentProperty, i, newProperty); } ParticlePropertyChanged(); } selectionMask = GUILayout.Toggle(selectionMask, new GUIContent(Resources.Load <Texture2D>("MaskButton"), "Selection mask"), GUI.skin.FindStyle("Button"), GUILayout.MaxHeight(24), GUILayout.Width(42)); EditorGUI.BeginChangeCheck(); textureProperties = GUILayout.Toggle(textureProperties, new GUIContent(Resources.Load <Texture2D>("TextureButton")), GUI.skin.FindStyle("Button"), GUILayout.MaxHeight(24), GUILayout.Width(42)); if (EditorGUI.EndChangeCheck()) { if (textureProperties) { paintBrush = false; } ForceWindowRelayout(); } EditorGUI.BeginChangeCheck(); paintBrush = GUILayout.Toggle(paintBrush, new GUIContent(Resources.Load <Texture2D>("PaintButton"), "Paint brush"), GUI.skin.FindStyle("Button"), GUILayout.MaxHeight(24), GUILayout.Width(42)); if (EditorGUI.EndChangeCheck()) { if (paintBrush) { selectionBrush = false; textureProperties = false; } ForceWindowRelayout(); } GUILayout.EndHorizontal(); if (paintBrush) { GUILayout.BeginHorizontal(); if (GUILayout.Toggle(paintMode == PaintBrushType.Gaussian, new GUIContent(Resources.Load <Texture2D>("GaussianButton"), "Soft brush"), GUI.skin.FindStyle("ButtonLeft"), GUILayout.MaxHeight(28))) { paintMode = PaintBrushType.Gaussian; } if (GUILayout.Toggle(paintMode == PaintBrushType.Pencil, new GUIContent(Resources.Load <Texture2D>("PencilButton"), "Pencil"), GUI.skin.FindStyle("ButtonMid"), GUILayout.MaxHeight(28))) { paintMode = PaintBrushType.Pencil; } if (GUILayout.Toggle(paintMode == PaintBrushType.Smooth, new GUIContent(Resources.Load <Texture2D>("SmoothButton"), "Smooth"), GUI.skin.FindStyle("ButtonRight"), GUILayout.MaxHeight(28))) { paintMode = PaintBrushType.Smooth; } GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); GUILayout.Label("Radius"); brushRadius = EditorGUILayout.Slider(brushRadius, 5, 200); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); GUILayout.Label("Opacity"); brushOpacity = EditorGUILayout.Slider(brushOpacity, 0, 1); GUILayout.EndHorizontal(); EditorGUI.BeginChangeCheck(); // auto range visualization: autoRangeDraw = GUILayout.Toggle(autoRangeDraw, "Auto range visualization"); if (!autoRangeDraw) { GUILayout.BeginHorizontal(); GUILayout.Label("Min"); GUILayout.FlexibleSpace(); minPropertyValue = EditorGUILayout.FloatField(minPropertyValue, GUILayout.Width(EditorGUIUtility.fieldWidth)); GUILayout.FlexibleSpace(); GUILayout.Label("Max"); GUILayout.FlexibleSpace(); maxPropertyValue = EditorGUILayout.FloatField(maxPropertyValue, GUILayout.Width(EditorGUIUtility.fieldWidth)); GUILayout.EndHorizontal(); } if (EditorGUI.EndChangeCheck()) { ParticlePropertyChanged(); ForceWindowRelayout(); } } if (textureProperties) { GUILayout.BeginHorizontal(); float oldLabelWidth = EditorGUIUtility.labelWidth; EditorGUIUtility.labelWidth = 40; GUILayout.Label("Source"); propertyTexture = (Texture2D)EditorGUILayout.ObjectField("", propertyTexture, typeof(Texture2D), false); EditorGUIUtility.labelWidth = oldLabelWidth; GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); GUILayout.Label("Source channel"); GUILayout.FlexibleSpace(); textureChannel = (TextureChannel)EditorGUILayout.EnumPopup(textureChannel); GUILayout.EndHorizontal(); EditorGUI.BeginChangeCheck(); GUILayout.BeginHorizontal(); GUILayout.Label("Min value"); GUILayout.FlexibleSpace(); minPropertyValue = EditorGUILayout.FloatField(minPropertyValue, GUILayout.Width(EditorGUIUtility.fieldWidth)); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); GUILayout.Label("Max value"); GUILayout.FlexibleSpace(); maxPropertyValue = EditorGUILayout.FloatField(maxPropertyValue, GUILayout.Width(EditorGUIUtility.fieldWidth)); GUILayout.EndHorizontal(); if (GUILayout.Button("Load property")) { Undo.RecordObject(actor, "Load particle property"); if (!actor.ReadParticlePropertyFromTexture(propertyTexture, (int i, Color color) => { if (!selectionMask || selectionStatus[i]) { SetPropertyValue(currentProperty, i, minPropertyValue + color[(int)textureChannel] * (maxPropertyValue - minPropertyValue)); } })) { EditorUtility.DisplayDialog("Invalid texture", "The texture is either null or not readable.", "Ok"); } ParticlePropertyChanged(); } // auto range visualization: autoRangeDraw = GUILayout.Toggle(autoRangeDraw, "Auto range visualization"); if (EditorGUI.EndChangeCheck()) { ParticlePropertyChanged(); } } }