예제 #1
0
        /// <summary>
        /// Snap a Vector3 to the nearest point on the current ProGrids grid if ProGrids is enabled.
        /// </summary>
        /// <param name="point"></param>
        /// <returns></returns>
        public static float ProGridsSnap(float point)
        {
            if (GetProGridsType() == null)
            {
                return(point);
            }

            if (SnapEnabled())
            {
                return(ProGridsSnapping.SnapValue(point, ProGridsInterface.SnapValue()));
            }

            return(point);
        }
예제 #2
0
        /// <summary>
        /// Snap a Vector3 to the nearest point on the current ProGrids grid if ProGrids is enabled, with mask.
        /// </summary>
        /// <param name="point"></param>
        /// <param name="mask"></param>
        /// <returns></returns>
        public static Vector3 ProGridsSnap(Vector3 point, Vector3 mask)
        {
            if (GetProGridsType() == null)
            {
                return(point);
            }

            if (ProGridsInterface.SnapEnabled())
            {
                float snap = ProGridsInterface.SnapValue();
                return(ProGridsSnapping.SnapValue(point, mask * snap));
            }

            return(point);
        }
예제 #3
0
        internal static void SetPivotLocationAndSnap(ProBuilderMesh mesh)
        {
            if (ProGridsInterface.SnapEnabled())
            {
                mesh.transform.position = ProGridsSnapping.SnapValue(mesh.transform.position, ProGridsInterface.SnapValue());
            }
            else if (s_SnapNewShapesToGrid)
            {
                mesh.transform.position = ProGridsSnapping.SnapValue(mesh.transform.position, new Vector3(
                                                                         EditorPrefs.GetFloat("MoveSnapX"),
                                                                         EditorPrefs.GetFloat("MoveSnapY"),
                                                                         EditorPrefs.GetFloat("MoveSnapZ")));
            }

            mesh.Optimize();
        }
예제 #4
0
        /// <summary>
        /// Return the last known grid pivot point.
        /// </summary>
        /// <param name="pivot"></param>
        /// <returns></returns>
        public static bool GetPivot(out Vector3 pivot)
        {
            pivot = Vector3.zero;

            if (s_GetPivotDelegate == null)
            {
                s_GetPivotDelegate = (Func <Vector3>)ReflectionUtility.GetOpenDelegate <Func <Vector3> >(GetProGridsType(), "GetPivot");
            }

            if (s_GetPivotDelegate != null)
            {
                pivot = s_GetPivotDelegate();

                // earlier version of progrids return a non-snapped pivot point
                pivot = ProGridsSnapping.SnapValue(pivot, SnapValue());
                return(true);
            }

            return(false);
        }
예제 #5
0
        protected override void DoTool(Vector3 handlePosition, Quaternion handleRotation)
        {
            if (!isEditing)
            {
                m_Position = Vector3.zero;
            }

            EditorHandleUtility.PushMatrix();

            Handles.matrix = Matrix4x4.TRS(handlePosition, handleRotation, Vector3.one);

            EditorGUI.BeginChangeCheck();

            Handles.color = Color.blue;

            m_Position = Handles.Slider2D(m_Position,
                                          Vector3.forward,
                                          Vector3.right,
                                          Vector3.up,
                                          HandleUtility.GetHandleSize(m_Position) * .2f,
                                          Handles.RectangleHandleCap,
                                          0f,
                                          false);

            Handles.color = Color.green;

            m_Position = Handles.Slider(m_Position, Vector3.up);

            Handles.color = Color.red;

            m_Position = Handles.Slider(m_Position, Vector3.right);

            Handles.color = Color.white;

            if (EditorGUI.EndChangeCheck())
            {
                if (!isEditing)
                {
                    BeginEdit("Translate Textures");
                }

                if (relativeSnapEnabled)
                {
                    m_Position.x = ProGridsSnapping.SnapValue(m_Position.x, relativeSnapX);
                    m_Position.y = ProGridsSnapping.SnapValue(m_Position.y, relativeSnapY);
                }
                else if (progridsSnapEnabled)
                {
                    m_Position.x = ProGridsSnapping.SnapValue(m_Position.x, progridsSnapValue);
                    m_Position.y = ProGridsSnapping.SnapValue(m_Position.y, progridsSnapValue);
                }

                // invert `y` because to users it's confusing that "up" in UV space visually moves the texture down
                var delta = new Vector4(m_Position.x, -m_Position.y, 0f, 0f);

                foreach (var value in elementSelection)
                {
                    var selection = value as TranslateTextureSelection;

                    if (selection == null)
                    {
                        continue;
                    }

                    // Account for object scale
                    delta *= k_Vector3Magnitude / selection.mesh.transform.lossyScale.magnitude;

                    var origins   = selection.origins;
                    var positions = selection.textures;

                    // Translating faces is treated as a special case because we want the textures in scene to visually
                    // match the movement of the translation handle. When UVs are scaled, they have the appearance of
                    // moving faster or slower (even though they are translating the correct distances). To avoid this,
                    // we cache the UV scale of each face and modify the translation delta accordingly. This isn't perfect,
                    // as it will not be able to find the scale for sheared or otherwise distorted face UVs. However, for
                    // most cases it maps quite well.
                    if (ProBuilderEditor.selectMode == SelectMode.TextureFace)
                    {
                        foreach (var face in selection.faceAndScale)
                        {
                            var faceDelta = new Vector4(delta.x / face.item2.x, delta.y / face.item2.y, 0f, 0f);

                            foreach (var index in face.item1.distinctIndexes)
                            {
                                positions[index] = origins[index] + faceDelta;
                            }
                        }
                    }
                    else
                    {
                        foreach (var group in value.elementGroups)
                        {
                            foreach (var index in group.indices)
                            {
                                positions[index] = origins[index] + delta;
                            }
                        }
                    }

                    selection.mesh.mesh.SetUVs(k_TextureChannel, positions);
                }
            }

            EditorHandleUtility.PopMatrix();
        }
예제 #6
0
        protected override void DoTool(Vector3 handlePosition, Quaternion handleRotation)
        {
            if (!isEditing)
            {
                m_Rotation = 0f;
            }

            EditorGUI.BeginChangeCheck();

            var size = HandleUtility.GetHandleSize(handlePosition);

            EditorHandleUtility.PushMatrix();

            Handles.matrix = Matrix4x4.TRS(handlePosition, handleRotation, Vector3.one);

            Handles.color = Color.blue;
            m_Euler.z     = m_Rotation;
            m_Quaternion  = Quaternion.Euler(m_Euler);
            m_Quaternion  = Handles.Disc(m_Quaternion, Vector3.zero, Vector3.forward, size, relativeSnapEnabled, relativeSnapRotation);
            m_Euler       = m_Quaternion.eulerAngles;
            m_Rotation    = m_Euler.z;

            EditorHandleUtility.PopMatrix();

            if (EditorGUI.EndChangeCheck())
            {
                if (!isEditing)
                {
                    BeginEdit("Rotate Textures");
                }

                if (relativeSnapEnabled)
                {
                    m_Rotation = ProGridsSnapping.SnapValue(m_Rotation, relativeSnapX);
                }
                else if (progridsSnapEnabled)
                {
                    m_Rotation = ProGridsSnapping.SnapValue(m_Rotation, progridsSnapValue);
                }

                foreach (var mesh in elementSelection)
                {
                    if (!(mesh is MeshAndTextures))
                    {
                        continue;
                    }
                    var mat = (MeshAndTextures)mesh;

                    var origins   = mat.origins;
                    var positions = mat.textures;

                    foreach (var group in mat.elementGroups)
                    {
                        foreach (var index in group.indices)
                        {
                            positions[index] = mat.postApplyMatrix.MultiplyPoint(
                                Math.RotateAroundPoint(
                                    mat.preApplyMatrix.MultiplyPoint3x4(origins[index]), Vector2.zero, -m_Rotation));
                        }
                    }

                    mesh.mesh.mesh.SetUVs(k_TextureChannel, positions);
                }
            }
        }
예제 #7
0
        protected override void DoTool(Vector3 handlePosition, Quaternion handleRotation)
        {
            base.DoTool(handlePosition, handleRotation);

            if (!isEditing)
            {
                m_HandlePosition = handlePosition;
            }

#if PROBUILDER_ENABLE_TRANSFORM_ORIGIN_GIZMO
            if (isEditing)
            {
                DrawSelectionOriginGizmos();
            }
#endif

            EditorGUI.BeginChangeCheck();

            m_HandlePosition = Handles.PositionHandle(m_HandlePosition, handleRotation);

            m_RawHandleDelta = m_HandlePosition - handlePositionOrigin;

            var delta = m_RawHandleDelta;

            if (EditorGUI.EndChangeCheck() && delta.sqrMagnitude > k_MinTranslateDeltaSqrMagnitude)
            {
                if (!isEditing)
                {
                    BeginEdit("Translate Selection");
                }

                if (vertexDragging)
                {
                    Vector3 nearest;

                    if (FindNearestVertex(currentEvent.mousePosition, out nearest))
                    {
                        var unrotated = handleRotationOriginInverse * delta;
                        var dir       = new Vector3Mask(unrotated, k_CardinalAxisError);

                        if (dir.active == 1)
                        {
                            var rotationDirection = handleRotationOrigin * dir * 10000f;

                            m_HandlePosition = HandleUtility.ProjectPointLine(nearest,
                                                                              handlePositionOrigin + rotationDirection,
                                                                              handlePositionOrigin - rotationDirection);

                            delta = m_HandlePosition - handlePositionOrigin;
                        }
                    }
                }
                else if (progridsSnapEnabled)
                {
                    if (snapAxisConstraint)
                    {
                        m_ActiveAxesModel |= new Vector3Mask(handleRotationOriginInverse * delta, k_CardinalAxisError);
                        m_ActiveAxesWorld  = new Vector3Mask(handleRotation * m_ActiveAxesModel);

                        if (m_ActiveAxesWorld.active == 1)
                        {
                            m_HandlePosition = ProGridsSnapping.SnapValueOnRay(
                                new Ray(handlePositionOrigin, delta),
                                delta.magnitude,
                                progridsSnapValue,
                                m_ActiveAxesWorld);
                        }
                        else
                        {
                            m_HandlePosition = ProGridsSnapping.SnapValue(m_HandlePosition, progridsSnapValue);
                        }
                    }
                    else
                    {
                        m_HandlePosition = ProGridsSnapping.SnapValue(m_HandlePosition, progridsSnapValue);
                    }

                    delta = m_HandlePosition - handlePositionOrigin;
                }

#if PROBUILDER_ENABLE_TRANSFORM_ORIGIN_GIZMO
                if (pivotPoint == PivotPoint.IndividualOrigins && !m_DirectionOriginInitialized)
                {
                    var mask = new Vector3Mask(handleRotationOriginInverse * delta, k_CardinalAxisError);

                    if (mask.active > 0)
                    {
                        m_IndividualOriginDirection  = mask;
                        m_DirectionOriginInitialized = true;
                    }
                }
#endif

                ApplyTranslation(handleRotationOriginInverse * delta);
            }

            // Draw at the end so we get the snapped value
            if (showHandleInfo && isEditing)
            {
                DrawDeltaInfo(string.Format("Translate: <b>{0:F2}</b>  {1}", delta.magnitude, (handleRotationOriginInverse * delta).ToString("0.00")));
            }
        }
예제 #8
0
        void ApplyTranslation(Vector3 translation)
        {
            var translationMagnitude = translation.magnitude;

            foreach (var key in elementSelection)
            {
                if (!(key is MeshAndPositions))
                {
                    continue;
                }

                var kvp          = (MeshAndPositions)key;
                var mesh         = kvp.mesh;
                var worldToLocal = mesh.transform.worldToLocalMatrix;
                var origins      = kvp.positions;
                var positions    = mesh.positionsInternal;

                foreach (var group in kvp.elementGroups)
                {
                    var postApplyMatrix = GetPostApplyMatrix(group);
                    var preApplyMatrix  = postApplyMatrix.inverse;

                    foreach (var index in group.indices)
                    {
                        // res = Group pre-apply matrix * world vertex position
                        // res += translation
                        // res = Group post-apply matrix * res
                        // positions[i] = mesh.worldToLocal * res
                        if (progridsSnapEnabled && !m_SnapAsGroup)
                        {
                            if (snapAxisConstraint && m_ActiveAxesWorld.active == 1)
                            {
                                var wp = postApplyMatrix.MultiplyPoint3x4(preApplyMatrix.MultiplyPoint3x4(origins[index]));

                                var snap = ProGridsSnapping.SnapValueOnRay(
                                    new Ray(wp, m_RawHandleDelta),
                                    translationMagnitude,
                                    progridsSnapValue,
                                    m_ActiveAxesWorld);

                                positions[index] = worldToLocal.MultiplyPoint3x4(snap);
                            }
                            else
                            {
                                var wp   = postApplyMatrix.MultiplyPoint3x4(translation + preApplyMatrix.MultiplyPoint3x4(origins[index]));
                                var snap = ProGridsSnapping.SnapValue(wp, Vector3.one * progridsSnapValue);
                                positions[index] = worldToLocal.MultiplyPoint3x4(snap);
                            }
                        }
                        else
                        {
                            positions[index] = worldToLocal.MultiplyPoint3x4(
                                postApplyMatrix.MultiplyPoint3x4(
                                    translation + preApplyMatrix.MultiplyPoint3x4(origins[index])));
                        }
                    }
                }

                mesh.mesh.vertices = positions;
                mesh.RefreshUV(MeshSelection.selectedFacesInEditZone[mesh]);
                mesh.Refresh(RefreshMask.Normals);
            }

            ProBuilderEditor.Refresh(false);
        }