Example #1
0
        public override void OnInspectorGUI()
        {
            serializedObject.Update();

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

            EditorGUILayout.HelpBox("Active particles:" + emitter.ActiveParticles, MessageType.Info);

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

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

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

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

            EditorGUI.BeginChangeCheck();
            ObiEmitterMaterial emitterMaterial = EditorGUILayout.ObjectField(new GUIContent("Emitter Material", "Emitter material used. This controls the behavior of the emitted particles."),
                                                                             emitter.EmitterMaterial, typeof(ObiEmitterMaterial), false) as ObiEmitterMaterial;

            if (EditorGUI.EndChangeCheck())
            {
                Undo.RecordObject(emitter, "Set emitter material");
                emitter.EmitterMaterial = emitterMaterial;
            }

            EditorGUI.BeginChangeCheck();
            int numParticles = EditorGUILayout.IntField(new GUIContent("Num particles", "Amount of pooled particles used by this emitter."), emitter.NumParticles);

            if (EditorGUI.EndChangeCheck())
            {
                Undo.RecordObject(emitter, "Set num particles");
                emitter.NumParticles = numParticles;
            }

            Editor.DrawPropertiesExcluding(serializedObject, "m_Script");

            // Apply changes to the serializedProperty
            if (GUI.changed)
            {
                emitter.UpdateParticlePhases();                 //TODO: only do this when changing material.
                serializedObject.ApplyModifiedProperties();
            }
        }
Example #2
0
        public void Initialize()
        {
            // Tear everything down first:
            Teardown();

            try{
                // Create a default material:
                defaultMaterial           = ScriptableObject.CreateInstance <ObiCollisionMaterial>();
                defaultMaterial.hideFlags = HideFlags.HideAndDontSave;

                defaultFluidMaterial           = ScriptableObject.CreateInstance <ObiEmitterMaterialFluid>();
                defaultFluidMaterial.hideFlags = HideFlags.HideAndDontSave;

                // Create the Oni solver:
                oniSolver = Oni.CreateSolver(maxParticles, MAX_NEIGHBOURS);

                actors               = new List <ObiActor>();
                allocatedParticles   = new HashSet <int>();
                activeParticles      = new HashSet <int>();
                materialIndices      = new int[maxParticles];
                fluidMaterialIndices = new int[maxParticles];
                renderablePositions  = new Vector4[maxParticles];

                // Initialize materials:
                UpdateSolverMaterials();
                UpdateEmitterMaterials();

                // Initialize parameters:
                UpdateParameters();
            }catch (Exception exception) {
                Debug.LogException(exception);
            }finally{
                initialized = true;
            };
        }
Example #3
0
 public void FromObiCollisionMaterial(ObiCollisionMaterial material)
 {
     if (material != null)
     {
         dynamicFriction   = material.dynamicFriction;
         staticFriction    = material.staticFriction;
         stickiness        = material.stickiness;
         stickDistance     = material.stickDistance;
         rollingFriction   = material.rollingFriction;
         frictionCombine   = material.frictionCombine;
         stickinessCombine = material.stickinessCombine;
         rollingContacts   = material.rollingContacts ? 1 : 0;
     }
 }
        public override void OnInspectorGUI()
        {
            serializedObject.UpdateIfRequiredOrScript();

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

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

            Editor.DrawPropertiesExcluding(serializedObject, "m_Script");

            // Apply changes to the serializedProperty
            if (GUI.changed)
            {
                serializedObject.ApplyModifiedProperties();
            }
        }
Example #5
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();
            }
        }
Example #6
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;

            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();
            ObiCollisionMaterial material = EditorGUILayout.ObjectField("Collision Material", cloth.CollisionMaterial, typeof(ObiCollisionMaterial), false) as ObiCollisionMaterial;

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

            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();
            }
        }
Example #7
0
        public void Initialize()
        {
            // Tear everything down first:
            Teardown();

            try{
                // Create a default material (TODO: maybe expose this to the user?)
                defaultMaterial           = ScriptableObject.CreateInstance <ObiCollisionMaterial>();
                defaultMaterial.hideFlags = HideFlags.HideAndDontSave;

                defaultFluidMaterial           = ScriptableObject.CreateInstance <ObiEmitterMaterial>();
                defaultFluidMaterial.hideFlags = HideFlags.HideAndDontSave;

                // Create the Oni solver:
                oniSolver = Oni.CreateSolver(maxParticles, 92, interactionRadius);

                actors               = new List <ObiActor>();
                allocatedParticles   = new HashSet <int>();
                activeParticles      = new HashSet <int>();
                materialIndices      = new int[maxParticles];
                fluidMaterialIndices = new int[maxParticles];
                renderablePositions  = new Vector3[maxParticles];
                positions            = new Vector3[maxParticles];
                previousPositions    = new Vector3[maxParticles];
                predictedPositions   = new Vector3[maxParticles];
                velocities           = new Vector3[maxParticles];
                inverseMasses        = new float[maxParticles];
                solidRadii           = new float[maxParticles];
                phases               = new int[maxParticles];

                // Create constraint groups:
                distanceConstraints    = new ObiDistanceConstraintGroup(this);
                bendingConstraints     = new ObiBendingConstraintGroup(this);
                skinConstraints        = new ObiSkinConstraintGroup(this);
                aerodynamicConstraints = new ObiAerodynamicConstraintGroup(this);
                volumeConstraints      = new ObiVolumeConstraintGroup(this);
                tetherConstraints      = new ObiTetherConstraintGroup(this);
                pinConstraints         = new ObiPinConstraintGroup(this);

                // Register constraint groups:
                RegisterConstraintGroup(typeof(ObiDistanceConstraints), distanceConstraints);
                RegisterConstraintGroup(typeof(ObiBendingConstraints), bendingConstraints);
                RegisterConstraintGroup(typeof(ObiSkinConstraints), skinConstraints);
                RegisterConstraintGroup(typeof(ObiAerodynamicConstraints), aerodynamicConstraints);
                RegisterConstraintGroup(typeof(ObiVolumeConstraints), volumeConstraints);
                RegisterConstraintGroup(typeof(ObiTetherConstraints), tetherConstraints);
                RegisterConstraintGroup(typeof(ObiPinConstraints), pinConstraints);

                // Pin all memory so that the GC won't deallocate it before we are done.
                materialIndicesHandle      = Oni.PinMemory(materialIndices);
                fluidMaterialIndicesHandle = Oni.PinMemory(fluidMaterialIndices);
                renderablePositionsHandle  = Oni.PinMemory(renderablePositions);
                positionsHandle            = Oni.PinMemory(positions);
                predictedHandle            = Oni.PinMemory(predictedPositions);
                previousHandle             = Oni.PinMemory(previousPositions);
                velocitiesHandle           = Oni.PinMemory(velocities);
                inverseMassesHandle        = Oni.PinMemory(inverseMasses);
                solidRadiiHandle           = Oni.PinMemory(solidRadii);
                phasesHandle = Oni.PinMemory(phases);

                // Send all pointers to pinned memory to the solver:
                Oni.SetMaterialIndices(oniSolver, materialIndicesHandle.AddrOfPinnedObject());
                Oni.SetFluidMaterialIndices(oniSolver, fluidMaterialIndicesHandle.AddrOfPinnedObject());
                Oni.SetRenderableParticlePositions(oniSolver, renderablePositionsHandle.AddrOfPinnedObject());
                Oni.SetParticlePositions(oniSolver, positionsHandle.AddrOfPinnedObject());
                Oni.SetPredictedParticlePositions(oniSolver, predictedHandle.AddrOfPinnedObject());
                Oni.SetPreviousParticlePositions(oniSolver, previousHandle.AddrOfPinnedObject());
                Oni.SetParticleVelocities(oniSolver, velocitiesHandle.AddrOfPinnedObject());
                Oni.SetParticleInverseMasses(oniSolver, inverseMassesHandle.AddrOfPinnedObject());
                Oni.SetParticleSolidRadii(oniSolver, solidRadiiHandle.AddrOfPinnedObject());
                Oni.SetParticlePhases(oniSolver, phasesHandle.AddrOfPinnedObject());

                // Initialize materials:
                UpdateSolverMaterials();
                UpdateFluidMaterials();

                // Initialize parameters:
                UpdateParameters();

                boundsHandle = Oni.PinMemory(bounds);
            }catch (Exception exception) {
                Debug.LogException(exception);
            }finally{
                initialized = true;
            };
        }