55import com .jme3 .bounding .BoundingBox ;
66import com .jme3 .bounding .BoundingSphere ;
77import com .jme3 .bounding .BoundingVolume ;
8+ import com .jme3 .collision .CollisionResult ;
9+ import com .jme3 .collision .CollisionResults ;
810import com .jme3 .effect .ParticleEmitter ;
911import com .jme3 .environment .generation .JobProgressAdapter ;
1012import com .jme3 .input .ChaseCamera ;
13+ import com .jme3 .input .InputManager ;
14+ import com .jme3 .input .MouseInput ;
15+ import com .jme3 .input .controls .ActionListener ;
16+ import com .jme3 .input .controls .MouseButtonTrigger ;
1117import com .jme3 .light .DirectionalLight ;
1218import com .jme3 .light .LightProbe ;
1319import com .jme3 .material .Material ;
1420import com .jme3 .math .ColorRGBA ;
21+ import com .jme3 .math .Ray ;
22+ import com .jme3 .math .Vector2f ;
23+ import com .jme3 .math .Vector3f ;
24+ import com .jme3 .renderer .Camera ;
1525import com .jme3 .scene .Geometry ;
1626import com .jme3 .scene .Mesh ;
1727import com .jme3 .scene .Node ;
2030import com .jme3 .scene .debug .WireBox ;
2131import com .jme3 .scene .debug .WireSphere ;
2232import com .ss .editor .state .editor .impl .AbstractEditorState ;
33+ import com .ss .editor .ui .component .editor .impl .model .ModelFileEditor ;
2334
2435import rlib .geom .util .AngleUtils ;
2536
@@ -46,6 +57,16 @@ public void done(final LightProbe result) {
4657 }
4758 };
4859
60+ /**
61+ * Слушатель кликов мышкой по области редактора.
62+ */
63+ private final ActionListener actionListener = (name , isPressed , tpf ) -> processClick (isPressed );
64+
65+ /**
66+ * Редактор в который встроен этот стейт.
67+ */
68+ private final ModelFileEditor editor ;
69+
4970 /**
5071 * Узел для размещения модели.
5172 */
@@ -111,7 +132,8 @@ public void done(final LightProbe result) {
111132 */
112133 private int frame ;
113134
114- public ModelEditorState () {
135+ public ModelEditorState (final ModelFileEditor editor ) {
136+ this .editor = editor ;
115137 this .modelNode = new Node ("ModelNode" );
116138 this .modelNode .setUserData (ModelEditorState .class .getName (), true );
117139 this .toolNode = new Node ("ToolNode" );
@@ -130,6 +152,62 @@ public ModelEditorState() {
130152 setShowGrid (true );
131153 }
132154
155+ /**
156+ * @return слушатель кликов мышкой по области редактора.
157+ */
158+ private ActionListener getActionListener () {
159+ return actionListener ;
160+ }
161+
162+ /**
163+ * Обработка клика мышкой по области редактора.
164+ */
165+ private void processClick (final boolean isPressed ) {
166+
167+ if (!isPressed ) {
168+ return ;
169+ }
170+
171+ final Camera camera = EDITOR .getCamera ();
172+
173+ final InputManager inputManager = EDITOR .getInputManager ();
174+ final Vector2f cursor = inputManager .getCursorPosition ();
175+ final Vector3f click3d = camera .getWorldCoordinates (cursor , 0f );
176+ final Vector3f dir = camera .getWorldCoordinates (cursor , 1f ).subtractLocal (click3d ).normalizeLocal ();
177+
178+ final Ray ray = new Ray ();
179+ ray .setOrigin (click3d );
180+ ray .setDirection (dir );
181+
182+ final CollisionResults results = new CollisionResults ();
183+
184+ final Node modelNode = getModelNode ();
185+ modelNode .collideWith (ray , results );
186+
187+ final ModelFileEditor editor = getEditor ();
188+
189+ if (results .size () < 1 ) {
190+ EXECUTOR_MANAGER .addFXTask (() -> editor .notifySelected (null ));
191+ return ;
192+ }
193+
194+ final CollisionResult collision = results .getClosestCollision ();
195+
196+ if (collision == null ) {
197+ EXECUTOR_MANAGER .addFXTask (() -> editor .notifySelected (null ));
198+ return ;
199+ }
200+
201+ EXECUTOR_MANAGER .addFXTask (() -> editor .notifySelected (collision .getGeometry ()));
202+ }
203+
204+ /**
205+ * @return редактор в который встроен этот стейт.
206+ */
207+ private ModelFileEditor getEditor () {
208+ return editor ;
209+ }
210+
133211 /**
134212 * Создание вспомогательных элементов.
135213 */
@@ -264,6 +342,16 @@ public void initialize(final AppStateManager stateManager, final Application app
264342 super .initialize (stateManager , application );
265343
266344 frame = 0 ;
345+
346+ final String mappingName = getClass ().getName () + "_click" ;
347+
348+ final InputManager inputManager = EDITOR .getInputManager ();
349+
350+ if (!inputManager .hasMapping (mappingName )) {
351+ inputManager .addMapping (mappingName , new MouseButtonTrigger (MouseInput .BUTTON_LEFT ));
352+ }
353+
354+ inputManager .addListener (getActionListener (), mappingName );
267355 }
268356
269357 @ Override
@@ -273,6 +361,9 @@ public void cleanup() {
273361 final Node stateNode = getStateNode ();
274362 stateNode .detachChild (getModelNode ());
275363 stateNode .detachChild (getToolNode ());
364+
365+ final InputManager inputManager = EDITOR .getInputManager ();
366+ inputManager .removeListener (getActionListener ());
276367 }
277368
278369 @ Override
0 commit comments