void OnBrushBeginApply(BrushTarget brushTarget, BrushSettings settings)
 {
     PolySceneUtility.PushGIWorkflowMode();
     firstGameObject = brushTarget.gameObject;
     mode.RegisterUndo(brushTarget);
     m_UndoQueue.Add(brushTarget.gameObject);
     mode.OnBrushBeginApply(brushTarget, brushSettings);
 }
 internal void OnFinishApplyingBrush()
 {
     PolySceneUtility.PopGIWorkflowMode();
     firstGameObject = null;
     m_ApplyingBrush = false;
     mode.OnBrushFinishApply(brushTarget, brushSettings);
     FinalizeAndResetHovering();
     m_IgnoreDrag.Clear();
 }
Exemple #3
0
        void PlaceGameObject(PolyRaycastHit hit, PrefabAndSettings prefabAndSettings, BrushTarget target, BrushSettings settings)
        {
            if (prefabAndSettings == null)
            {
                return;
            }

            GameObject prefab = prefabAndSettings.gameObject;

            var worldPosition = target.transform.TransformPoint(hit.position);
            var worldNormal   = target.transform.TransformDirection(hit.normal);
            Ray ray           = RandomRay(worldPosition, worldNormal, settings.radius, settings.falloff, settings.falloffCurve);

            ray.origin    = target.transform.InverseTransformPoint(ray.origin);
            ray.direction = target.transform.InverseTransformDirection(ray.direction);

            PolyRaycastHit rand_hit;

            Vector3[] vertices  = target.editableObject.editMesh.vertices;
            int[]     triangles = target.editableObject.editMesh.GetTriangles();

            if (PolySceneUtility.MeshRaycast(ray, vertices, triangles, out rand_hit))
            {
                PlacementSettings placementSettings = prefabAndSettings.settings;
                Vector3           scaleSetting      = prefab.transform.localScale;
                if (placementSettings.uniformBool)
                {
                    float uniformScale = Random.Range(placementSettings.uniformScale.x, placementSettings.uniformScale.y);
                    scaleSetting *= uniformScale;
                }
                else
                {
                    if (placementSettings.xScaleBool)
                    {
                        scaleSetting.x = Random.Range(placementSettings.scaleRangeMin.x, placementSettings.scaleRangeMax.x);
                    }
                    if (placementSettings.yScaleBool)
                    {
                        scaleSetting.y = Random.Range(placementSettings.scaleRangeMin.y, placementSettings.scaleRangeMax.y);
                    }
                    if (placementSettings.zScaleBool)
                    {
                        scaleSetting.z = Random.Range(placementSettings.scaleRangeMin.z, placementSettings.scaleRangeMax.z);
                    }
                }

                Vector3 rotationSetting = Vector3.zero;
                if (placementSettings.xRotationBool)
                {
                    rotationSetting.x = Random.Range(placementSettings.rotationRangeMin.x, placementSettings.rotationRangeMax.x);
                }
                if (placementSettings.yRotationBool)
                {
                    rotationSetting.y = Random.Range(placementSettings.rotationRangeMin.y, placementSettings.rotationRangeMax.y);
                }
                if (placementSettings.xRotationBool)
                {
                    rotationSetting.z = Random.Range(placementSettings.rotationRangeMin.z, placementSettings.rotationRangeMax.z);
                }


                Quaternion rotation = Quaternion.FromToRotation(Vector3.up, target.transform.TransformDirection(rand_hit.normal));

                GameObject inst = (GameObject)PrefabUtility.InstantiatePrefab(prefab);
                inst.transform.position   = target.transform.TransformPoint(rand_hit.position);
                inst.transform.rotation   = rotation;
                inst.transform.localScale = scaleSetting;

                float pivotOffset = s_UsePivotForPlacement ? 0f : GetPivotOffset(inst);

                inst.name = FormatInstanceName(prefab);

                inst.transform.position = inst.transform.position - (inst.transform.up * pivotOffset);
                inst.transform.rotation = inst.transform.rotation * Quaternion.Euler(rotationSetting);


                if (s_AvoidOverlappingGameObjects && TestIntersection(inst))
                {
                    Object.DestroyImmediate(inst);
                    return;
                }

                if (s_ParentObjectWithSurface)
                {
                    inst.transform.SetParent(target.transform);
                }

                m_PrefabsInstances.Add(inst);

                Undo.RegisterCreatedObjectUndo(inst, UndoMessage);
            }
        }
Exemple #4
0
 internal override void OnBrushBeginApply(BrushTarget target, BrushSettings settings)
 {
     base.OnBrushBeginApply(target, settings);
     m_PrefabsInstances = PolySceneUtility.FindInstancesInScene(prefabPalette.prefabs.Select(x => x.gameObject), FormatInstanceName).ToList();
 }
        /// <summary>
        /// Calculate the weights for this ray.
        /// </summary>
        /// <param name="mouseRay">The ray used to calculate weights</param>
        /// <param name="target">The object on which to calculate the weights</param>
        /// <returns>true if mouseRay hits the target, false otherwise</returns>
        bool DoMeshRaycast(Ray mouseRay, BrushTarget target, MirrorSettings mirrorSettings)
        {
            if (!Util.IsValid(target))
            {
                return(false);
            }

            target.ClearRaycasts();

            EditableObject editable = target.editableObject;

            s_Rays.Clear();
            s_Rays.Add(mouseRay);

            if (mirrorSettings.Axes != BrushMirror.None)
            {
                for (int i = 0; i < 3; i++)
                {
                    if (((uint)mirrorSettings.Axes & (1u << i)) < 1)
                    {
                        continue;
                    }

                    int len = s_Rays.Count;

                    for (int n = 0; n < len; n++)
                    {
                        Vector3 flipVec = ((BrushMirror)(1u << i)).ToVector3();

                        if (mirrorSettings.Space == MirrorCoordinateSpace.World)
                        {
                            Vector3 cen = editable.gameObjectAttached.GetComponent <Renderer>().bounds.center;
                            s_Rays.Add(new Ray(Vector3.Scale(s_Rays[n].origin - cen, flipVec) + cen,
                                               Vector3.Scale(s_Rays[n].direction, flipVec)));
                        }
                        else
                        {
                            Transform t = SceneView.lastActiveSceneView.camera.transform;
                            Vector3   o = t.InverseTransformPoint(s_Rays[n].origin);
                            Vector3   d = t.InverseTransformDirection(s_Rays[n].direction);
                            s_Rays.Add(new Ray(t.TransformPoint(Vector3.Scale(o, flipVec)),
                                               t.TransformDirection(Vector3.Scale(d, flipVec))));
                        }
                    }
                }
            }

            bool hitMesh = false;

            int[] triangles = editable.editMesh.GetTriangles();

            foreach (Ray ray in s_Rays)
            {
                PolyRaycastHit hit;

                if (PolySceneUtility.WorldRaycast(ray, editable.transform, editable.visualMesh.vertices, triangles, out hit))
                {
                    target.raycastHits.Add(hit);
                    hitMesh = true;
                }
            }

            PolySceneUtility.CalculateWeightedVertices(target, brushSettings, tool, mode);

            return(hitMesh);
        }
        void OnSceneGUI(SceneView sceneView)
        {
            if (mode == null)
            {
                return;
            }

            Event e = Event.current;

            CheckForEscapeKey(e);

            if (Tools.current != Tool.None)
            {
                SetTool(BrushTool.None);
            }

            if (brushSettings == null)
            {
                SetBrushSettings(PolyEditorUtility.GetFirstOrNew <BrushSettings>());
            }

            if (PolySceneUtility.SceneViewInUse(e) || tool == BrushTool.None)
            {
                // Force exit the current brush if user's mouse left
                // the SceneView while a brush was still in use.
                if (m_ApplyingBrush)
                {
                    OnFinishApplyingBrush();
                }
                return;
            }

            int controlID = GUIUtility.GetControlID(FocusType.Passive);

            if (Util.IsValid(brushTarget))
            {
                HandleUtility.AddDefaultControl(controlID);
            }

            switch (e.GetTypeForControl(controlID))
            {
            case EventType.MouseMove:
                // Handles:
                //		OnBrushEnter
                //		OnBrushExit
                //		OnBrushMove
                if (EditorApplication.timeSinceStartup - m_LastBrushUpdate > GetTargetFramerate(brushTarget))
                {
                    m_LastBrushUpdate = EditorApplication.timeSinceStartup;
                    UpdateBrush(e.mousePosition, Event.current.control, Event.current.shift && Event.current.type != EventType.ScrollWheel);
                }
                break;

            case EventType.MouseDown:
            case EventType.MouseDrag:
                // Handles:
                //		OnBrushBeginApply
                //		OnBrushApply
                //		OnBrushFinishApply
                if (EditorApplication.timeSinceStartup - m_LastBrushUpdate > GetTargetFramerate(brushTarget))
                {
                    m_LastBrushUpdate = EditorApplication.timeSinceStartup;
                    UpdateBrush(e.mousePosition, Event.current.control, Event.current.shift && Event.current.type != EventType.ScrollWheel);
                    ApplyBrush(Event.current.control, Event.current.shift && Event.current.type != EventType.ScrollWheel);
                }
                break;

            case EventType.MouseUp:
                if (m_ApplyingBrush)
                {
                    OnFinishApplyingBrush();
                    UpdateBrush(e.mousePosition, Event.current.control, Event.current.shift && Event.current.type != EventType.ScrollWheel);
                }
                break;

            case EventType.ScrollWheel:
                ScrollBrushSettings(e);
                break;
            }

            if (Util.IsValid(brushTarget))
            {
                mode.DrawGizmos(brushTarget, brushSettings);
            }
        }
Exemple #7
0
        void OnSceneGUI(SceneView sceneView)
        {
            if (mode == null)
            {
                return;
            }

            Event e = Event.current;

            CheckForEscapeKey(e);

            if (Tools.current != Tool.None)
            {
                SetTool(BrushTool.None);
            }

            if (brushSettings == null)
            {
                SetBrushSettings(PolyEditorUtility.GetFirstOrNew <BrushSettings>());
            }

            if (PolySceneUtility.SceneViewInUse(e) || tool == BrushTool.None)
            {
                // Force exit the current brush if user's mouse left
                // the SceneView while a brush was still in use.
                if (m_ApplyingBrush)
                {
                    OnFinishApplyingBrush();
                }
                return;
            }

            int controlID = GUIUtility.GetControlID(FocusType.Passive);

            if (Util.IsValid(brushTarget))
            {
                HandleUtility.AddDefaultControl(controlID);
            }

            switch (e.GetTypeForControl(controlID))
            {
            case EventType.MouseMove:
                // Handles:
                //		OnBrushEnter
                //		OnBrushExit
                //		OnBrushMove
                if (EditorApplication.timeSinceStartup - m_LastBrushUpdate > GetTargetFramerate(brushTarget))
                {
                    m_LastBrushUpdate = EditorApplication.timeSinceStartup;
                    UpdateBrush(e.mousePosition, Event.current.control, Event.current.shift && Event.current.type != EventType.ScrollWheel);
                }
                break;

            case EventType.MouseDown:
            case EventType.MouseDrag:
                // Handles:
                //		OnBrushBeginApply
                //		OnBrushApply
                //		OnBrushFinishApply
                if (EditorApplication.timeSinceStartup - m_LastBrushUpdate > GetTargetFramerate(brushTarget))
                {
                    m_LastBrushUpdate = EditorApplication.timeSinceStartup;
                    UpdateBrush(e.mousePosition, Event.current.control, Event.current.shift && Event.current.type != EventType.ScrollWheel);
                    ApplyBrush(Event.current.control, Event.current.shift && Event.current.type != EventType.ScrollWheel);
                }
                break;

            case EventType.MouseUp:
                if (m_ApplyingBrush)
                {
                    OnFinishApplyingBrush();
                    UpdateBrush(e.mousePosition, Event.current.control, Event.current.shift && Event.current.type != EventType.ScrollWheel);
                }
                break;

            case EventType.ScrollWheel:
                ScrollBrushSettings(e);
                break;

            case EventType.KeyDown:
                // Key down event continues as long as the key is held down. However, we only need to update the brush once while the key is down.
                // Check if the key has already been marked as pressed in the brush settings, and don't update if it is.
                if (((e.keyCode == KeyCode.LeftControl || e.keyCode == KeyCode.RightControl) && !brushSettings.isUserHoldingControl) ||
                    ((e.keyCode == KeyCode.LeftShift || e.keyCode == KeyCode.RightShift) && !brushSettings.isUserHoldingShift))
                {
                    m_LastBrushUpdate = EditorApplication.timeSinceStartup;
                    UpdateBrush(e.mousePosition, Event.current.control, Event.current.shift && Event.current.type != EventType.ScrollWheel);
                }
                break;

            case EventType.KeyUp:
                // Key up only happens once, so don't need to check if we were already holding control/shift
                if ((e.keyCode == KeyCode.LeftControl || e.keyCode == KeyCode.RightControl) ||
                    (e.keyCode == KeyCode.LeftShift || e.keyCode == KeyCode.RightShift))
                {
                    m_LastBrushUpdate = EditorApplication.timeSinceStartup;
                    UpdateBrush(e.mousePosition, Event.current.control, Event.current.shift && Event.current.type != EventType.ScrollWheel);
                }
                break;
            }

            if (Util.IsValid(brushTarget))
            {
                mode.DrawGizmos(brushTarget, brushSettings);
            }
        }
        /// <summary>
        /// Calculate the weights for this ray.
        /// </summary>
        /// <param name="mouseRay">The ray used to calculate weights</param>
        /// <param name="target">The object on which to calculate the weights</param>
        /// <returns>true if mouseRay hits the target, false otherwise</returns>
        bool DoMeshRaycast(Ray mouseRay, BrushTarget target, MirrorSettings mirrorSettings)
        {
            m_SecondaryBrushTargets.Clear();
            if (!Util.IsValid(target))
            {
                return(false);
            }

            target.ClearRaycasts();

            EditableObject editable = target.editableObject;

            s_Rays.Clear();
            s_Rays.Add(mouseRay);

            if (mirrorSettings.Axes != BrushMirror.None)
            {
                for (int i = 0; i < 3; i++)
                {
                    if (((uint)mirrorSettings.Axes & (1u << i)) < 1)
                    {
                        continue;
                    }

                    int len = s_Rays.Count;

                    for (int n = 0; n < len; n++)
                    {
                        Vector3 flipVec = ((BrushMirror)(1u << i)).ToVector3();

                        if (mirrorSettings.Space == MirrorCoordinateSpace.World)
                        {
                            Vector3 cen = editable.gameObjectAttached.GetComponent <Renderer>().bounds.center;
                            s_Rays.Add(new Ray(Vector3.Scale(s_Rays[n].origin - cen, flipVec) + cen,
                                               Vector3.Scale(s_Rays[n].direction, flipVec)));
                        }
                        else
                        {
                            Transform t = SceneView.lastActiveSceneView.camera.transform;
                            Vector3   o = t.InverseTransformPoint(s_Rays[n].origin);
                            Vector3   d = t.InverseTransformDirection(s_Rays[n].direction);
                            s_Rays.Add(new Ray(t.TransformPoint(Vector3.Scale(o, flipVec)),
                                               t.TransformDirection(Vector3.Scale(d, flipVec))));
                        }
                    }
                }
            }

            bool hitMesh = false;

            int[] triangles = editable.editMesh.GetTriangles();
            foreach (Ray ray in s_Rays)
            {
                PolyRaycastHit hit;

                if (PolySceneUtility.WorldRaycast(ray, editable.transform, editable.visualMesh.vertices, triangles,
                                                  out hit))
                {
                    target.raycastHits.Add(hit);
                    hitMesh = true;
                }
            }

            PolySceneUtility.CalculateWeightedVertices(target, brushSettings, tool, mode);

            if (hitMesh && !s_LockBrushToFirst)
            {
                Transform[] trs  = Selection.GetTransforms(SelectionMode.Unfiltered);
                var         hits = target.raycastHits;
                foreach (var selectedTransform in trs)
                {
                    bool isValid = false;
                    if (selectedTransform != editable.transform)
                    {
                        BrushTarget secondaryTarget = GetOrCreateBrushTarget(selectedTransform.gameObject);
                        isValid = Util.IsValid(secondaryTarget);
                        if (isValid)
                        {
                            m_SecondaryBrushTargets.Add(secondaryTarget);
                            secondaryTarget.ClearRaycasts();

                            foreach (var hit in hits)
                            {
                                PolyRaycastHit secondaryHit = new PolyRaycastHit(hit.distance,
                                                                                 secondaryTarget.transform.InverseTransformPoint(editable.transform.TransformPoint(hit.position)),
                                                                                 hit.normal,
                                                                                 -1);
                                secondaryTarget.raycastHits.Add(secondaryHit);
                            }
                        }
                        PolySceneUtility.CalculateWeightedVertices(secondaryTarget, brushSettings, tool, mode);
                    }
                }
            }

            return(hitMesh);
        }