public void OnSceneGUI() { VolumeGrass _target = (VolumeGrass)target; int i; EditorWindow currentWindow = EditorWindow.mouseOverWindow; if (currentWindow) { //Rect winRect = currentWindow.position; Event current = Event.current; switch (current.type) { case EventType.keyDown: if (current.keyCode == KeyCode.M) { _target.paint_height = !_target.paint_height; EditorUtility.SetDirty(_target); } break; } if (_target.state == 1) { if (_target.paint_height) { if (current.alt) { return; } if (current.control) { if (current.type == EventType.mouseMove) { if (control_down_flag) { control_down_flag = false; EditorUtility.SetDirty(_target); } } return; } control_down_flag = true; switch (current.type) { case EventType.mouseDown: get_paint_coverage(); cover_verts_num_start_drag = cover_verts_num; if (cover_verts_num > 0) { Undo.RegisterSceneUndo("grass edit (height)"); _target.modify_height(cover_verts_num, cover_indices, cover_strength, current.shift); current.Use(); } else { _target.undo_flag = true; } break; case EventType.mouseDrag: get_paint_coverage(); if (cover_verts_num > 0) { if (_target.undo_flag) { Undo.RegisterSceneUndo("grass edit (height)"); _target.undo_flag = false; } } if (cover_verts_num_start_drag > 0) { _target.modify_height(cover_verts_num, cover_indices, cover_strength, current.shift); current.Use(); } break; case EventType.mouseMove: get_paint_coverage(); break; } if (current.shift) { for (i = 0; i < cover_verts_num; i++) { Handles.color = new Color(0, 1, 0, cover_strength[i]); //Handles.ArrowCap(0, cover_verts[i], cover_norms[i], 5*cover_strength[i]); Handles.DrawSolidDisc(cover_verts[i], Camera.current.transform.position - cover_verts[i], HandleUtility.GetHandleSize(cover_verts[i]) * 0.03f); } } else { Handles.color = Color.red; for (i = 0; i < cover_verts_num; i++) { Handles.color = new Color(1, 0, 0, cover_strength[i]); //Handles.ArrowCap(0, cover_verts[i], cover_norms_flip[i], 5*cover_strength[i]); Handles.DrawSolidDisc(cover_verts[i], Camera.current.transform.position - cover_verts[i], HandleUtility.GetHandleSize(cover_verts[i]) * 0.03f); } } return; } } switch (current.type) { case EventType.keyDown: if (current.keyCode == KeyCode.Delete) { if ((_target.state == 0) || (_target.which_active == 3)) { if (_target.active_idx >= 0) { Undo.RegisterUndo(new Object[2] { _target, _target.transform }, "grass edit"); _target.DeleteActiveControlPoint(); current.Use(); } } else { if (_target.active_idx >= 0) { current.Use(); if (_target.which_active == 0) { EditorUtility.DisplayDialog("Info", "Deleting nodes in Edit mode only ", "Proceed", ""); } } } } else if (current.keyCode == KeyCode.Return) { if (_target.state == 1) { // rebuild current.Use(); if (!_target.BuildMesh()) { EditorUtility.DisplayDialog("Error...", "Can't build mesh ", "Proceed", ""); } } } break; case EventType.keyUp: // current.Use(); break; case EventType.mouseDown: //Debug.Log(current +" "+controlID); float dist; float min_dist; _target.active_idx = -1; _target.which_active = 0; // pressing control points min_dist = 12f; // promień kliku w obrębie którego "łapiemy" pkt kontrolny for (i = 0; i < _target.control_points.Count; i++) { dist = Vector2.Distance(current.mousePosition, HandleUtility.WorldToGUIPoint(T_lw(_target.control_points[i]))); if (dist < min_dist) { min_dist = dist; _target.active_idx = i; } } if (_target.state == 0) // zaznaczanie pktów beziera tylko w trybie edycji (w rybie build i tak są niewidoczne) // pressing bezierA points { min_dist = 5f; // kółko bezier handla jest mniejsze niż control point for (i = 0; i < _target.control_points.Count; i++) { // pkt beziera traktujemy jako "aktywny" jeśli jest choć trochę oddalony od control_pointa if (Vector2.Distance(HandleUtility.WorldToGUIPoint(T_lw(_target.control_points[i])), HandleUtility.WorldToGUIPoint(T_lw(_target.bezier_pointsA[i]))) > 0.01f) { dist = Vector2.Distance(current.mousePosition, HandleUtility.WorldToGUIPoint(T_lw(_target.bezier_pointsA[i]))); if (dist < min_dist) { min_dist = dist; _target.which_active = 1; _target.active_idx = i; } } } // pressing bezierB points min_dist = 5f; // kółko bezier handla jest mniejsze niż control point for (i = 0; i < _target.control_points.Count; i++) { // pkt beziera traktujemy jako "aktywny" jeśli jest choć trochę oddalony od control_pointa if (Vector2.Distance(HandleUtility.WorldToGUIPoint(T_lw(_target.control_points[i])), HandleUtility.WorldToGUIPoint(T_lw(_target.bezier_pointsB[i]))) > 0.01f) { dist = Vector2.Distance(current.mousePosition, HandleUtility.WorldToGUIPoint(T_lw(_target.bezier_pointsB[i]))); if (dist < min_dist) { min_dist = dist; _target.which_active = 2; _target.active_idx = i; } } } } // pressing tesselation points if ((_target.state == 0) || (_target.show_tesselation_points)) { min_dist = 8f; // kółko tesselation handla jest mniejsze niż control point for (i = 0; i < _target.tesselation_points.Count; i++) { dist = Vector2.Distance(current.mousePosition, HandleUtility.WorldToGUIPoint(T_lw(_target.tesselation_points[i]))); if (dist < min_dist) { min_dist = dist; _target.which_active = 3; _target.active_idx = i; } } } if ((_target.state == 0) && current.shift && (!current.alt) && (_target.active_idx == -1) && (_target.which_active == 0)) { // dodawanie pktów kontrolnych Vector3 insert_pos = new Vector3(0, 0, 0); int insert_idx = -1; _target.GetInsertPos(current.mousePosition, ref insert_pos, ref insert_idx); if (insert_idx < 0) { // add point Undo.RegisterUndo(new Object[2] { _target, _target.transform }, "grass edit"); _target.AddControlPoint(GetWorldPointFromMouse(_target.ground_layerMask), -1); } else { // insert point Undo.RegisterUndo(new Object[2] { _target, _target.transform }, "grass edit"); _target.AddControlPoint(insert_pos, insert_idx); } current.Use(); } else if (current.shift && current.alt && (_target.active_idx == -1) && (_target.which_active == 0) && ((_target.state == 0) || (_target.show_tesselation_points))) { // dodawanie pktów tesselacji Undo.RegisterUndo(new Object[2] { _target, _target.transform }, "grass edit"); _target.AddTesselationPoint(GetWorldPointFromMouse(_target.ground_layerMask)); current.Use(); } else if ((_target.state == 0) && (_target.active_idx >= 0) && (_target.which_active == 0) && (current.alt)) { // dodawanie pktów beziera if (Vector2.Distance(HandleUtility.WorldToGUIPoint(T_lw(_target.control_points[_target.active_idx])), HandleUtility.WorldToGUIPoint(T_lw(_target.bezier_pointsA[_target.active_idx]))) < 0.01f) { // wstawienie bezier_pointA //_target.which_active=1; Vector3 dir_vec = _target.control_points[(_target.active_idx + 1) % _target.control_points.Count] - _target.control_points[_target.active_idx]; dir_vec += 1.5f * (_target.control_points[(_target.active_idx + _target.control_points.Count - 1) % _target.control_points.Count] - _target.control_points[_target.active_idx]); if (dir_vec.magnitude < 0.01f) { dir_vec = Vector3.right; } else if (dir_vec.magnitude > 5) { dir_vec.Normalize(); dir_vec *= 5; } _target.bezier_pointsA[_target.active_idx] -= dir_vec; } else if (Vector2.Distance(HandleUtility.WorldToGUIPoint(T_lw(_target.control_points[_target.active_idx])), HandleUtility.WorldToGUIPoint(T_lw(_target.bezier_pointsB[_target.active_idx]))) < 0.01f) { // wstawienie bezier_pointB //_target.which_active=2; Vector3 dir_vec = _target.control_points[(_target.active_idx + _target.control_points.Count - 1) % _target.control_points.Count] - _target.control_points[_target.active_idx]; dir_vec += 1.5f * (_target.control_points[(_target.active_idx + 1) % _target.control_points.Count] - _target.control_points[_target.active_idx]); if (dir_vec.magnitude < 0.01f) { dir_vec = Vector3.right; } else if (dir_vec.magnitude > 5) { dir_vec.Normalize(); dir_vec *= 5; } _target.bezier_pointsB[_target.active_idx] -= dir_vec; } //current.Use(); } // if ((prev_target_active_idx!=_target.active_idx) || (prev_target_which_active!=_target.which_active)) { // Undo.RegisterUndo(new Object[2]{_target, _target.transform}, "grass edit"); // } _target.undo_flag = false; //current.Use(); break; // case EventType.mouseMove: // break; case EventType.mouseDrag: //current.Use(); break; case EventType.mouseUp: //current.Use(); break; case EventType.layout: // HandleUtility.AddDefaultControl(controlID); break; } } // Node Numbers if (_target.showNodeNumbers) { for (i = 0; i < _target.control_points.Count; i++) { Handles.Label(T_lw(_target.control_points[i]), " " + i); } } // tesselation points labels if ((_target.state == 0) || (_target.show_tesselation_points)) { for (i = 0; i < _target.tesselation_points.Count; i++) { Handles.Label(T_lw(_target.tesselation_points[i]), " tp"); } } // control_points for (i = 0; i < _target.control_points.Count; i++) { Vector3 vec = Handles.FreeMoveHandle(T_lw(_target.control_points[i]), Quaternion.identity, HandleUtility.GetHandleSize(T_lw(_target.control_points[i])) * 0.08f, Vector3.one, Handles.RectangleCap); if ((_target.state == 0) && (Vector3.Distance(vec, T_lw(_target.control_points[i])) > 0)) { if (!_target.undo_flag) { Undo.RegisterUndo(new Object[2] { _target, _target.transform }, "grass edit"); _target.undo_flag = true; } Vector3 delta_bezierA = T_lw(_target.bezier_pointsA[i]) - T_lw(_target.control_points[i]); Vector3 delta_bezierB = T_lw(_target.bezier_pointsB[i]) - T_lw(_target.control_points[i]); if (_target.snap_on_move) { _target.control_points[i] = T_wl(GetWorldPointFromMouse(_target.ground_layerMask)); } else { _target.control_points[i] = T_wl(vec); } _target.bezier_pointsA[i] = T_wl(T_lw(_target.control_points[i]) + delta_bezierA); _target.bezier_pointsB[i] = T_wl(T_lw(_target.control_points[i]) + delta_bezierB); } } Handles.color = Color.gray; // tesselation point handles if ((_target.state == 0) || (_target.show_tesselation_points)) { for (i = 0; i < _target.tesselation_points.Count; i++) { Vector3 vec = Handles.FreeMoveHandle(T_lw(_target.tesselation_points[i]), Quaternion.identity, HandleUtility.GetHandleSize(T_lw(_target.tesselation_points[i])) * 0.06f, Vector3.one, Handles.CircleCap); if (Vector3.Distance(vec, T_lw(_target.tesselation_points[i])) > 0) { if (!_target.undo_flag) { Undo.RegisterUndo(new Object[2] { _target, _target.transform }, "grass edit"); _target.undo_flag = true; } if (_target.snap_on_move) { _target.tesselation_points[i] = T_wl(GetWorldPointFromMouse(_target.ground_layerMask)); } else { _target.tesselation_points[i] = T_wl(vec); } } } } // custom UV grid bounds handles if (_target.custom_UV_bounds) { Vector3 handle_pos, vec; // minx handle_pos = new Vector3(_target.custom_minx, _target.transform.position.y, 0.5f * (_target.custom_minz + _target.custom_maxz)); vec = Handles.FreeMoveHandle(handle_pos, Quaternion.identity, HandleUtility.GetHandleSize(handle_pos) * 0.04f, Vector3.one, Handles.DotCap); if (Mathf.Abs(vec.x - handle_pos.x) > 0) { if (!_target.undo_flag) { Undo.RegisterUndo(_target, "grass edit"); _target.undo_flag = true; } if (vec.x > _target.minx) { vec.x = _target.minx; } _target.custom_minx = vec.x; } // maxx handle_pos = new Vector3(_target.custom_maxx, _target.transform.position.y, 0.5f * (_target.custom_minz + _target.custom_maxz)); vec = Handles.FreeMoveHandle(handle_pos, Quaternion.identity, HandleUtility.GetHandleSize(handle_pos) * 0.04f, Vector3.one, Handles.DotCap); if (Mathf.Abs(vec.x - handle_pos.x) > 0) { if (!_target.undo_flag) { Undo.RegisterUndo(_target, "grass edit"); _target.undo_flag = true; } if (vec.x < _target.maxx + 0.1f) { vec.x = _target.maxx + 0.1f; } _target.custom_maxx = vec.x; } // minz handle_pos = new Vector3(0.5f * (_target.custom_minx + _target.custom_maxx), _target.transform.position.y, _target.custom_minz); vec = Handles.FreeMoveHandle(handle_pos, Quaternion.identity, HandleUtility.GetHandleSize(handle_pos) * 0.04f, Vector3.one, Handles.DotCap); if (Mathf.Abs(vec.z - handle_pos.z) > 0) { if (!_target.undo_flag) { Undo.RegisterUndo(_target, "grass edit"); _target.undo_flag = true; } if (vec.z > _target.minz) { vec.z = _target.minz; } _target.custom_minz = vec.z; } // maxz handle_pos = new Vector3(0.5f * (_target.custom_minx + _target.custom_maxx), _target.transform.position.y, _target.custom_maxz); vec = Handles.FreeMoveHandle(handle_pos, Quaternion.identity, HandleUtility.GetHandleSize(handle_pos) * 0.04f, Vector3.one, Handles.DotCap); if (Mathf.Abs(vec.z - handle_pos.z) > 0) { if (!_target.undo_flag) { Undo.RegisterUndo(_target, "grass edit"); _target.undo_flag = true; } if (vec.z < _target.maxz + 0.1f) { vec.z = _target.maxz + 0.1f; } _target.custom_maxz = vec.z; } } if (_target.state == 0) { if (_target.which_active != 3) { // bezier handle A for (i = 0; i < _target.control_points.Count; i++) { if ((_target.active_idx == i) && ((_target.which_active == 1) || (Vector3.Distance(T_lw(_target.control_points[i]), T_lw(_target.bezier_pointsA[i])) > 0.01f))) { Vector3 vec = Handles.FreeMoveHandle(T_lw(_target.bezier_pointsA[i]), Quaternion.identity, HandleUtility.GetHandleSize(T_lw(_target.bezier_pointsA[i])) * 0.05f, Vector3.one, Handles.CircleCap); if (Vector3.Distance(vec, T_lw(_target.bezier_pointsA[i])) > 0) { if (!_target.undo_flag) { Undo.RegisterUndo(new Object[2] { _target, _target.transform }, "grass edit"); _target.undo_flag = true; } if (_target.snap_on_move) { _target.bezier_pointsA[i] = T_wl(GetWorldPointFromMouse(_target.ground_layerMask)); } else { _target.bezier_pointsA[i] = T_wl(vec); } } Handles.DrawLine(T_lw(_target.control_points[i]), T_lw(_target.bezier_pointsA[i])); } } // bezier handle B for (i = 0; i < _target.control_points.Count; i++) { if ((_target.active_idx == i) && ((_target.which_active == 2) || (Vector3.Distance(T_lw(_target.control_points[i]), T_lw(_target.bezier_pointsB[i])) > 0.01f))) { Vector3 vec = Handles.FreeMoveHandle(T_lw(_target.bezier_pointsB[i]), Quaternion.identity, HandleUtility.GetHandleSize(T_lw(_target.bezier_pointsB[i])) * 0.05f, Vector3.one, Handles.CircleCap); if (Vector3.Distance(vec, T_lw(_target.bezier_pointsB[i])) > 0) { if (!_target.undo_flag) { Undo.RegisterUndo(new Object[2] { _target, _target.transform }, "grass edit"); _target.undo_flag = true; } if (_target.snap_on_move) { _target.bezier_pointsB[i] = T_wl(GetWorldPointFromMouse(_target.ground_layerMask)); } else { _target.bezier_pointsB[i] = T_wl(vec); } } Handles.DrawLine(T_lw(_target.control_points[i]), T_lw(_target.bezier_pointsB[i])); } } } } }