#c_sharp #unity3d #вычислительная_геометрия
Здравствуйте! Собственно, реализую редактор поверхностей, основная проблема встала с расчётом "габаритов" кисточки, а точнее, поверхности в пространстве, попадающей под эту самую кисточку. Привожу максимально урезанный рабочий код сего действа: using System; using System.Collections.Generic; using UnityEngine; using UnityEditor; namespace EngineEditor.Terrain { ////// Режим редактирования /// public enum EEditorMode : int { ModeAdd = 0x00, // режим добавления ModeDelete = 0x01, // режим удаления ModePick = 0x02 // режим захвата }; public class Test : EditorWindow { private static Color designAddColor = new Color(0.15f, 1.0f, 0.15f); private static Color textColor = new Color(0.9f, 0.9f, 0.9f); private static float brushSize = 1.1f; private EEditorMode currentMode = EEditorMode.ModeAdd; private bool selectModeOn = false; [MenuItem("Test/Editor")] public static void ShowWindow() { EditorWindow window = EditorWindow.GetWindow(typeof(Test)); window.titleContent = new GUIContent("..."); } void OnGUI() { } void OnFocus() { SceneView.onSceneGUIDelegate -= this.OnSceneGUI; SceneView.onSceneGUIDelegate += this.OnSceneGUI; } void OnDestroy() { SceneView.onSceneGUIDelegate -= this.OnSceneGUI; } ////// Метод обрабатывающий задобренный объект /// /// /// Объект, до которого дотронулись лучи добра private void OnRaycast(SceneView sceneView, RaycastHit hitInfo) { Collider collider = hitInfo.collider; Vector3 cameraPoint = sceneView.camera.transform.position + sceneView.camera.transform.forward + sceneView.camera.transform.right; Quaternion startRot = Quaternion.LookRotation(hitInfo.normal); switch (currentMode) { case EEditorMode.ModeAdd: Handles.color = designAddColor; break; } Handles.DrawLine(hitInfo.point, cameraPoint); // рисуем кисточку Handles.CircleCap(0, hitInfo.point, startRot, brushSize); Handles.color = textColor; Handles.Label(collider.transform.position, new GUIContent(Utils.ToString(collider.transform.position)), EditorStyles.boldLabel); Handles.Label(hitInfo.point, new GUIContent("\n"+Utils.ToString(hitInfo.normal)+"\n"+Utils.ToString(hitInfo.barycentricCoordinate))); Handles.Label(hitInfo.point, Utils.ToString(startRot)); sceneView.Repaint(); } ////// Отрисовка в окне сцены /// /// public void OnSceneGUI(SceneView sceneView) { Selection.activeObject = null; Vector3 mousePosition = new Vector3(Event.current.mousePosition.x, sceneView.camera.pixelHeight - Event.current.mousePosition.y, 0); RaycastHit hitInfo = new RaycastHit(); Ray ray = sceneView.camera.ScreenPointToRay(mousePosition); // генерируем луч добра if (Physics.Raycast(ray, out hitInfo)) // одобряем всё и вся нашим лучом OnRaycast(sceneView, hitInfo); } } } Покажу схематично саму кисточку: Собственно, что я знаю: Известна середина фигуры point{x,y,z} Известны углы этой фигуры rect{x,y,z} и вращение quaternion{x,y,z,w} Известен размер кисти (в данном случае - сторона квадрата) Сам вопрос: Каким образом я могу вычислить координаты v1,v2,v3,v4, чтобы провести линии от point до v1, от point до v2, от point до v3, от point до v4? Если получится их вычислить, решиться проблема с обнаружением поверхности под кисточкой (обычными вычитаниями). Возможно ли, что я не правильно подхожу к задаче, и данные точки можно не вычислять, а каким то чудесным образом получить единичные вектора direction из центра к каждой из этих точек?
Ответы
Ответ 1
VladD Хм. А почему не так: вектор MV1 = quaternion * (-d/2, 0, 0), отсюда V1 = M + MV1 (M — центр, d — сторона). – VladD 4 мин. назад Дал самое простое и понятное решение! Огромное спасибо, я просто не знал что в unity перегружены операции кватернионов с векторами (facepalm), пинать меня за это надо. Ещё раз Спасибо!
Комментариев нет:
Отправить комментарий