public void OnEnable()
        {
            cloth = (ObiCloth)target;

            // In case the cloth has not been initialized yet, start the initialization routine.
            if (!cloth.Initialized && !cloth.Initializing){
            CoroutineJob job = new CoroutineJob();
            routine = EditorCoroutine.StartCoroutine(job.Start(cloth.GeneratePhysicRepresentationForMesh()));
            }

            EditorApplication.update += Update;
            EditorApplication.playmodeStateChanged += OnPlayModeStateChanged;
        }
 public static void ShowCoroutineProgressBar(string title, EditorCoroutine coroutine)
 {
     #if (UNITY_EDITOR)
     if (coroutine != null && !coroutine.IsDone){
     CoroutineJob.ProgressInfo progressInfo = coroutine.Result as CoroutineJob.ProgressInfo;
     if (progressInfo != null){
         if (EditorUtility.DisplayCancelableProgressBar(title, progressInfo.userReadableInfo, progressInfo.progress)){
             coroutine.Stop();
         }
     }
     }else{
     EditorUtility.ClearProgressBar();
     }
     #endif
 }
 void Source_OnInitialized(object sender, EventArgs e)
 {
     if (!bound)
     {
         if (Application.isPlaying)
         {
             IEnumerator g = BindSkin();
             while (g.MoveNext())
             {
             }
         }
         else
         {
             // In editor, show a progress bar while binding the skin:
             CoroutineJob job     = new CoroutineJob();
             IEnumerator  routine = job.Start(BindSkin());
             EditorCoroutine.ShowCoroutineProgressBar("Binding to particles...", ref routine);
         }
     }
 }
 public static void ShowCoroutineProgressBar(string title, EditorCoroutine coroutine)
 {
         #if (UNITY_EDITOR)
     if (coroutine != null && !coroutine.IsDone)
     {
         CoroutineJob.ProgressInfo progressInfo = coroutine.Result as CoroutineJob.ProgressInfo;
         if (progressInfo != null)
         {
             if (EditorUtility.DisplayCancelableProgressBar(title, progressInfo.userReadableInfo, progressInfo.progress))
             {
                 coroutine.Stop();
             }
         }
     }
     else
     {
         EditorUtility.ClearProgressBar();
     }
         #endif
 }
Beispiel #5
0
 protected void Generate()
 {
     if (blueprint.empty)
     {
         EditorUtility.SetDirty(target);
         CoroutineJob job = new CoroutineJob();
         routine = job.Start(blueprint.Generate());
         EditorCoroutine.ShowCoroutineProgressBar("Generating blueprint...", ref routine);
         EditorGUIUtility.ExitGUI();
     }
     else
     {
         if (EditorUtility.DisplayDialog("Blueprint generation", "This blueprint already contains data. Are you sure you want to re-generate this blueprint from scratch?", "Ok", "Cancel"))
         {
             EditorUtility.SetDirty(target);
             CoroutineJob job = new CoroutineJob();
             routine = job.Start(blueprint.Generate());
             EditorCoroutine.ShowCoroutineProgressBar("Generating blueprint...", ref routine);
             EditorGUIUtility.ExitGUI();
         }
     }
 }
        public override void OnInspectorGUI()
        {
            serializedObject.UpdateIfRequiredOrScript();

            Editor.DrawPropertiesExcluding(serializedObject, "m_Script");

            GUI.enabled = (distanceField.InputMesh != null);
            if (GUILayout.Button("Generate"))
            {
                // Start a coroutine job in the editor.
                CoroutineJob job = new CoroutineJob();
                routine = EditorCoroutine.StartCoroutine(job.Start(distanceField.Generate()));
                EditorUtility.SetDirty(target);
            }
            GUI.enabled = true;

            // Show job progress:
            EditorCoroutine.ShowCoroutineProgressBar("Generating distance field", routine);

            //If the generation routine has been completed, release it and update volumetric preview:
            if (routine != null && routine.IsDone)
            {
                routine = null;
                UpdatePreview();
            }

            int   nodeCount  = (distanceField.nodes != null ? distanceField.nodes.Length : 0);
            float resolution = distanceField.FieldBounds.size.x / distanceField.EffectiveSampleSize;

            EditorGUILayout.HelpBox("Nodes: " + nodeCount + "\n" +
                                    "Size in memory: " + (nodeCount * 0.052f).ToString("0.#") + " kB\n" +
                                    "Compressed to: " + (nodeCount / Mathf.Pow(resolution, 3) * 100).ToString("0.##") + "%", MessageType.Info);

            if (GUI.changed)
            {
                serializedObject.ApplyModifiedProperties();
            }
        }
Beispiel #7
0
        public override void OnInspectorGUI()
        {
            serializedObject.Update();

            GUI.enabled = bone.Initialized;
            EditorGUI.BeginChangeCheck();
            editMode = GUILayout.Toggle(editMode, new GUIContent("Edit particles", Resources.Load <Texture2D>("EditParticles")), "LargeButton");
            if (EditorGUI.EndChangeCheck())
            {
                SceneView.RepaintAll();
            }
            GUI.enabled = true;

            EditorGUILayout.LabelField("Status: " + (bone.Initialized ? "Initialized":"Not initialized"));

            if (GUILayout.Button("Initialize"))
            {
                if (!bone.Initialized)
                {
                    CoroutineJob job = new CoroutineJob();
                    routine = EditorCoroutine.StartCoroutine(job.Start(bone.GeneratePhysicRepresentationForBones()));
                    EditorSceneManager.MarkSceneDirty(EditorSceneManager.GetActiveScene());
                }
                else
                {
                    if (EditorUtility.DisplayDialog("Actor initialization", "Are you sure you want to re-initialize this actor?", "Ok", "Cancel"))
                    {
                        CoroutineJob job = new CoroutineJob();
                        routine = EditorCoroutine.StartCoroutine(job.Start(bone.GeneratePhysicRepresentationForBones()));
                        EditorSceneManager.MarkSceneDirty(EditorSceneManager.GetActiveScene());
                    }
                }
            }

            EditorGUI.BeginChangeCheck();
            ObiSolver solver = EditorGUILayout.ObjectField("Solver", bone.Solver, typeof(ObiSolver), true) as ObiSolver;

            if (EditorGUI.EndChangeCheck())
            {
                Undo.RecordObject(bone, "Set solver");
                bone.Solver = solver;
            }

            bool newSelfCollisions = EditorGUILayout.Toggle(new GUIContent("Self collisions", "Enabling this allows particles generated by this actor to interact with each other."), bone.SelfCollisions);

            if (bone.SelfCollisions != newSelfCollisions)
            {
                Undo.RecordObject(bone, "Set self collisions");
                bone.SelfCollisions = newSelfCollisions;
            }

            Editor.DrawPropertiesExcluding(serializedObject, "m_Script", "chainLinks");

            // Progress bar:
            EditorCoroutine.ShowCoroutineProgressBar("Generating physical representation...", routine);

            // Apply changes to the serializedProperty
            if (GUI.changed)
            {
                serializedObject.ApplyModifiedProperties();
            }
        }
Beispiel #8
0
        public override void OnInspectorGUI()
        {
            serializedObject.UpdateIfDirtyOrScript();

            GUI.enabled = cloth.Initialized;
            EditorGUI.BeginChangeCheck();
            editMode = GUILayout.Toggle(editMode, new GUIContent("Edit particles", EditorGUIUtility.Load("EditParticles.psd") as Texture2D), "LargeButton");
            if (EditorGUI.EndChangeCheck())
            {
                SceneView.RepaintAll();
            }
            GUI.enabled = true;

            EditorGUILayout.LabelField("Status: " + (cloth.Initialized ? "Initialized":"Not initialized"));

            GUI.enabled = (cloth.sharedTopology != null);
            if (GUILayout.Button("Initialize"))
            {
                if (!cloth.Initialized)
                {
                    CoroutineJob job = new CoroutineJob();
                    routine = EditorCoroutine.StartCoroutine(job.Start(cloth.GeneratePhysicRepresentationForMesh()));
                }
                else
                {
                    if (EditorUtility.DisplayDialog("Actor initialization", "Are you sure you want to re-initialize this actor?", "Ok", "Cancel"))
                    {
                        CoroutineJob job = new CoroutineJob();
                        routine = EditorCoroutine.StartCoroutine(job.Start(cloth.GeneratePhysicRepresentationForMesh()));
                    }
                }
            }
            GUI.enabled = true;

            if (cloth.sharedTopology == null)
            {
                EditorGUILayout.HelpBox("No ObiMeshTopology asset present.", MessageType.Info);
            }

            GUI.enabled = cloth.Initialized;
            if (GUILayout.Button("Set Rest State"))
            {
                cloth.PullDataFromSolver(new ObiSolverData(ObiSolverData.ParticleData.POSITIONS | ObiSolverData.ParticleData.VELOCITIES));
            }

            GUILayout.BeginHorizontal();
            if (GUILayout.Button("Optimize"))
            {
                Undo.RecordObject(cloth, "Optimize");
                cloth.Optimize();
                EditorUtility.SetDirty(cloth);
            }
            if (GUILayout.Button("Unoptimize"))
            {
                Undo.RecordObject(cloth, "Unoptimize");
                cloth.Unoptimize();
                EditorUtility.SetDirty(cloth);
            }
            GUILayout.EndHorizontal();
            GUI.enabled = true;

            cloth.Solver = EditorGUILayout.ObjectField("Solver", cloth.Solver, typeof(ObiSolver), true) as ObiSolver;

            bool newSelfCollisions = EditorGUILayout.Toggle(new GUIContent("Self collisions", "Enabling this allows particles generated by this actor to interact with each other."), cloth.SelfCollisions);

            if (cloth.SelfCollisions != newSelfCollisions)
            {
                Undo.RecordObject(cloth, "Set self collisions");
                cloth.SelfCollisions = newSelfCollisions;
            }

            Editor.DrawPropertiesExcluding(serializedObject, "m_Script");

            // Progress bar:
            EditorCoroutine.ShowCoroutineProgressBar("Generating physical representation...", routine);

            // Apply changes to the serializedProperty
            if (GUI.changed)
            {
                serializedObject.ApplyModifiedProperties();
            }
        }
Beispiel #9
0
        void UpdateEditMode()
        {
            EditorGUILayout.BeginVertical(EditorStyles.inspectorDefaultMargins);

            EditorGUILayout.PropertyField(barycentricWeight);
            EditorGUILayout.PropertyField(normalAlignmentWeight);
            EditorGUILayout.PropertyField(elevationWeight);

            EditorGUI.BeginChangeCheck();
            paintMode    = GUILayout.Toggle(paintMode, new GUIContent("Paint skin", Resources.Load <Texture2D>("PaintButton")), "LargeButton");
            Tools.hidden = paintMode || subject == SubjectBeingEdited.Master;
            if (EditorGUI.EndChangeCheck())
            {
                SceneView.RepaintAll();
            }

            // Buttons:
            GUILayout.BeginHorizontal();

            if (GUILayout.Button("Bind") && masterObject != null && slaveObject != null)
            {
                EditorUtility.SetDirty(target);
                CoroutineJob job = new CoroutineJob();
                routine = job.Start(skinMap.Bind());
                EditorCoroutine.ShowCoroutineProgressBar("Generating skinmap...", ref routine);
                EditorGUIUtility.ExitGUI();
            }

            if (GUILayout.Button("Done"))
            {
                EditorApplication.delayCall += ExitSkinEditMode;
            }

            GUILayout.EndHorizontal();

            EditorGUILayout.EndVertical();

            // skin channel selector:
            if (paintMode)
            {
                EditorGUILayout.Space();
                GUILayout.Box(GUIContent.none, ObiEditorUtils.GetSeparatorLineStyle());

                EditorGUILayout.BeginVertical(EditorStyles.inspectorDefaultMargins);

                // Brush parameters:
                paintBrush.radius      = EditorGUILayout.Slider("Brush size", paintBrush.radius, 0.0001f, 0.5f);
                paintBrush.innerRadius = 1;
                paintBrush.opacity     = 1;

                EditorGUI.BeginChangeCheck();
                if (paintBrush.brushMode.needsInputValue)
                {
                    currentProperty.PropertyField();
                }
                if (EditorGUI.EndChangeCheck())
                {
                    SceneView.RepaintAll();
                }

                GUILayout.BeginHorizontal();

                if (GUILayout.Button(new GUIContent("Fill"), EditorStyles.miniButtonLeft))
                {
                    if (subject == SubjectBeingEdited.Master)
                    {
                        skinMap.FillChannel(skinMap.m_MasterChannels, currentProperty.GetDefault());
                    }
                    else
                    {
                        skinMap.FillChannel(skinMap.m_SlaveChannels, currentProperty.GetDefault());
                    }
                    SceneView.RepaintAll();
                }

                if (GUILayout.Button(new GUIContent("Clear"), EditorStyles.miniButtonMid))
                {
                    if (subject == SubjectBeingEdited.Master)
                    {
                        skinMap.ClearChannel(skinMap.m_MasterChannels, currentProperty.GetDefault());
                    }
                    else
                    {
                        skinMap.ClearChannel(skinMap.m_SlaveChannels, currentProperty.GetDefault());
                    }
                    SceneView.RepaintAll();
                }

                if (GUILayout.Button(new GUIContent("Copy"), EditorStyles.miniButtonMid))
                {
                    targetSkinChannel = currentProperty.GetDefault();
                }

                if (GUILayout.Button(new GUIContent("Paste"), EditorStyles.miniButtonRight))
                {
                    if (subject == SubjectBeingEdited.Master)
                    {
                        skinMap.CopyChannel(skinMap.m_MasterChannels, targetSkinChannel, currentProperty.GetDefault());
                    }
                    else
                    {
                        skinMap.CopyChannel(skinMap.m_SlaveChannels, targetSkinChannel, currentProperty.GetDefault());
                    }
                    SceneView.RepaintAll();
                }

                GUILayout.EndHorizontal();

                EditorGUILayout.EndVertical();
            }

            EditorGUILayout.Space();
            GUILayout.Box(GUIContent.none, ObiEditorUtils.GetSeparatorLineStyle());

            EditorGUILayout.BeginVertical(EditorStyles.inspectorDefaultMargins);

            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.LabelField("Slave transform", EditorStyles.boldLabel);
            if (GUILayout.Button("Reset", EditorStyles.miniButton))
            {
                skinMap.m_SlaveTransform.Reset();
            }
            EditorGUILayout.EndHorizontal();
            EditorGUILayout.PropertyField(serializedObject.FindProperty("m_SlaveTransform"));

            EditorGUILayout.EndVertical();
        }
Beispiel #10
0
        public override void OnInspectorGUI()
        {
            serializedObject.UpdateIfDirtyOrScript();

            GUI.enabled = cloth.Initialized;
            EditorGUI.BeginChangeCheck();
            editMode = GUILayout.Toggle(editMode, new GUIContent("Edit particles", EditorGUIUtility.Load("Obi/EditParticles.psd") as Texture2D), "LargeButton");
            if (EditorGUI.EndChangeCheck())
            {
                // show wireframe
                EditorUtility.SetSelectedWireframeHidden(cloth.GetComponent <Renderer>(), false);
                SceneView.RepaintAll();
            }
            GUI.enabled = true;

            EditorGUILayout.LabelField("Status: " + (cloth.Initialized ? "Initialized":"Not initialized"));

            GUI.enabled = (cloth.SharedTopology != null);
            if (GUILayout.Button("Initialize"))
            {
                if (!cloth.Initialized)
                {
                    CoroutineJob job = new CoroutineJob();
                    routine = EditorCoroutine.StartCoroutine(job.Start(cloth.GeneratePhysicRepresentationForMesh()));
                    EditorSceneManager.MarkSceneDirty(EditorSceneManager.GetActiveScene());
                }
                else
                {
                    if (EditorUtility.DisplayDialog("Actor initialization", "Are you sure you want to re-initialize this actor?", "Ok", "Cancel"))
                    {
                        CoroutineJob job = new CoroutineJob();
                        routine = EditorCoroutine.StartCoroutine(job.Start(cloth.GeneratePhysicRepresentationForMesh()));
                        EditorSceneManager.MarkSceneDirty(EditorSceneManager.GetActiveScene());
                    }
                }
            }
            GUI.enabled = true;

            if (cloth.SharedTopology == null)
            {
                EditorGUILayout.HelpBox("No ObiMeshTopology asset present.", MessageType.Info);
            }

            GUI.enabled = cloth.Initialized;
            if (GUILayout.Button("Set Rest State"))
            {
                cloth.PullDataFromSolver(ParticleData.POSITIONS | ParticleData.VELOCITIES);
            }
            GUILayout.BeginHorizontal();
            if (GUILayout.Button("Optimize"))
            {
                Undo.RecordObject(cloth, "Optimize");
                cloth.Optimize();
            }
            if (GUILayout.Button("Unoptimize"))
            {
                Undo.RecordObject(cloth, "Unoptimize");
                cloth.Unoptimize();
            }
            GUILayout.EndHorizontal();

            GUI.enabled = true;

            EditorGUI.BeginChangeCheck();
            ObiSolver solver = EditorGUILayout.ObjectField("Solver", cloth.Solver, typeof(ObiSolver), true) as ObiSolver;

            if (EditorGUI.EndChangeCheck())
            {
                Undo.RecordObject(cloth, "Set solver");
                cloth.Solver = solver;
            }

            EditorGUI.BeginChangeCheck();
            ObiMeshTopology topology = EditorGUILayout.ObjectField("Shared Topology", cloth.SharedTopology, typeof(ObiMeshTopology), true) as ObiMeshTopology;

            if (EditorGUI.EndChangeCheck())
            {
                Undo.RecordObject(cloth, "Set topology");
                cloth.SharedTopology = topology;
            }

            bool newSelfCollisions = EditorGUILayout.Toggle(new GUIContent("Self collisions", "Enabling this allows particles generated by this actor to interact with each other."), cloth.SelfCollisions);

            if (cloth.SelfCollisions != newSelfCollisions)
            {
                Undo.RecordObject(cloth, "Set self collisions");
                cloth.SelfCollisions = newSelfCollisions;
            }

            bool newUpdateTangents = EditorGUILayout.Toggle(new GUIContent("Update tangents", "If enabled, tangent space will be updated after each simulation step. Enable this if your cloth uses normal maps."), cloth.UpdateTangents);

            if (cloth.UpdateTangents != newUpdateTangents)
            {
                Undo.RecordObject(cloth, "Set update tangents");
                cloth.UpdateTangents = newUpdateTangents;
            }

            Oni.NormalsUpdate newNormalsUpdate = (Oni.NormalsUpdate)EditorGUILayout.EnumPopup(new GUIContent("Update normals", "If set to recalculate, smooth normals will be recalculated each step. If set to skin, the original mesh normals will be rotated based on surface orientation."), cloth.NormalsUpdate);
            if (cloth.NormalsUpdate != newNormalsUpdate)
            {
                Undo.RecordObject(cloth, "Set normals update");
                cloth.NormalsUpdate = newNormalsUpdate;
            }

            Editor.DrawPropertiesExcluding(serializedObject, "m_Script");

            // Progress bar:
            EditorCoroutine.ShowCoroutineProgressBar("Generating physical representation...", routine);

            // Apply changes to the serializedProperty
            if (GUI.changed)
            {
                serializedObject.ApplyModifiedProperties();
            }
        }
        /**
         * Draws a window with cloth info:
         */
        void DrawUIWindow(int windowID)
        {
            previewVirtualParticles = GUILayout.Toggle(previewVirtualParticles,"Preview virtual particles");
            previewSpatialGrid = GUILayout.Toggle(previewSpatialGrid,"Preview grid");
            if (cloth.IsSkinned) previewSkin = GUILayout.Toggle(previewSkin,"Preview skin");

            GUILayout.BeginHorizontal();

            EditorGUI.showMixedValue = mixedMass;
            newMass = EditorGUILayout.FloatField(newMass);
            EditorGUI.showMixedValue = false;

            if (GUILayout.Button("Set Mass")){
                selectionMass = newMass;
                foreach(int particleIndex in selectedParticles){
                    ObiClothParticle particle = cloth.particles[particleIndex];
                    particle.mass = selectionMass;
                }
            }

            if (GUILayout.Button(new GUIContent(EditorGUIUtility.Load("PinIcon.psd") as Texture2D,"Fix/unfix particles."),GUILayout.MaxHeight(18),GUILayout.MaxWidth(25))){
                foreach(int particleIndex in selectedParticles){
                    ObiClothParticle particle = cloth.particles[particleIndex];
                    if (particle.w == 0){
                        particle.mass = 1;
                    }else{
                        newMass = particle.mass = float.PositiveInfinity;
                        particle.velocity = Vector3.zero;
                    }
                }
            }

            GUILayout.EndHorizontal();

            if (GUILayout.Button("Invert selection")){
            List<ObiClothParticle> unselectedParticles = cloth.particles.FindAll(x => !selectedParticles.Contains(x.index));
            selectedParticles.Clear();
            foreach(ObiClothParticle p in unselectedParticles){
                SelectParticle(p.index);
            }
            }

            GUILayout.BeginHorizontal();

            GUI.enabled = !EditorApplication.isPlaying;

            if (GUILayout.Button(EditorGUIUtility.Load("RewindButton.psd") as Texture2D,GUILayout.MaxHeight(24))){
                cloth.ResetGeometry();
                accumulatedTime = 0;
            }

            if (GUILayout.Button(EditorGUIUtility.Load("StopButton.psd") as Texture2D,GUILayout.MaxHeight(24))){
                isPlaying = false;
            }

            if (GUILayout.Button(EditorGUIUtility.Load("PlayButton.psd") as Texture2D,GUILayout.MaxHeight(24))){
                lastFrameTime = Time.realtimeSinceStartup;
                isPlaying = true;
            }

            if (GUILayout.Button(EditorGUIUtility.Load("StepButton.psd") as Texture2D,GUILayout.MaxHeight(24))){
                isPlaying = false;
                cloth.SimulateStep(Time.fixedDeltaTime);
                cloth.CommitResultsToMesh();
            }

            GUI.enabled = true;

            GUILayout.EndHorizontal();

            GUILayout.BeginHorizontal();

            if (GUILayout.Button("Reset Cloth")){
            accumulatedTime = 0;
            CoroutineJob job = new CoroutineJob();
            job.asyncThreshold = 1000;
            routine = EditorCoroutine.StartCoroutine(job.Start(cloth.ResetAll()));
            }

            if (GUILayout.Button("Optimize")){
            if (EditorUtility.DisplayDialog("Cloth optimization","About to remove fixed particles that do not contribute to the simulation. The only way to undo this is reset or recreate the cloth. Do you want to continue?","Ok","Cancel"))
                cloth.Optimize();
            }

            GUILayout.EndHorizontal();
        }
Beispiel #12
0
        public override void OnInspectorGUI()
        {
            serializedObject.Update();

            GUI.enabled = rope.Initialized;
            EditorGUI.BeginChangeCheck();
            editMode = GUILayout.Toggle(editMode, new GUIContent("Edit particles", Resources.Load <Texture2D>("EditParticles")), "LargeButton");
            if (EditorGUI.EndChangeCheck())
            {
                SceneView.RepaintAll();
            }
            GUI.enabled = true;

            EditorGUILayout.LabelField("Status: " + (rope.Initialized ? "Initialized":"Not initialized"));

            GUI.enabled = (rope.ropePath != null && rope.Section != null);
            if (GUILayout.Button("Initialize"))
            {
                if (!rope.Initialized)
                {
                    CoroutineJob job = new CoroutineJob();
                    routine = EditorCoroutine.StartCoroutine(job.Start(rope.GeneratePhysicRepresentationForMesh()));
                    EditorSceneManager.MarkSceneDirty(EditorSceneManager.GetActiveScene());
                }
                else
                {
                    if (EditorUtility.DisplayDialog("Actor initialization", "Are you sure you want to re-initialize this actor?", "Ok", "Cancel"))
                    {
                        CoroutineJob job = new CoroutineJob();
                        routine = EditorCoroutine.StartCoroutine(job.Start(rope.GeneratePhysicRepresentationForMesh()));
                        EditorSceneManager.MarkSceneDirty(EditorSceneManager.GetActiveScene());
                    }
                }
            }
            GUI.enabled = true;

            GUI.enabled = rope.Initialized;
            if (GUILayout.Button("Set Rest State"))
            {
                Undo.RecordObject(rope, "Set rest state");
                rope.PullDataFromSolver(ParticleData.POSITIONS | ParticleData.VELOCITIES);
            }
            GUI.enabled = true;

            if (rope.ropePath == null)
            {
                EditorGUILayout.HelpBox("Rope path spline is missing.", MessageType.Info);
            }
            if (rope.Section == null)
            {
                EditorGUILayout.HelpBox("Rope section is missing.", MessageType.Info);
            }

            EditorGUI.BeginChangeCheck();
            ObiSolver solver = EditorGUILayout.ObjectField("Solver", rope.Solver, typeof(ObiSolver), true) as ObiSolver;

            if (EditorGUI.EndChangeCheck())
            {
                Undo.RecordObject(rope, "Set solver");
                rope.Solver = solver;
            }

            EditorGUI.BeginChangeCheck();
            ObiCollisionMaterial material = EditorGUILayout.ObjectField("Collision Material", rope.CollisionMaterial, typeof(ObiCollisionMaterial), false) as ObiCollisionMaterial;

            if (EditorGUI.EndChangeCheck())
            {
                Undo.RecordObject(rope, "Set collision material");
                rope.CollisionMaterial = material;
            }

            bool newSelfCollisions = EditorGUILayout.Toggle(new GUIContent("Self collisions", "Enabling this allows particles generated by this actor to interact with each other."), rope.SelfCollisions);

            if (rope.SelfCollisions != newSelfCollisions)
            {
                Undo.RecordObject(rope, "Set self collisions");
                rope.SelfCollisions = newSelfCollisions;
            }

            Editor.DrawPropertiesExcluding(serializedObject, "m_Script", "chainLinks");

            bool newThicknessFromParticles = EditorGUILayout.Toggle(new GUIContent("Thickness from particles", "Enabling this will allow particle radius to influence rope thickness. Use it for variable-thickness ropes."), rope.ThicknessFromParticles);

            if (rope.ThicknessFromParticles != newThicknessFromParticles)
            {
                Undo.RecordObject(rope, "Set thickness from particles");
                rope.ThicknessFromParticles = newThicknessFromParticles;
            }

            float newTwist = EditorGUILayout.FloatField(new GUIContent("Section twist", "Amount of twist applied to each section, in degrees."), rope.SectionTwist);

            if (rope.SectionTwist != newTwist)
            {
                Undo.RecordObject(rope, "Set section twist");
                rope.SectionTwist = newTwist;
            }

            EditorGUILayout.Space();
            EditorGUILayout.LabelField("Rendering", EditorStyles.boldLabel);

            ObiRope.RenderingMode newRenderMode = (ObiRope.RenderingMode)EditorGUILayout.EnumPopup(rope.RenderMode);
            if (rope.RenderMode != newRenderMode)
            {
                Undo.RecordObject(rope, "Set rope render mode");
                rope.RenderMode = newRenderMode;
            }

            float newUVAnchor = EditorGUILayout.Slider(new GUIContent("UV anchor", "Normalized point along the rope where the V texture coordinate starts. Useful when changing rope length."), rope.UVAnchor, 0, 1);

            if (rope.UVAnchor != newUVAnchor)
            {
                Undo.RecordObject(rope, "Set rope uv anchor");
                rope.UVAnchor = newUVAnchor;
            }

            // Render-mode specific stuff:
            if (rope.RenderMode != ObiRope.RenderingMode.Chain)
            {
                ObiRopeSection newSection = EditorGUILayout.ObjectField(new GUIContent("Section", "Section asset to be extruded along the rope path.")
                                                                        , rope.Section, typeof(ObiRopeSection), false) as ObiRopeSection;
                if (rope.Section != newSection)
                {
                    Undo.RecordObject(rope, "Set rope section");
                    rope.Section = newSection;
                }

                float newThickness = EditorGUILayout.FloatField(new GUIContent("Section thickness scale", "Scales mesh thickness."), rope.SectionThicknessScale);
                if (rope.SectionThicknessScale != newThickness)
                {
                    Undo.RecordObject(rope, "Set rope section thickness");
                    rope.SectionThicknessScale = newThickness;
                }

                uint newSmoothness = (uint)EditorGUILayout.IntSlider(new GUIContent("Smoothness", "Level of smoothing applied to the rope path."), Convert.ToInt32(rope.Smoothing), 0, 3);
                if (rope.Smoothing != newSmoothness)
                {
                    Undo.RecordObject(rope, "Set smoothness");
                    rope.Smoothing = newSmoothness;
                }

                Vector2 newUVScale = EditorGUILayout.Vector2Field(new GUIContent("UV scale", "Scaling of the uv coordinates generated for the rope. The u coordinate wraps around the whole rope section, and the v spans the full length of the rope."), rope.UVScale);
                if (rope.UVScale != newUVScale)
                {
                    Undo.RecordObject(rope, "Set rope uv scale");
                    rope.UVScale = newUVScale;
                }

                bool newNormalizeV = EditorGUILayout.Toggle(new GUIContent("Normalize V", "Scaling of the uv coordinates generated for the rope. The u coordinate wraps around the whole rope section, and the v spans the full length of the rope."), rope.NormalizeV);
                if (rope.NormalizeV != newNormalizeV)
                {
                    Undo.RecordObject(rope, "Set normalize v");
                    rope.NormalizeV = newNormalizeV;
                }
            }
            else
            {
                Vector3 newLinkScale = EditorGUILayout.Vector3Field(new GUIContent("Link scale", "Scale applied to each chain link."), rope.LinkScale);
                if (rope.LinkScale != newLinkScale)
                {
                    Undo.RecordObject(rope, "Set chain link scale");
                    rope.LinkScale = newLinkScale;
                }

                bool newRandomizeLinks = EditorGUILayout.Toggle(new GUIContent("Randomize links", "Toggling this on this causes each chain link to be selected at random from the set of provided links."), rope.RandomizeLinks);
                if (rope.RandomizeLinks != newRandomizeLinks)
                {
                    Undo.RecordObject(rope, "Set randomize links");
                    rope.RandomizeLinks = newRandomizeLinks;
                }

                EditorGUI.BeginChangeCheck();
                EditorGUILayout.PropertyField(chainLinks, true);
                if (EditorGUI.EndChangeCheck())
                {
                    // update the chain representation in response to a change in available link templates:
                    serializedObject.ApplyModifiedProperties();
                    rope.GenerateProceduralChainLinks();
                }
            }

            // Progress bar:
            EditorCoroutine.ShowCoroutineProgressBar("Generating physical representation...", routine);

            // Apply changes to the serializedProperty
            if (GUI.changed)
            {
                serializedObject.ApplyModifiedProperties();
            }
        }
        public override void OnInspectorGUI()
        {
            serializedObject.Update();

            GUI.enabled = rope.Initialized;
            EditorGUI.BeginChangeCheck();
            editMode = GUILayout.Toggle(editMode, new GUIContent("Edit particles", Resources.Load <Texture2D>("EditParticles")), "LargeButton");
            if (EditorGUI.EndChangeCheck())
            {
                SceneView.RepaintAll();
            }
            GUI.enabled = true;

            EditorGUILayout.LabelField("Status: " + (rope.Initialized ? "Initialized":"Not initialized"));

            GUI.enabled = (rope.ropePath != null);
            if (GUILayout.Button("Initialize"))
            {
                if (!rope.Initialized)
                {
                    EditorSceneManager.MarkSceneDirty(EditorSceneManager.GetActiveScene());
                    CoroutineJob job = new CoroutineJob();
                    routine = job.Start(rope.GeneratePhysicRepresentationForMesh());
                    EditorCoroutine.ShowCoroutineProgressBar("Generating physical representation...", ref routine);
                    EditorGUIUtility.ExitGUI();
                }
                else
                {
                    if (EditorUtility.DisplayDialog("Actor initialization", "Are you sure you want to re-initialize this actor?", "Ok", "Cancel"))
                    {
                        EditorSceneManager.MarkSceneDirty(EditorSceneManager.GetActiveScene());
                        CoroutineJob job = new CoroutineJob();
                        routine = job.Start(rope.GeneratePhysicRepresentationForMesh());
                        EditorCoroutine.ShowCoroutineProgressBar("Generating physical representation...", ref routine);
                        EditorGUIUtility.ExitGUI();
                    }
                }
            }
            GUI.enabled = true;

            GUI.enabled = rope.Initialized;
            if (GUILayout.Button("Set Rest State"))
            {
                Undo.RecordObject(rope, "Set rest state");
                rope.PullDataFromSolver(ParticleData.POSITIONS | ParticleData.VELOCITIES);
            }
            GUI.enabled = true;

            if (rope.ropePath == null)
            {
                EditorGUILayout.HelpBox("Rope path spline is missing.", MessageType.Info);
            }

            Editor.DrawPropertiesExcluding(serializedObject, "m_Script", "chainLinks");

            // Apply changes to the serializedProperty
            if (GUI.changed)
            {
                serializedObject.ApplyModifiedProperties();
            }
        }
Beispiel #14
0
        public override void OnInspectorGUI()
        {
            serializedObject.UpdateIfRequiredOrScript();

            GUI.enabled = cloth.Initialized;
            EditorGUI.BeginChangeCheck();
            editMode = GUILayout.Toggle(editMode, new GUIContent("Edit particles", Resources.Load <Texture2D>("EditParticles")), "LargeButton");
            if (EditorGUI.EndChangeCheck())
            {
                SceneView.RepaintAll();
            }
            GUI.enabled = true;

            EditorGUILayout.LabelField("Status: " + (cloth.Initialized ? "Initialized":"Not initialized"));

            GUI.enabled = (cloth.SharedTopology != null);
            if (GUILayout.Button("Initialize"))
            {
                if (!cloth.Initialized)
                {
                    CoroutineJob job = new CoroutineJob();
                    routine = EditorCoroutine.StartCoroutine(job.Start(cloth.GeneratePhysicRepresentationForMesh()));
                    EditorSceneManager.MarkSceneDirty(EditorSceneManager.GetActiveScene());
                }
                else
                {
                    if (EditorUtility.DisplayDialog("Actor initialization", "Are you sure you want to re-initialize this actor?", "Ok", "Cancel"))
                    {
                        CoroutineJob job = new CoroutineJob();
                        routine = EditorCoroutine.StartCoroutine(job.Start(cloth.GeneratePhysicRepresentationForMesh()));
                        EditorSceneManager.MarkSceneDirty(EditorSceneManager.GetActiveScene());
                    }
                }
            }
            GUI.enabled = true;

            if (cloth.SharedTopology == null)
            {
                EditorGUILayout.HelpBox("No ObiMeshTopology asset present.", MessageType.Info);
            }

            GUI.enabled = cloth.Initialized;
            if (GUILayout.Button("Set Rest State"))
            {
                Undo.RecordObject(cloth, "Set rest state");
                cloth.PullDataFromSolver(ParticleData.POSITIONS | ParticleData.VELOCITIES);
            }
            GUILayout.BeginHorizontal();
            if (GUILayout.Button("Optimize"))
            {
                Undo.RecordObject(cloth, "Optimize");
                cloth.Optimize();
            }
            if (GUILayout.Button("Unoptimize"))
            {
                Undo.RecordObject(cloth, "Unoptimize");
                cloth.Unoptimize();
            }
            GUILayout.EndHorizontal();

            GUI.enabled = true;

            Editor.DrawPropertiesExcluding(serializedObject, "m_Script");

            // Progress bar:
            EditorCoroutine.ShowCoroutineProgressBar("Generating physical representation...", routine);

            // Apply changes to the serializedProperty
            if (GUI.changed)
            {
                serializedObject.ApplyModifiedProperties();
            }
        }
 public static EditorCoroutine StartCoroutine( IEnumerator _routine )
 {
     EditorCoroutine coroutine = new EditorCoroutine(_routine);
     coroutine.Start();
     return coroutine;
 }