// Inspector GUI shown in the Editor window.  Base class shows BrushSettings by default
        internal override void DrawGUI(BrushSettings brushSettings)
        {
            base.DrawGUI(brushSettings);

            /// Verify dependencies
            VerifyLoadedAssetsIntegrity();

            EditorGUI.BeginChangeCheck();

            /// Interface
            s_UsePivotForPlacement.value = PolyGUILayout.Toggle(m_GCUsePrefabPivot, s_UsePivotForPlacement);

            s_ParentObjectWithSurface.value     = PolyGUILayout.Toggle(m_GCHitSurfaceIsParent, s_ParentObjectWithSurface);
            s_AvoidOverlappingGameObjects.value = PolyGUILayout.Toggle(m_GCAvoidOverlappingGameObjects, s_AvoidOverlappingGameObjects);

            if (SceneView.lastActiveSceneView.in2DMode)
            {
                s_2DDepthOffset.value = PolyGUILayout.FloatField(m_GC2DPaintingDepth, s_2DDepthOffset);
            }

            EditorGUI.BeginChangeCheck();
            m_CurrentPaletteIndex = EditorGUILayout.Popup(m_CurrentPaletteIndex, m_AvailablePalettesAsStrings);
            if (EditorGUI.EndChangeCheck())
            {
                if (m_CurrentPaletteIndex >= m_AvailablePalettes.Length)
                {
                    SetPrefabPalette(PrefabPaletteEditor.AddNew());
                }
                else
                {
                    SetPrefabPalette(m_AvailablePalettes[m_CurrentPaletteIndex]);
                }
            }

            using (new GUILayout.HorizontalScope())
            {
                s_PreviewThumbSize.value = (int)EditorGUILayout.Slider("Preview Size", (float)s_PreviewThumbSize, 60f, 128f);
            }

            if (EditorGUI.EndChangeCheck())
            {
                if (m_CurrentPaletteIndex >= m_AvailablePalettes.Length)
                {
                    SetPrefabPalette(PrefabPaletteEditor.AddNew());
                }
                else
                {
                    SetPrefabPalette(m_AvailablePalettes[m_CurrentPaletteIndex]);
                }

                PolybrushSettings.Save();
            }

            using (new GUILayout.VerticalScope())
            {
                if (prefabLoadoutEditor != null)
                {
                    prefabLoadoutEditor.OnInspectorGUI_Internal(s_PreviewThumbSize);
                }
            }
        }
Пример #2
0
        // Called whenever the brush is moved.  Note that @target may have a null editableObject.
        internal override void OnBrushMove(BrushTarget target, BrushSettings settings)
        {
            base.OnBrushMove(target, settings);

            if (!Util.IsValid(target) || !m_LikelySupportsTextureBlending)
            {
                return;
            }

            bool invert = settings.isUserHoldingControl;

            float[] weights;

            if (paintMode == PaintMode.Brush)
            {
                weights = target.GetAllWeights();
            }
            else if (paintMode == PaintMode.Flood)
            {
                weights = new float[m_VertexCount];

                for (int i = 0; i < m_VertexCount; i++)
                {
                    weights[i] = 1f;
                }
            }
            else
            {
                weights = new float[m_VertexCount];
                int[] indices      = target.editableObject.editMesh.GetTriangles();
                int   index        = 0;
                float weightTarget = 1f;

                foreach (PolyRaycastHit hit in target.raycastHits)
                {
                    if (hit.triangle > -1)
                    {
                        index = hit.triangle * 3;

                        m_FillModeEdges[0].x = indices[index + 0];
                        m_FillModeEdges[0].y = indices[index + 1];

                        m_FillModeEdges[1].x = indices[index + 1];
                        m_FillModeEdges[1].y = indices[index + 2];

                        m_FillModeEdges[2].x = indices[index + 2];
                        m_FillModeEdges[2].y = indices[index + 0];

                        for (int i = 0; i < 3; i++)
                        {
                            if (m_TriangleLookup.TryGetValue(m_FillModeEdges[i], out m_FillModeAdjacentTriangles))
                            {
                                for (int n = 0; n < m_FillModeAdjacentTriangles.Count; n++)
                                {
                                    index = m_FillModeAdjacentTriangles[n] * 3;

                                    weights[indices[index]]     = weightTarget;
                                    weights[indices[index + 1]] = weightTarget;
                                    weights[indices[index + 2]] = weightTarget;
                                }
                            }
                        }
                    }
                }
            }

            if (m_SelectedAttributeIndex < 0 || m_SelectedAttributeIndex >= meshAttributes.Length)
            {
                SetBrushColorWithAttributeIndex(0);
            }

            int mask = meshAttributes[m_SelectedAttributeIndex].mask;

            splat_current.LerpWeights(splat_cache, invert ? splat_erase : splat_target, mask, weights);
            splat_current.Apply(target.editableObject.editMesh);
            target.editableObject.ApplyMeshAttributes();
        }
Пример #3
0
        internal override void DrawGizmos(BrushTarget target, BrushSettings settings)
        {
            PolyMesh mesh = target.editableObject.editMesh;

            if (Util.IsValid(target) && paintMode == PaintMode.Fill)
            {
                Vector3[] vertices = mesh.vertices;
                int[]     indices  = mesh.GetTriangles();

                PolyHandles.PushMatrix();
                PolyHandles.PushHandleColor();

                Handles.matrix = target.transform.localToWorldMatrix;

                int index = 0;

                foreach (PolyRaycastHit hit in target.raycastHits)
                {
                    if (hit.triangle > -1)
                    {
                        Handles.color = Color.green;

                        index = hit.triangle * 3;

                        Handles.DrawLine(vertices[indices[index + 0]] + hit.normal * .1f, vertices[indices[index + 1]] + hit.normal * .1f);
                        Handles.DrawLine(vertices[indices[index + 1]] + hit.normal * .1f, vertices[indices[index + 2]] + hit.normal * .1f);
                        Handles.DrawLine(vertices[indices[index + 2]] + hit.normal * .1f, vertices[indices[index + 0]] + hit.normal * .1f);

                        m_FillModeEdges[0].x = indices[index + 0];
                        m_FillModeEdges[0].y = indices[index + 1];

                        m_FillModeEdges[1].x = indices[index + 1];
                        m_FillModeEdges[1].y = indices[index + 2];

                        m_FillModeEdges[2].x = indices[index + 2];
                        m_FillModeEdges[2].y = indices[index + 0];

                        for (int i = 0; i < 3; i++)
                        {
                            if (m_TriangleLookup.TryGetValue(m_FillModeEdges[i], out m_FillModeAdjacentTriangles))
                            {
                                for (int n = 0; n < m_FillModeAdjacentTriangles.Count; n++)
                                {
                                    index = m_FillModeAdjacentTriangles[n] * 3;

                                    Handles.DrawLine(vertices[indices[index + 0]] + hit.normal * .1f, vertices[indices[index + 1]] + hit.normal * .1f);
                                    Handles.DrawLine(vertices[indices[index + 1]] + hit.normal * .1f, vertices[indices[index + 2]] + hit.normal * .1f);
                                    Handles.DrawLine(vertices[indices[index + 2]] + hit.normal * .1f, vertices[indices[index + 0]] + hit.normal * .1f);
                                }
                            }
                        }
                    }
                }

                PolyHandles.PopHandleColor();
                PolyHandles.PopMatrix();
            }
            else
            {
                base.DrawGizmos(target, settings);
            }
        }
Пример #4
0
 // Called whenever the brush is moved.  Note that @target may have a null editableObject.
 internal override void OnBrushMove(BrushTarget target, BrushSettings settings)
 {
     base.OnBrushMove(target, settings);
 }
Пример #5
0
 void OnBrushEnter(BrushTarget target, BrushSettings settings)
 {
     mode.OnBrushEnter(target.editableObject, settings);
 }
Пример #6
0
        internal override void OnBrushApply(BrushTarget target, BrushSettings settings)
        {
            if (!likelyToSupportVertexSculpt)
            {
                return;
            }

            int rayCount = target.raycastHits.Count;


            Vector3  v, t, avg, dirVec = s_SmoothDirection.value.ToVector3();
            Plane    plane = new Plane(Vector3.up, Vector3.zero);
            PolyMesh mesh  = target.editableObject.editMesh;

            Vector3[] normals     = (s_SmoothDirection == PolyDirection.BrushNormal) ? mesh.normals : null;
            int       vertexCount = mesh.vertexCount;

            // don't use target.GetAllWeights because brush normal needs
            // to know which ray to use for normal
            for (int ri = 0; ri < rayCount; ri++)
            {
                PolyRaycastHit hit = target.raycastHits[ri];

                if (hit.weights == null || hit.weights.Length < vertexCount)
                {
                    continue;
                }

                for (int i = 0; i < commonVertexCount; i++)
                {
                    int index = commonVertices[i][0];

                    if (hit.weights[index] < .0001f || (s_IgnoreOpenEdges && nonManifoldIndices.Contains(index)))
                    {
                        continue;
                    }

                    v = vertices[index];

                    if (s_SmoothDirection == PolyDirection.VertexNormal)
                    {
                        avg = Math.Average(vertices, neighborLookup[index]);
                    }
                    else
                    {
                        avg = Math.WeightedAverage(vertices, neighborLookup[index], hit.weights);

                        if (s_SmoothDirection == PolyDirection.BrushNormal)
                        {
                            if (s_UseFirstNormalVector)
                            {
                                dirVec = brushNormalOnBeginApply[ri].normalized;
                            }
                            else
                            {
                                dirVec = Math.WeightedAverage(normals, neighborLookup[index], hit.weights).normalized;
                            }
                        }

                        plane.SetNormalAndPosition(dirVec, avg);
                        avg = v - dirVec * plane.GetDistanceToPoint(v);
                    }

                    t = Vector3.Lerp(v, avg, hit.weights[index]);
                    int[] indices = commonVertices[i];

                    Vector3 pos = v + (t - v) * settings.strength * SMOOTH_STRENGTH_MODIFIER;

                    for (int n = 0; n < indices.Length; n++)
                    {
                        vertices[indices[n]] = pos;
                    }
                }
            }

            mesh.vertices = vertices;

            if (tempComponent != null)
            {
                tempComponent.OnVerticesMoved(mesh);
            }

            base.OnBrushApply(target, settings);
        }
Пример #7
0
 internal override void OnBrushSettingsChanged(BrushTarget target, BrushSettings settings)
 {
     base.OnBrushSettingsChanged(target, settings);
 }
Пример #8
0
 /// <summary>
 /// Called when the mouse begins a drag across a valid target.
 /// </summary>
 /// <param name="target"> The object the mouse is dragging on</param>
 /// <param name="settings">Current brush settings</param>
 internal virtual void OnBrushBeginApply(BrushTarget target, BrushSettings settings)
 {
 }
Пример #9
0
 /// <summary>
 /// Called every time the brush should apply itself to a valid target.  Default is on mouse move.
 /// </summary>
 /// <param name="target">Object on which to apply the brush</param>
 /// <param name="settings">Current brush settings</param>
 internal abstract void OnBrushApply(BrushTarget target, BrushSettings settings);
Пример #10
0
        /// <summary>
        /// Calculates the per-vertex weight for each raycast hit and fills in brush target weights.
        /// </summary>
        /// <param name="target"></param>
        /// <param name="settings"></param>
        /// <param name="tool"></param>
        /// <param name="bMode"></param>
        internal static void CalculateWeightedVertices(BrushTarget target, BrushSettings settings, BrushTool tool = BrushTool.None, BrushMode bMode = null)
        {
            if (target == null || settings == null)
            {
                return;
            }

            if (target.editableObject == null)
            {
                return;
            }

            bool  uniformScale = Math.VectorIsUniform(target.transform.lossyScale);
            float scale        = uniformScale ? 1f / target.transform.lossyScale.x : 1f;

            PolyMesh mesh = target.editableObject.visualMesh;

            Transform transform   = target.transform;
            int       vertexCount = mesh.vertexCount;

            Vector3[] vertices = mesh.vertices;

            if (!uniformScale)
            {
                // As we only increase size only when it's needed, always make sure to
                // use the vertexCount variable in loop statements and not the buffer length.
                if (s_WorldBuffer.Length < vertexCount)
                {
                    System.Array.Resize <Vector3>(ref s_WorldBuffer, vertexCount);
                }

                for (int i = 0; i < vertexCount; i++)
                {
                    s_WorldBuffer[i] = transform.TransformPoint(vertices[i]);
                }
                vertices = s_WorldBuffer;
            }

            AnimationCurve curve = settings.falloffCurve;
            float          radius = settings.radius * scale, falloff_mag = Mathf.Max((radius - radius * settings.falloff), 0.00001f);

            Vector3        hitPosition = Vector3.zero;
            PolyRaycastHit hit;

            if (tool == BrushTool.Texture && mesh.subMeshCount > 1)
            {
                var   mode           = bMode as BrushModeTexture;
                int[] submeshIndices = mesh.subMeshes[mode.currentMeshACIndex].indexes;

                for (int n = 0; n < target.raycastHits.Count; n++)
                {
                    hit = target.raycastHits[n];
                    hit.SetVertexCount(vertexCount);

                    for (int i = 0; i < vertexCount; i++)
                    {
                        hit.weights[i] = 0f;
                    }

                    hitPosition = uniformScale ? hit.position : transform.TransformPoint(hit.position);

                    for (int i = 0; i < submeshIndices.Length; i++)
                    {
                        int   currentIndex = submeshIndices[i];
                        float dist         = (hitPosition - vertices[currentIndex]).magnitude;
                        float delta        = radius - dist;

                        if (delta >= 0)
                        {
                            float weight = Mathf.Clamp(curve.Evaluate(1f - Mathf.Clamp(delta / falloff_mag, 0f, 1f)), 0f, 1f);

                            hit.weights[currentIndex] = weight;
                        }
                    }
                }
            }
            else
            {
                int[][] common = PolyMeshUtility.GetCommonVertices(mesh);

                Vector3 buf = Vector3.zero;

                for (int n = 0; n < target.raycastHits.Count; n++)
                {
                    hit = target.raycastHits[n];
                    hit.SetVertexCount(vertexCount);

                    hitPosition = uniformScale ? hit.position : transform.TransformPoint(hit.position);

                    for (int i = 0; i < common.Length; i++)
                    {
                        int[] commonItem       = common[i];
                        int   commonArrayCount = commonItem.Length;

                        Math.Subtract(vertices[commonItem[0]], hitPosition, ref buf);

                        float sqrDist = buf.sqrMagnitude;

                        if (sqrDist > radius * radius)
                        {
                            for (int j = 0; j < commonArrayCount; j++)
                            {
                                hit.weights[commonItem[j]] = 0f;
                            }
                        }
                        else
                        {
                            float weight = Mathf.Clamp(curve.Evaluate(1f - Mathf.Clamp((radius - Mathf.Sqrt(sqrDist)) / falloff_mag, 0f, 1f)), 0f, 1f);

                            for (int j = 0; j < commonArrayCount; j++)
                            {
                                hit.weights[commonItem[j]] = weight;
                            }
                        }
                    }
                }
            }

            target.GetAllWeights(true);
        }
Пример #11
0
 /// <summary>
 /// Called whenever the brush is moved. Note that @target may have a null editableObject.
 /// </summary>
 /// <param name="target">Current target of the brush</param>
 /// <param name="settings">Current brush settings</param>
 internal virtual void OnBrushMove(BrushTarget target, BrushSettings settings)
 {
     UpdateTempComponent(target, settings);
 }
Пример #12
0
        // Called whenever the brush is moved.  Note that @target may have a null editableObject.
        internal override void OnBrushMove(BrushTarget target, BrushSettings settings)
        {
            base.OnBrushMove(target, settings);

            if (!Util.IsValid(target))
            {
                return;
            }

            bool invert = settings.isUserHoldingControl;

            PolyMesh mesh        = target.editableObject.editMesh;
            int      vertexCount = mesh.vertexCount;

            float[] weights = target.GetAllWeights();

            switch (paintMode)
            {
            case PaintMode.Flood:
                for (int i = 0; i < vertexCount; i++)
                {
                    m_MeshVertexColors.Colors[i] = invert? s_WhiteColor : m_MeshVertexColors.TargetColors[i];
                }
                break;

            case PaintMode.Fill:

                System.Array.Copy(m_MeshVertexColors.OriginalColors, m_MeshVertexColors.Colors, vertexCount);
                int[] indices = target.editableObject.editMesh.GetTriangles();
                int   index   = 0;

                foreach (PolyRaycastHit hit in target.raycastHits)
                {
                    if (hit.triangle > -1)
                    {
                        index = hit.triangle * 3;

                        m_MeshVertexColors.Colors[indices[index + 0]] = invert ? s_WhiteColor : m_MeshVertexColors.TargetColors[indices[index + 0]];
                        m_MeshVertexColors.Colors[indices[index + 1]] = invert ? s_WhiteColor : m_MeshVertexColors.TargetColors[indices[index + 1]];
                        m_MeshVertexColors.Colors[indices[index + 2]] = invert ? s_WhiteColor : m_MeshVertexColors.TargetColors[indices[index + 2]];

                        m_FillModeEdges[0].x = indices[index + 0];
                        m_FillModeEdges[0].y = indices[index + 1];

                        m_FillModeEdges[1].x = indices[index + 1];
                        m_FillModeEdges[1].y = indices[index + 2];

                        m_FillModeEdges[2].x = indices[index + 2];
                        m_FillModeEdges[2].y = indices[index + 0];

                        for (int i = 0; i < 3; i++)
                        {
                            if (m_TriangleLookup.TryGetValue(m_FillModeEdges[i], out m_FillModeAdjacentTriangles))
                            {
                                for (int n = 0; n < m_FillModeAdjacentTriangles.Count; n++)
                                {
                                    index = m_FillModeAdjacentTriangles[n] * 3;

                                    m_MeshVertexColors.Colors[indices[index + 0]] = invert ? s_WhiteColor : m_MeshVertexColors.TargetColors[indices[index + 0]];
                                    m_MeshVertexColors.Colors[indices[index + 1]] = invert ? s_WhiteColor : m_MeshVertexColors.TargetColors[indices[index + 1]];
                                    m_MeshVertexColors.Colors[indices[index + 2]] = invert ? s_WhiteColor : m_MeshVertexColors.TargetColors[indices[index + 2]];
                                }
                            }
                        }
                    }
                }

                break;

            default:
            {
                for (int i = 0; i < vertexCount; i++)
                {
                    m_MeshVertexColors.Colors[i] = Util.Lerp(m_MeshVertexColors.OriginalColors[i],
                                                             invert ? m_MeshVertexColors.EraseColors[i] : m_MeshVertexColors.TargetColors[i],
                                                             mask,
                                                             weights[i]);
                }

                break;
            }
            }

            target.editableObject.editMesh.colors = m_MeshVertexColors.Colors;
            target.editableObject.ApplyMeshAttributes(MeshChannel.Color);
        }
Пример #13
0
        internal override void OnBrushSettingsChanged(BrushTarget target, BrushSettings settings)
        {
            base.OnBrushSettingsChanged(target, settings);

            m_MeshVertexColors.RebuildColorTargets(m_BrushColor, settings.strength, mask);
        }
Пример #14
0
        void DrawBrushSettings()
        {
            EnsureBrushSettingsListIsValid();

            // Brush preset selector
            using (new GUILayout.VerticalScope("box"))
            {
                // Show the settings header in PolyEditor so that the preset selector can be included in the block.
                // Can't move preset selector to BrushSettingsEditor because it's a CustomEditor for BrushSettings,
                // along with other issues.
                if (PolyGUILayout.HeaderWithDocsLink(PolyGUI.TempContent("Brush Settings")))
                {
                    Application.OpenURL(PrefUtility.documentationBrushSettingsLink);
                }

                using (new GUILayout.HorizontalScope())
                {
                    EditorGUI.BeginChangeCheck();

                    m_CurrentBrushIndex = EditorGUILayout.Popup(m_CurrentBrushIndex, m_AvailableBrushesStrings);

                    if (EditorGUI.EndChangeCheck())
                    {
                        if (m_CurrentBrushIndex >= m_AvailableBrushes.Length)
                        {
                            SetBrushSettings(BrushSettingsEditor.AddNew(brushSettings));
                        }
                        else
                        {
                            SetBrushSettings(m_AvailableBrushes.ElementAt <BrushSettings>(m_CurrentBrushIndex));
                        }
                    }

                    if (GUILayout.Button(m_GCSaveBrushSettings, GUILayout.Width(50)))
                    {
                        if (brushSettings != null && brushSettingsAsset != null)
                        {
                            // integer 0, 1 or 2 corresponding to ok, cancel and alt buttons
                            int res = EditorUtility.DisplayDialogComplex("Save Brush Settings", "Overwrite brush preset, or Create a New brush preset? ", "Overwrite", "Create New", "Cancel");

                            if (res == 0)
                            {
                                brushSettings.CopyTo(brushSettingsAsset);
                                EditorGUIUtility.PingObject(brushSettingsAsset);
                            }
                            else if (res == 1)
                            {
                                BrushSettings dup = BrushSettingsEditor.AddNew(brushSettings);
                                SetBrushSettings(dup);
                                EditorGUIUtility.PingObject(brushSettingsAsset);
                            }

                            GUIUtility.ExitGUI();
                        }
                        else
                        {
                            Debug.LogWarning("Something went wrong saving brush settings.");
                        }
                    }
                }
                EditorGUI.BeginChangeCheck();

                brushEditor.OnInspectorGUI();
            }
        }
Пример #15
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 = SceneView.lastActiveSceneView.in2DMode ?
                                      Quaternion.FromToRotation(-Vector3.forward, target.transform.TransformDirection(rand_hit.normal)):
                                      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 (SceneView.lastActiveSceneView.in2DMode)
                {
                    inst.transform.position += Vector3.back * s_2DDepthOffset;
                }

                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);
            }
        }
Пример #16
0
 /// <summary>
 /// Called when a brush application has finished.  Use this to clean up temporary resources or apply
 /// deferred actions to a mesh (rebuild UV2, tangents, whatever).
 /// </summary>
 /// <param name="target">The Object the brush was being applied on</param>
 /// <param name="settings">Current brush settings</param>
 internal virtual void OnBrushFinishApply(BrushTarget target, BrushSettings settings)
 {
     DestroyTempComponent();
 }
Пример #17
0
        /// <summary>
        /// Draw gizmos taking into account handling of normal by smooth brush mode.
        /// </summary>
        /// <param name="target">Current target Object</param>
        ///// <param name="settings">Current brush settings</param>
        internal override void DrawGizmos(BrushTarget target, BrushSettings settings)
        {
            UpdateBrushGizmosColor();
            Vector3 normal = s_SmoothDirection.value.ToVector3();

            int      rayCount    = target.raycastHits.Count;
            PolyMesh mesh        = target.editableObject.editMesh;
            int      vertexCount = mesh.vertexCount;

            Vector3[] normals = (s_SmoothDirection == PolyDirection.BrushNormal) ? mesh.normals : null;

            // don't use target.GetAllWeights because brush normal needs
            // to know which ray to use for normal
            for (int ri = 0; ri < rayCount; ri++)
            {
                PolyRaycastHit hit = target.raycastHits[ri];

                if (hit.weights == null || hit.weights.Length < vertexCount)
                {
                    continue;
                }

                if (s_SmoothDirection == PolyDirection.BrushNormal)
                {
                    if (s_UseFirstNormalVector && brushNormalOnBeginApply.Count > ri)
                    {
                        normal = brushNormalOnBeginApply[ri];
                    }
                    else
                    {
                        // get the highest weighted vertex to use its direction computation
                        float highestWeight = .0001f;
                        int   highestIndex  = -1;
                        for (int i = 0; i < commonVertexCount; i++)
                        {
                            int index = commonVertices[i][0];
                            if (hit.weights[index] < .0001f || (s_IgnoreOpenEdges && nonManifoldIndices.Contains(index)))
                            {
                                continue;
                            }

                            if (hit.weights[index] > highestWeight)
                            {
                                highestIndex = index;
                            }
                        }

                        if (highestIndex != -1)
                        {
                            normal = Math.WeightedAverage(normals, neighborLookup[highestIndex], hit.weights).normalized;
                        }
                        else
                        {
                            normal = hit.normal;
                        }
                    }
                }
                else if (s_SmoothDirection == PolyDirection.VertexNormal)
                {
                    normal = hit.normal;
                }

                PolyHandles.DrawBrush(hit.position, normal, settings, target.localToWorldMatrix, innerColor, outerColor);
            }
        }
Пример #18
0
        /// <summary>
        /// Draw scene gizmos. Base implementation draws the brush preview.
        /// </summary>
        /// <param name="target">Current target Object</param>
        /// <param name="settings">Current brush settings</param>
        internal virtual void DrawGizmos(BrushTarget target, BrushSettings settings)
        {
            UpdateBrushGizmosColor();
            foreach (PolyRaycastHit hit in target.raycastHits)
            {
                PolyHandles.DrawBrush(hit.position, hit.normal, settings, target.localToWorldMatrix, innerColor, outerColor);
            }

#if Z_DEBUG
#if Z_DRAW_WEIGHTS || DRAW_PER_VERTEX_ATTRIBUTES
            float[] w = target.GetAllWeights();
#endif

#if Z_DRAW_WEIGHTS
            Mesh       m       = target.mesh;
            Vector3[]  v       = m.vertices;
            GUIContent content = new GUIContent("", "");

            Handles.BeginGUI();
            for (int i = 0; i < v.Length; i++)
            {
                if (w[i] < .0001f)
                {
                    continue;
                }

                content.text = w[i].ToString("F2");
                GUI.Label(HandleUtility.WorldPointToSizedRect(target.transform.TransformPoint(v[i]), content, EditorStyles.label), content);
            }
            Handles.EndGUI();
#endif

#if DRAW_PER_VERTEX_ATTRIBUTES
            Mesh           m        = target.editableObject.editMesh;
            Color32[]      colors   = m.colors;
            Vector4[]      tangents = m.tangents;
            List <Vector4> uv0      = m.uv0;
            List <Vector4> uv1      = m.uv1;
            List <Vector4> uv2      = m.uv2;
            List <Vector4> uv3      = m.uv3;

            int vertexCount = m.vertexCount;

            Vector3[]  verts = m.vertices;
            GUIContent gc    = new GUIContent("");

            List <List <int> >        common = MeshUtility.GetCommonVertices(m);
            System.Text.StringBuilder sb     = new System.Text.StringBuilder();

            Handles.BeginGUI();
            foreach (List <int> l in common)
            {
                if (w[l[0]] < .001)
                {
                    continue;
                }

                Vector3 v = target.transform.TransformPoint(verts[l[0]]);

                if (colors != null)
                {
                    sb.AppendLine("color: " + colors[l[0]].ToString("F2"));
                }
                if (tangents != null)
                {
                    sb.AppendLine("tangent: " + tangents[l[0]].ToString("F2"));
                }
                if (uv0 != null && uv0.Count == vertexCount)
                {
                    sb.AppendLine("uv0: " + uv0[l[0]].ToString("F2"));
                }
                if (uv1 != null && uv1.Count == vertexCount)
                {
                    sb.AppendLine("uv1: " + uv1[l[0]].ToString("F2"));
                }
                if (uv2 != null && uv2.Count == vertexCount)
                {
                    sb.AppendLine("uv2: " + uv2[l[0]].ToString("F2"));
                }
                if (uv3 != null && uv3.Count == vertexCount)
                {
                    sb.AppendLine("uv3: " + uv3[l[0]].ToString("F2"));
                }

                gc.text = sb.ToString();
                sb.Remove(0, sb.Length);                        // @todo .NET 4.0
                GUI.Label(HandleUtility.WorldPointToSizedRect(v, gc, EditorStyles.label), gc);
            }
            Handles.EndGUI();
#endif
#endif
        }
Пример #19
0
        /// <summary>
        /// Calculates the per-vertex weight for each raycast hit and fills in brush target weights.
        /// </summary>
        /// <param name="target"></param>
        /// <param name="settings"></param>
        /// <param name="tool"></param>
        /// <param name="bMode"></param>
        internal static void CalculateWeightedVertices(BrushTarget target, BrushSettings settings, BrushTool tool = BrushTool.None, BrushMode bMode = null)
        {
            //null checks
            if (target == null || settings == null)
            {
                return;
            }

            if (target.editableObject == null)
            {
                return;
            }

            bool  uniformScale = PolyMath.VectorIsUniform(target.transform.lossyScale);
            float scale        = uniformScale ? 1f / target.transform.lossyScale.x : 1f;

            PolyMesh mesh = target.editableObject.visualMesh;

            if (tool == BrushTool.Texture && mesh.subMeshCount > 1)
            {
                var   mode           = bMode as BrushModeTexture;
                int[] submeshIndices = mesh.subMeshes[mode.currentMeshACIndex].indexes;

                //List<List<int>> common = PolyMeshUtility.GetCommonVertices(mesh);

                Transform transform   = target.transform;
                int       vertexCount = mesh.vertexCount;
                Vector3[] vertices    = mesh.vertices;

                if (!uniformScale)
                {
                    Vector3[] world = new Vector3[vertexCount];
                    for (int i = 0; i < vertexCount; i++)
                    {
                        world[i] = transform.TransformPoint(vertices[i]);
                    }
                    vertices = world;
                }

                AnimationCurve curve = settings.falloffCurve;
                float          radius = settings.radius * scale, falloff_mag = Mathf.Max((radius - radius * settings.falloff), 0.00001f);

                Vector3        hitPosition = Vector3.zero;
                PolyRaycastHit hit;

                for (int n = 0; n < target.raycastHits.Count; n++)
                {
                    hit = target.raycastHits[n];
                    hit.SetVertexCount(vertexCount);

                    for (int i = 0; i < vertexCount; i++)
                    {
                        hit.weights[i] = 0f;
                    }

                    hitPosition = uniformScale ? hit.position : transform.TransformPoint(hit.position);

                    for (int i = 0; i < submeshIndices.Length; i++)
                    {
                        int   currentIndex = submeshIndices[i];
                        float dist         = (hitPosition - vertices[currentIndex]).magnitude;
                        float delta        = radius - dist;

                        if (delta >= 0)
                        {
                            float weight = Mathf.Clamp(curve.Evaluate(1f - Mathf.Clamp(delta / falloff_mag, 0f, 1f)), 0f, 1f);

                            hit.weights[currentIndex] = weight;
                        }
                    }
                }
            }
            else
            {
                List <List <int> > common = PolyMeshUtility.GetCommonVertices(mesh);

                Transform transform   = target.transform;
                int       vertexCount = mesh.vertexCount;
                Vector3[] vertices    = mesh.vertices;

                if (!uniformScale)
                {
                    Vector3[] world = new Vector3[vertexCount];
                    for (int i = 0; i < vertexCount; i++)
                    {
                        world[i] = transform.TransformPoint(vertices[i]);
                    }
                    vertices = world;
                }

                AnimationCurve curve = settings.falloffCurve;
                float          radius = settings.radius * scale, falloff_mag = Mathf.Max((radius - radius * settings.falloff), 0.00001f);

                Vector3        hitPosition = Vector3.zero;
                PolyRaycastHit hit;

                for (int n = 0; n < target.raycastHits.Count; n++)
                {
                    hit = target.raycastHits[n];
                    hit.SetVertexCount(vertexCount);

                    hitPosition = uniformScale ? hit.position : transform.TransformPoint(hit.position);

                    for (int i = 0; i < common.Count; i++)
                    {
                        int   commonArrayCount = common[i].Count;
                        float sqrDist          = (hitPosition - vertices[common[i][0]]).sqrMagnitude;

                        if (sqrDist > radius * radius)
                        {
                            for (int j = 0; j < commonArrayCount; j++)
                            {
                                hit.weights[common[i][j]] = 0f;
                            }
                        }
                        else
                        {
                            float weight = Mathf.Clamp(curve.Evaluate(1f - Mathf.Clamp((radius - Mathf.Sqrt(sqrDist)) / falloff_mag, 0f, 1f)), 0f, 1f);

                            for (int j = 0; j < commonArrayCount; j++)
                            {
                                hit.weights[common[i][j]] = weight;
                            }
                        }
                    }
                }
            }
            target.GetAllWeights(true);
        }
Пример #20
0
        // Inspector GUI shown in the Editor window.  Base class shows BrushSettings by default
        internal override void DrawGUI(BrushSettings brushSettings)
        {
            base.DrawGUI(brushSettings);

            using (new GUILayout.HorizontalScope())
            {
                GUILayout.FlexibleSpace();
                paintMode = (PaintMode)GUILayout.Toolbar((int)paintMode, m_ModeIcons, GUILayout.Width(130));
                GUILayout.FlexibleSpace();
            }

            GUILayout.Space(4);

            if (!m_LikelySupportsTextureBlending)
            {
                EditorGUILayout.HelpBox("It doesn't look like any of the materials on this object support texture blending!\n\nSee the readme for information on creating custom texture blend shaders.", MessageType.Warning);
            }

            // Selection dropdown for material (for submeshes)
            if (m_AvailableMaterialsAsString.Count() > 0)
            {
                EditorGUILayout.BeginHorizontal();
                EditorGUI.BeginChangeCheck();

                EditorGUILayout.LabelField("Material :", GUILayout.Width(60));
                currentMeshACIndex = EditorGUILayout.Popup(currentMeshACIndex, m_AvailableMaterialsAsString, "Popup");

                if (EditorGUI.EndChangeCheck())
                {
                    m_MeshAttributesContainer = m_MeshAttributesContainers[currentMeshACIndex];
                }

                EditorGUILayout.EndHorizontal();
            }

            GUILayout.Space(4);

            if (meshAttributes != null)
            {
                RefreshPreviewTextureCache();
                int prevSelectedAttributeIndex = m_SelectedAttributeIndex;
                m_SelectedAttributeIndex = SplatWeightEditor.OnInspectorGUI(m_SelectedAttributeIndex, ref brushColor, meshAttributes);
                if (prevSelectedAttributeIndex != m_SelectedAttributeIndex)
                {
                    SetBrushColorWithAttributeIndex(m_SelectedAttributeIndex);
                }

#if POLYBRUSH_DEBUG
                GUILayout.BeginHorizontal();

                GUILayout.FlexibleSpace();

                if (GUILayout.Button("MetaData", EditorStyles.miniButton))
                {
                    Debug.Log(meshAttributes.ToString("\n"));

                    string str = EditorUtility.FindPolybrushMetaDataForShader(meshAttributesContainer.shader);

                    if (!string.IsNullOrEmpty(str))
                    {
                        TextAsset asset = AssetDatabase.LoadAssetAtPath <TextAsset>(str);

                        if (asset != null)
                        {
                            EditorGUIUtility.PingObject(asset);
                        }
                        else
                        {
                            Debug.LogWarning("No MetaData found for Shader \"" + meshAttributesContainer.shader.name + "\"");
                        }
                    }
                    else
                    {
                        Debug.LogWarning("No MetaData found for Shader \"" + meshAttributesContainer.shader.name + "\"");
                    }
                }

                GUILayout.EndHorizontal();

                GUILayout.Space(4);

                if (GUILayout.Button("rebuild  targets"))
                {
                    RebuildColorTargets(brushColor, brushSettings.strength);
                }


                GUILayout.Label(brushColor != null ? brushColor.ToString() : "brush color: null\n");
#endif
            }
        }
Пример #21
0
 // Called when the mouse begins hovering an editable object.
 internal override void OnBrushEnter(EditableObject target, BrushSettings settings)
 {
     base.OnBrushEnter(target, settings);
 }
Пример #22
0
 internal override void OnBrushSettingsChanged(BrushTarget target, BrushSettings settings)
 {
     base.OnBrushSettingsChanged(target, settings);
     RebuildColorTargets(brushColor, settings.strength);
 }
Пример #23
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();
 }
 internal override void OnBrushBeginApply(BrushTarget brushTarget, BrushSettings brushSettings)
 {
     base.OnBrushBeginApply(brushTarget, brushSettings);
 }