From fba343da207534600f56cce02105201ffe46cb3c Mon Sep 17 00:00:00 2001 From: yyc <395976266@qq.com> Date: Sat, 9 Feb 2019 13:20:51 +0800 Subject: [PATCH] feat(scene-view): "transform gizmo": add "switch world coordinate system" ui --- public/css/index.css | 39 ++++++----- .../components/controller/_controller.scss | 46 ++++++++----- .../TransformGizmoCoordinateSystemSwitch.re | 53 +++++++++++++++ ...ransformGizmoCoordinateSystemSwitchType.re | 10 +++ .../controller/ui/Controller.re | 37 +++++++++-- src/core/job/loop/UpdateTransformGizmosJob.re | 44 +++---------- .../CoordinateSystemTransformGizmosUtils.re | 64 +++++++++++++++++++ src/core/utils/ui/StoreUtils.re | 9 +-- 8 files changed, 226 insertions(+), 76 deletions(-) create mode 100644 src/core/composable_component/controller/atom_component/transformGizmo/ui/TransformGizmoCoordinateSystemSwitch.re create mode 100644 src/core/composable_component/controller/atom_component/transformGizmo/ui/TransformGizmoCoordinateSystemSwitchType.re create mode 100644 src/core/utils/engine/job/init/initTransformGizmosJob/CoordinateSystemTransformGizmosUtils.re diff --git a/public/css/index.css b/public/css/index.css index 5cded7345..8c109f860 100755 --- a/public/css/index.css +++ b/public/css/index.css @@ -400,27 +400,36 @@ html, body { align-items: center; height: 100%; flex-direction: row; } - .wonder-app-component .wonder-controller-component .header-controller .controller-transform .header-item .transform-gizmo-switch { + .wonder-app-component .wonder-controller-component .header-controller .controller-transform .header-item .component-item { flex: initial; display: flex; flex-direction: row; margin-left: 10px; align-items: center; justify-content: center; } - .wonder-app-component .wonder-controller-component .header-controller .controller-transform .header-item .transform-gizmo-switch .translation { - background-image: url("../img/translation.png"); } - .wonder-app-component .wonder-controller-component .header-controller .controller-transform .header-item .transform-gizmo-switch .rotation { - background-image: url("../img/rotation.png"); } - .wonder-app-component .wonder-controller-component .header-controller .controller-transform .header-item .transform-gizmo-switch .select { - background-color: white; - background-size: 100%; - width: 30px; - height: 30px; } - .wonder-app-component .wonder-controller-component .header-controller .controller-transform .header-item .transform-gizmo-switch .not-select { - background-color: gray; - background-size: 100%; - width: 30px; - height: 30px; } + .wonder-app-component .wonder-controller-component .header-controller .controller-transform .header-item .component-item .transform-gizmo-switch { + flex: initial; + display: flex; + flex-direction: row; + margin-left: 10px; + align-items: center; + justify-content: center; } + .wonder-app-component .wonder-controller-component .header-controller .controller-transform .header-item .component-item .transform-gizmo-switch .translation { + background-image: url("../img/translation.png"); } + .wonder-app-component .wonder-controller-component .header-controller .controller-transform .header-item .component-item .transform-gizmo-switch .rotation { + background-image: url("../img/rotation.png"); } + .wonder-app-component .wonder-controller-component .header-controller .controller-transform .header-item .component-item .transform-gizmo-switch .select { + background-color: white; + background-size: 100%; + width: 30px; + height: 30px; } + .wonder-app-component .wonder-controller-component .header-controller .controller-transform .header-item .component-item .transform-gizmo-switch .not-select { + background-color: gray; + background-size: 100%; + width: 30px; + height: 30px; } + .wonder-app-component .wonder-controller-component .header-controller .controller-transform .header-item .component-item .transform-gizmo-coordinate-system-switch { + margin-left: 30px; } .wonder-app-component .wonder-controller-component .header-controller .controller-runAndStop { flex: initial; width: 4%; diff --git a/public/sass/components/controller/_controller.scss b/public/sass/components/controller/_controller.scss index f05002b08..520626baa 100755 --- a/public/sass/components/controller/_controller.scss +++ b/public/sass/components/controller/_controller.scss @@ -58,30 +58,42 @@ align-items: center; height: 100%; flex-direction: row; - .transform-gizmo-switch { + .component-item { flex: initial; display: flex; flex-direction: row; margin-left: 10px; align-items: center; justify-content: center; - .translation { - background-image: url("../img/translation.png") - } - .rotation { - background-image: url("../img/rotation.png") - } - .select { - background-color: white; - background-size: 100%; - width: 30px; - height: 30px; + .transform-gizmo-switch { + flex: initial; + display: flex; + flex-direction: row; + margin-left: 10px; + align-items: center; + justify-content: center; + .translation { + background-image: url("../img/translation.png") + } + .rotation { + background-image: url("../img/rotation.png") + } + .select { + background-color: white; + background-size: 100%; + width: 30px; + height: 30px; + } + .not-select { + background-color: gray; + background-size: 100%; + width: 30px; + height: 30px; + } } - .not-select { - background-color: gray; - background-size: 100%; - width: 30px; - height: 30px; + ; + .transform-gizmo-coordinate-system-switch { + margin-left: 30px } } } diff --git a/src/core/composable_component/controller/atom_component/transformGizmo/ui/TransformGizmoCoordinateSystemSwitch.re b/src/core/composable_component/controller/atom_component/transformGizmo/ui/TransformGizmoCoordinateSystemSwitch.re new file mode 100644 index 000000000..f403cd771 --- /dev/null +++ b/src/core/composable_component/controller/atom_component/transformGizmo/ui/TransformGizmoCoordinateSystemSwitch.re @@ -0,0 +1,53 @@ +open TransformGizmoCoordinateSystemSwitchType; + +type state = {selectedCoordinateSystem: coordinateSystem}; + +type action = + | Change(coordinateSystem, onChangeFunc); + +module Method = { + let getText = (coordinateSystem: coordinateSystem) => + switch (coordinateSystem) { + | World => "World" + | Local => "Local" + }; + + let _getReverse = (coordinateSystem: coordinateSystem) : coordinateSystem => + switch (coordinateSystem) { + | World => Local + | Local => World + }; + + let change = ((state, send), onChangeFunc) => + send( + Change(state.selectedCoordinateSystem |> _getReverse, onChangeFunc), + ); +}; + +let component = ReasonReact.reducerComponent("TransformGizmoSwitch"); + +let reducer = (action, state) => + switch (action) { + | Change(coordinateSystem, onChangeFunc) => + ReasonReactUtils.updateWithSideEffects( + {...state, selectedCoordinateSystem: coordinateSystem}, _state => + onChangeFunc(coordinateSystem) + ) + }; + +let render = + (onChangeFunc, ({state, send}: ReasonReact.self('a, 'b, 'c)) as self) => +
+ +
; + +let make = (~defaultCoordinateSystem, ~onChange, _children) => { + ...component, + initialState: () => {selectedCoordinateSystem: defaultCoordinateSystem}, + reducer, + render: self => render(onChange, self), +}; \ No newline at end of file diff --git a/src/core/composable_component/controller/atom_component/transformGizmo/ui/TransformGizmoCoordinateSystemSwitchType.re b/src/core/composable_component/controller/atom_component/transformGizmo/ui/TransformGizmoCoordinateSystemSwitchType.re new file mode 100644 index 000000000..45c406f2f --- /dev/null +++ b/src/core/composable_component/controller/atom_component/transformGizmo/ui/TransformGizmoCoordinateSystemSwitchType.re @@ -0,0 +1,10 @@ +type coordinateSystem = SceneViewType.coordinateSystem; + +type onChangeFunc = coordinateSystem => unit; + +type item = { + coordinateSystem, + onChangeFunc, +}; + +/* type data = array(item); */ \ No newline at end of file diff --git a/src/core/composable_component/controller/ui/Controller.re b/src/core/composable_component/controller/ui/Controller.re index 8f56025b6..3e4eab958 100755 --- a/src/core/composable_component/controller/ui/Controller.re +++ b/src/core/composable_component/controller/ui/Controller.re @@ -2,6 +2,8 @@ open ColorType; open Color; +type retainedProps = {updateTypeArr: UpdateStore.updateComponentTypeArr}; + type state = {isReload: bool}; type action = @@ -45,7 +47,7 @@ module Method = { ; - let _handleChangeCurrentTransformType = type_ => { + let _handleChangeCurrentTransformGizmoType = type_ => { open SceneViewType; StateEditorService.getState() @@ -57,6 +59,19 @@ module Method = { StateLogicService.getAndRefreshEngineState(); }; + let _handleChangeCurrentTransformGizmoCoordinateSystem = coordinateSystem => { + StateEditorService.getState() + |> CoordinateSystemTransformGizmoSceneViewEditorService.setCoordinateSystem( + coordinateSystem, + ) + |> StateEditorService.setState + |> ignore; + + StateLogicService.getAndRefreshEngineState(); + + (); + }; + let _getCurrentTransformType = () => CurrentTransformGizmoSceneViewEditorService.getCurrentGizmoType |> StateLogicService.getEditorState; @@ -69,20 +84,25 @@ module Method = { data=[| { type_: SceneViewType.Translation, - onChangeFunc: _handleChangeCurrentTransformType, + onChangeFunc: _handleChangeCurrentTransformGizmoType, }, { type_: SceneViewType.Rotation, - onChangeFunc: _handleChangeCurrentTransformType, + onChangeFunc: _handleChangeCurrentTransformGizmoType, }, |] defaultType=(_getCurrentTransformType()) /> + ; }; -let component = ReasonReact.reducerComponent("Controller"); +let component = ReasonReact.reducerComponentWithRetainedProps("Controller"); let reducer = (action, state) => switch (action) { @@ -124,9 +144,18 @@ let render = ; +let shouldUpdate = + ({newSelf}: ReasonReact.oldNewSelf('a, retainedProps, 'c)) => + newSelf.retainedProps.updateTypeArr + |> StoreUtils.shouldComponentUpdateWithAll; + let make = (~uiState: AppStore.appState, ~dispatchFunc, _children) => { ...component, initialState: () => {isReload: false}, reducer, + retainedProps: { + updateTypeArr: StoreUtils.getUpdateComponentTypeArr(uiState), + }, + shouldUpdate, render: self => render(uiState, dispatchFunc, self), }; \ No newline at end of file diff --git a/src/core/job/loop/UpdateTransformGizmosJob.re b/src/core/job/loop/UpdateTransformGizmosJob.re index 19c93b240..0f0bd8890 100644 --- a/src/core/job/loop/UpdateTransformGizmosJob.re +++ b/src/core/job/loop/UpdateTransformGizmosJob.re @@ -21,29 +21,6 @@ let _moveWholeGizmoToCurrentSceneTreeNode = ); }; -let _rotateWholeGizmoToCurrentSceneTreeNode = - (currentSceneTreeNode, wholeGizmo, engineState) => { - let currentSceneTreeNodeTransform = - GameObjectComponentEngineService.unsafeGetTransformComponent( - currentSceneTreeNode, - engineState, - ); - let wholeGizmoTransform = - GameObjectComponentEngineService.unsafeGetTransformComponent( - wholeGizmo, - engineState, - ); - - engineState - |> TransformEngineService.setEulerAngles( - wholeGizmoTransform, - TransformEngineService.getEulerAngles( - currentSceneTreeNodeTransform, - engineState, - ), - ); -}; - let _scaleWholeGizmo = (currentSceneTreeNode, cameraGameObject, wholeGizmo, engineState) => { let scaleFactor = @@ -108,19 +85,14 @@ let updateTransformJob = (_, engineState) => { ); /* TODO test */ - switch ( - CoordinateSystemTransformGizmoSceneViewEditorService.getCoordinateSystem( - editorState, - ) - ) { - | Local => - engineState - |> _rotateWholeGizmoToCurrentSceneTreeNode( - currentSceneTreeNode, - wholeGizmo, - ) - | World => engineState - }; + engineState + |> CoordinateSystemTransformGizmosUtils.rotateWholeGizmoToCurrentSceneTreeNode( + currentSceneTreeNode, + wholeGizmo, + CoordinateSystemTransformGizmoSceneViewEditorService.getCoordinateSystem( + editorState, + ), + ); } : engineState; /* IsTransformGizmoRenderSceneViewEditorService.isTranslationWholeGizmoRender( diff --git a/src/core/utils/engine/job/init/initTransformGizmosJob/CoordinateSystemTransformGizmosUtils.re b/src/core/utils/engine/job/init/initTransformGizmosJob/CoordinateSystemTransformGizmosUtils.re new file mode 100644 index 000000000..e5837f255 --- /dev/null +++ b/src/core/utils/engine/job/init/initTransformGizmosJob/CoordinateSystemTransformGizmosUtils.re @@ -0,0 +1,64 @@ +let rotateWholeGizmoToCurrentSceneTreeNode = + ( + currentSceneTreeNode, + wholeGizmo, + coordinateSystem: SceneViewType.coordinateSystem, + engineState, + ) => { + let wholeGizmoTransform = + GameObjectComponentEngineService.unsafeGetTransformComponent( + wholeGizmo, + engineState, + ); + + switch (coordinateSystem) { + | Local => + let currentSceneTreeNodeTransform = + GameObjectComponentEngineService.unsafeGetTransformComponent( + currentSceneTreeNode, + engineState, + ); + + engineState + |> TransformEngineService.setEulerAngles( + wholeGizmoTransform, + TransformEngineService.getEulerAngles( + currentSceneTreeNodeTransform, + engineState, + ), + ); + | World => + engineState + |> TransformEngineService.setEulerAngles( + wholeGizmoTransform, + (0., 0., 0.), + ) + }; +}; + +let rotateWholeTransformGizmoToCurrentSceneTreeNode = + (editorState, engineState) => { + let currentSceneTreeNode = + SceneTreeEditorService.unsafeGetCurrentSceneTreeNode(editorState); + + let coordinateSystem = + CoordinateSystemTransformGizmoSceneViewEditorService.getCoordinateSystem( + editorState, + ); + + engineState + |> rotateWholeGizmoToCurrentSceneTreeNode( + currentSceneTreeNode, + OperateTranslationGizmoSceneViewEditorService.unsafeGetTranslationWholeGizmo( + editorState, + ), + coordinateSystem, + ) + |> rotateWholeGizmoToCurrentSceneTreeNode( + currentSceneTreeNode, + OperateRotationGizmoSceneViewEditorService.unsafeGetRotationWholeGizmo( + editorState, + ), + coordinateSystem, + ); +}; \ No newline at end of file diff --git a/src/core/utils/ui/StoreUtils.re b/src/core/utils/ui/StoreUtils.re index 7f93a3e5b..47b9782c0 100755 --- a/src/core/utils/ui/StoreUtils.re +++ b/src/core/utils/ui/StoreUtils.re @@ -17,13 +17,14 @@ let geGameObjectisShowComponentFromStore = (uiState, componentType) => | Some(isShowComponent) => isShowComponent }; +let shouldComponentUpdateWithAll = updateComponentTypeArr => + updateComponentTypeArr |> Js.Array.includes(All); + let shouldComponentUpdate = (componentType, updateComponentTypeArr) => updateComponentTypeArr |> Js.Array.includes(componentType) - || updateComponentTypeArr - |> Js.Array.includes(All); + || shouldComponentUpdateWithAll(updateComponentTypeArr); let shouldComponentUpdateMany = (componentTypeArr, updateComponentTypeArr) => ArrayService.hasIntersect(updateComponentTypeArr, componentTypeArr) - || updateComponentTypeArr - |> Js.Array.includes(UpdateStore.All); \ No newline at end of file + || shouldComponentUpdateWithAll(updateComponentTypeArr); \ No newline at end of file