private void DrawPaintModeScene() { if(_selectedAttributesStore == null || _selectedAttributeData == null) { // Nothing to do if no attribute selected return; } if(!_selectedAttributesStore.HasMeshForPainting()) { // Painting requires a mesh so nothing to do return; } if (!_mouseWithinSceneView) { return; } float brushRadius = GetBrushRadius(); // TODO: use Handles.DrawingScope Color originalHandleColor = Handles.color; Color newHandleColor = originalHandleColor; SerializedProperty handleColorProperty = HEU_EditorUtility.GetSerializedProperty(_toolsInfoSerializedObject, "_brushHandleColor"); if(handleColorProperty != null) { newHandleColor = handleColorProperty.colorValue; } HEU_ToolsInfo.PaintMergeMode paintMergeMode = HEU_ToolsInfo.PaintMergeMode.REPLACE; SerializedProperty paintMergeProperty = HEU_EditorUtility.GetSerializedProperty(_toolsInfoSerializedObject, "_paintMergeMode"); if (paintMergeProperty != null) { paintMergeMode = (HEU_ToolsInfo.PaintMergeMode)paintMergeProperty.intValue; } SerializedProperty isPaintingProperty = HEU_EditorUtility.GetSerializedProperty(_toolsInfoSerializedObject, "_isPainting"); // Enable the mesh collider so that we can raycast to paint using brush MeshCollider collider = _selectedAttributesStore.GetPaintMeshCollider(); if (collider != null) { Ray ray = _currentCamera.ScreenPointToRay(_mousePosition); ray.origin = _currentCamera.transform.position; RaycastHit hit; if (collider.Raycast(ray, out hit, _intersectionRayLength)) { if (_currentEvent.type == EventType.ScrollWheel && _currentEvent.shift) { // Brush resize brushRadius -= _currentEvent.delta.y * _mouseWheelBrushSizeMultiplier; brushRadius = UpdateBrushSize(brushRadius); _GUIChanged = true; _currentEvent.Use(); } else if (_currentEvent.type == EventType.MouseDrag && _currentEvent.shift) { // Brush resize brushRadius += _currentEvent.delta.x * _mouseWheelBrushSizeMultiplier; brushRadius = UpdateBrushSize(brushRadius); _GUIChanged = true; _currentEvent.Use(); } else if (_currentEvent.button == 0 && !_currentEvent.shift && !_currentEvent.alt && !_currentEvent.control && !_mouseOverInfoPanel) { // Painting if (_currentEvent.type == EventType.MouseDown && !isPaintingProperty.boolValue) { PaintingStarted(isPaintingProperty); } if (isPaintingProperty.boolValue) { if(_currentEvent.type == EventType.MouseDown || _currentEvent.type == EventType.MouseDrag) { HandlePaintEvent(hit, brushRadius, paintMergeMode); _currentEvent.Use(); } } } if (!_mouseOverInfoPanel) { Handles.color = newHandleColor; Vector3 endPt = hit.point + (Vector3.Normalize(hit.normal) * brushRadius); Handles.DrawAAPolyLine(2f, new Vector3[] { hit.point, endPt }); HEU_EditorUI.DrawCircleCap(_controlID, hit.point, Quaternion.FromToRotation(Vector3.forward, hit.normal), brushRadius); } } } switch (_currentEvent.type) { case EventType.MouseDown: { // Don't use event here as it will ignore mouse camera controls break; } case EventType.MouseUp: { if (_currentEvent.button == 0) { if(!_currentEvent.shift && !_currentEvent.alt && !_currentEvent.control) { if (isPaintingProperty != null && isPaintingProperty.boolValue) { _currentEvent.Use(); } PaintingFinished(isPaintingProperty); } } break; } case EventType.MouseMove: { // Use the mouse move event will force a repaint allowing for much more responsive UI _currentEvent.Use(); break; } case EventType.Layout: { // This disables deselection on asset while in Edit mode HandleUtility.AddDefaultControl(_controlID); break; } case EventType.Repaint: { break; } } Handles.color = originalHandleColor; }
public static SetAttributeValueFunc GetAttributeSetValueFunction(HEU_AttributeData.AttributeType attrType, HEU_ToolsInfo.PaintMergeMode paintMergeMode) { SetAttributeValueFunc setAttrFunc = null; if (attrType == HEU_AttributeData.AttributeType.INT) { if (paintMergeMode == HEU_ToolsInfo.PaintMergeMode.REPLACE) { setAttrFunc = HEU_AttributesStore.ReplaceAttributeValueInt; } else if (paintMergeMode == HEU_ToolsInfo.PaintMergeMode.ADD) { setAttrFunc = HEU_AttributesStore.AddAttributeValueInt; } else if (paintMergeMode == HEU_ToolsInfo.PaintMergeMode.SUBTRACT) { setAttrFunc = HEU_AttributesStore.SubtractAttributeValueInt; } else if (paintMergeMode == HEU_ToolsInfo.PaintMergeMode.MULTIPLY) { setAttrFunc = HEU_AttributesStore.MultiplyAttributeValueInt; } } else if (attrType == HEU_AttributeData.AttributeType.FLOAT) { if (paintMergeMode == HEU_ToolsInfo.PaintMergeMode.REPLACE) { setAttrFunc = HEU_AttributesStore.ReplaceAttributeValueFloat; } else if (paintMergeMode == HEU_ToolsInfo.PaintMergeMode.ADD) { setAttrFunc = HEU_AttributesStore.AddAttributeValueFloat; } else if (paintMergeMode == HEU_ToolsInfo.PaintMergeMode.SUBTRACT) { setAttrFunc = HEU_AttributesStore.SubtractAttributeValueFloat; } else if (paintMergeMode == HEU_ToolsInfo.PaintMergeMode.MULTIPLY) { setAttrFunc = HEU_AttributesStore.MultiplyAttributeValueFloat; } } else if (attrType == HEU_AttributeData.AttributeType.STRING) { setAttrFunc = HEU_AttributesStore.SetAttributeValueString; } return setAttrFunc; }
private void HandlePaintEvent(RaycastHit hit, float brushRadius, HEU_ToolsInfo.PaintMergeMode paintMergeMode) { if(_selectedAttributesStore == null || _selectedAttributeData == null) { return; } HEU_AttributesStore.SetAttributeValueFunc setAttrFunc = HEU_AttributesStore.GetAttributeSetValueFunction(_selectedAttributeData._attributeType, paintMergeMode); if(setAttrFunc == null) { return; } Vector3[] positionArray = new Vector3[0]; _selectedAttributesStore.GetPositionAttributeValues(out positionArray); int[] indices = new int[0]; _selectedAttributesStore.GetVertexIndices(out indices); int numPositions = positionArray.Length; if (positionArray != null && numPositions > 0 && indices != null && indices.Length > 0) { Vector3 localHitPoint = _selectedAttributesStore.OutputTransform.InverseTransformPoint(hit.point); Mesh mesh = _selectedAttributesStore.OutputMesh; Color[] colors = mesh.colors; for (int posIndex = 0; posIndex < numPositions; ++posIndex) { float distance = Vector3.Distance(localHitPoint, positionArray[posIndex]); if (distance <= brushRadius) { float paintFactor = Mathf.Abs((brushRadius - distance) / brushRadius) * _toolsInfo._paintBrushOpacity; // Update the attribute _selectedAttributesStore.PaintAttribute(_selectedAttributeData, _toolsInfo, posIndex, paintFactor, setAttrFunc); // Get the paint color Color paintColor = _toolsInfo._affectedAreaPaintColor; if (_selectedAttributeData.IsColorAttribute()) { if (_selectedAttributeData._attributeInfo.tupleSize >= 3 && _toolsInfo._paintFloatValue.Length >= 3) { paintColor.r = _toolsInfo._paintFloatValue[0]; paintColor.g = _toolsInfo._paintFloatValue[1]; paintColor.b = _toolsInfo._paintFloatValue[2]; if (_selectedAttributeData._attributeInfo.tupleSize >= 4 && _toolsInfo._paintFloatValue.Length >= 4) { paintColor.a = _toolsInfo._paintFloatValue[3]; } } } // Update local temporary mesh to show area of effect. // The position index, a point attribute, must be mapped to the vertex color, // which is a vertex attribute, via the vertex index int numIndices = indices.Length; for(int i = 0; i < numIndices; ++i) { if(indices[i] == posIndex && i < colors.Length) { colors[i] = Color.Lerp(colors[i], paintColor, paintFactor); } } } } mesh.colors = colors; } }