diff --git a/src/core/atom_component/dragTree/component/treeNode/SceneTreeNode.re b/src/core/atom_component/dragTree/component/treeNode/SceneTreeNode.re index 465a6bc8a..2f93cd371 100755 --- a/src/core/atom_component/dragTree/component/treeNode/SceneTreeNode.re +++ b/src/core/atom_component/dragTree/component/treeNode/SceneTreeNode.re @@ -103,12 +103,12 @@ module Method = { ); /* relationResult - |> OptionService.handleSomeAndIgnore(relationResult => - relationResult - |> Result.RelationResult.handleError(msg => - ConsoleUtils.error(msg, StateEditorService.getState()) - ) - ); */ + |> OptionService.handleSomeAndIgnore(relationResult => + relationResult + |> Result.RelationResult.handleError(msg => + ConsoleUtils.error(msg, StateEditorService.getState()) + ) + ); */ isValid ? DragGameObject(gameObject, startId, dragPosition) : @@ -401,20 +401,13 @@ let make = self, ), didUpdate: _self => - isSelected ? - { - let sceneTreeContainerJsObj = - DomHelper.getElementById("wonder-sceneTree-component") - |> DomHelperType.convertDomElementToJsObj; - - let sceneTreeNodeDomClientRect = - DomHelper.getElementById({j|sceneTreeNode-$gameObject|j}) - |> DomHelper.getDomClientRect; - - SceneTreeNodeScrollUtils.scrollCurrentSceneTreeNode( - sceneTreeContainerJsObj, - sceneTreeNodeDomClientRect, - ); - } : - (), + SceneTreeNodeScrollUtils.handleSelectedSceneTreeNodeScroll( + isSelected, + gameObject, + ), + didMount: _ => + SceneTreeNodeScrollUtils.handleSelectedSceneTreeNodeScroll( + isSelected, + gameObject, + ), }; \ No newline at end of file diff --git a/src/core/atom_component/dragTree/component/treeNode/utils/SceneTreeNodeScrollUtils.re b/src/core/atom_component/dragTree/component/treeNode/utils/SceneTreeNodeScrollUtils.re index 0bbc560c3..c62630ddf 100644 --- a/src/core/atom_component/dragTree/component/treeNode/utils/SceneTreeNodeScrollUtils.re +++ b/src/core/atom_component/dragTree/component/treeNode/utils/SceneTreeNodeScrollUtils.re @@ -107,4 +107,22 @@ let scrollCurrentSceneTreeNode = | None => () | Some(value) => sceneTreeContainerJsObj##scrollTop#=value }; -}; \ No newline at end of file +}; + +let handleSelectedSceneTreeNodeScroll = (isSelected, gameObject) => + isSelected ? + { + let sceneTreeContainerJsObj = + DomHelper.getElementById("wonder-sceneTree-component") + |> DomHelperType.convertDomElementToJsObj; + + let sceneTreeNodeDomClientRect = + DomHelper.getElementById({j|sceneTreeNode-$gameObject|j}) + |> DomHelper.getDomClientRect; + + scrollCurrentSceneTreeNode( + sceneTreeContainerJsObj, + sceneTreeNodeDomClientRect, + ); + } : + (); \ No newline at end of file diff --git a/src/core/utils/engine/job/init/initPickingJob/AABBShapeUtils.re b/src/core/utils/engine/job/init/initPickingJob/AABBShapeUtils.re index 69d8af256..bdcf155df 100755 --- a/src/core/utils/engine/job/init/initPickingJob/AABBShapeUtils.re +++ b/src/core/utils/engine/job/init/initPickingJob/AABBShapeUtils.re @@ -31,6 +31,31 @@ let _expandByVertex = (min, max, vertex) => ( Vector3Service.min(min, vertex), Vector3Service.max(max, vertex), ); +let _forEachVerticesWithMinAndMax = + (vertices, verticesCount, (min, max), func) => { + let index = ref(0); + let minRef = ref(min); + let maxRef = ref(max); + + while (index^ < verticesCount) { + let (min, max) = + func( + ( + Js.Typed_array.Float32Array.unsafe_get(vertices, index^), + Js.Typed_array.Float32Array.unsafe_get(vertices, index^ + 1), + Js.Typed_array.Float32Array.unsafe_get(vertices, index^ + 2), + ), + minRef^, + maxRef^, + ); + + minRef := min; + maxRef := max; + index := index^ + 3; + }; + + {min: minRef^, max: maxRef^}; +}; let setFromGameObject = (gameObject, engineState) => { let localToWorldMatrixTypeArray = @@ -71,10 +96,40 @@ let setFromPoints = vertices => _expandByVertex(min, max, vertex) ); +let setFromAllPointsAndLocalToWolrdMatrices = + ( + allPointsAndLocalToWolrdMatrices: + array( + (Js.Typed_array.Float32Array.t, Js.Typed_array.Float32Array.t), + ), + ) => + allPointsAndLocalToWolrdMatrices + |> WonderCommonlib.ArrayService.reduceOneParam( + (. {min, max}, (vertices, localToWorldMatrixTypeArray)) => + _forEachVerticesWithMinAndMax( + vertices, + Js.Typed_array.Float32Array.length(vertices), + (min, max), + (vertex, min, max) => + Wonderjs.Vector3Service.transformMat4Tuple( + vertex, + localToWorldMatrixTypeArray, + ) + |> _expandByVertex(min, max) + ), + { + min: (infinity, infinity, infinity), + max: (neg_infinity, neg_infinity, neg_infinity), + }, + ); + let getCenter = ({min, max}) => Wonderjs.Vector3Service.add(Wonderjs.Vector3Type.Float, max, min) |> Wonderjs.Vector3Service.scale(Wonderjs.Vector3Type.Float, 0.5); +let calcRadiusOfAABB = ({min, max}, center) => + Vector3Service.distanceTo(max, center); + let getHalfExtends = ({min, max}) => Wonderjs.Vector3Service.sub(Wonderjs.Vector3Type.Float, max, min) |> Wonderjs.Vector3Service.scale(Wonderjs.Vector3Type.Float, 0.5); diff --git a/src/core/utils/engine/job/init/initPickingJob/SphereShapeUtils.re b/src/core/utils/engine/job/init/initPickingJob/SphereShapeUtils.re index e97e28e49..17175c639 100755 --- a/src/core/utils/engine/job/init/initPickingJob/SphereShapeUtils.re +++ b/src/core/utils/engine/job/init/initPickingJob/SphereShapeUtils.re @@ -24,7 +24,7 @@ let _forEachVertices = (vertices, verticesCount, func) => { maxRadiusSqRef^; }; -let findMaxDistanceOfPointsToCenter = (center, vertices) => +let calcMaxDistanceOfPointsToCenter = (center, vertices) => _forEachVertices( vertices, Js.Typed_array.Float32Array.length(vertices), @@ -42,7 +42,7 @@ let setFromPoints = vertices => { { center, radius: - findMaxDistanceOfPointsToCenter(center, vertices) |> Js.Math.sqrt, + calcMaxDistanceOfPointsToCenter(center, vertices) |> Js.Math.sqrt, }; }; diff --git a/src/service/stateTuple/logic/ArcballCameraControllerLogicService.re b/src/service/stateTuple/logic/ArcballCameraControllerLogicService.re index b6bd021e6..2b9825d1c 100755 --- a/src/service/stateTuple/logic/ArcballCameraControllerLogicService.re +++ b/src/service/stateTuple/logic/ArcballCameraControllerLogicService.re @@ -1,3 +1,5 @@ +open ShapeType; + let _renderWhenStop = (event, handleFunc, engineState) => { let (engineState, event) = handleFunc(. event, engineState); @@ -203,44 +205,65 @@ let _setArcballCameraControllerFocusRelatedAttribute = }; let _getTargetGameObjectMaxScale = (targetGameObjectTransform, engineState) => { - let (xScale, yScale, zScale) = + let (scaleX, scaleY, scaleZ) = engineState |> TransformEngineService.getScale(targetGameObjectTransform); - Js.Math.max_float(xScale, yScale) |> Js.Math.max_float(zScale); + Js.Math.max_float(scaleX, scaleY) |> Js.Math.max_float(scaleZ); }; -let _getMaxDistanceOfPointsToCenter = (targetGameObject, engineState) => - engineState - |> HierarchyGameObjectEngineService.getAllGameObjects(targetGameObject) - |> Js.Array.map(gameObject => - switch ( - engineState - |> GameObjectComponentEngineService.getGeometryComponent(gameObject) - ) { - | None => None - | Some(geometry) => - engineState - |> GeometryEngineService.getGeometryVertices(geometry) - |. Some - } - ) - |> WonderCommonlib.ArrayService.reduceOneParam( - (. maxValue, vertices) => { - let distanceOfPointsToCenter = - switch (vertices) { - | None => 0. - | Some(vertices) => - SphereShapeUtils.findMaxDistanceOfPointsToCenter( - (0., 0., 0.), - vertices, - ) - }; +let _calcGeometrySphereCenterAndRadius = + (targetGameObject, targetGameObjectTransform, engineState) => { + let pointsAndLocalToWolrdMatricesArray = + engineState + |> HierarchyGameObjectEngineService.getAllGameObjects(targetGameObject) + |> Js.Array.map(gameObject => + switch ( + engineState + |> GameObjectComponentEngineService.getGeometryComponent( + gameObject, + ) + ) { + | None => (None, None) + | Some(geometry) => ( + engineState + |> GeometryEngineService.getGeometryVertices(geometry) + |. Some, + engineState + |> TransformEngineService.getLocalToWorldMatrixTypeArray( + targetGameObjectTransform, + ) + |. Some, + ) + } + ) + |> Js.Array.filter(((vertices, localToWolrdMatrices)) => + vertices |> Js.Option.isSome + ) + |> Js.Array.map(((vertices, localToWolrdMatrices)) => + ( + vertices |> OptionService.unsafeGet, + localToWolrdMatrices |> OptionService.unsafeGet, + ) + ); - Js.Math.max_float(distanceOfPointsToCenter, maxValue); - }, - 0., - ) - |> Js.Math.sqrt; + let {min, max} = + AABBShapeUtils.setFromAllPointsAndLocalToWolrdMatrices( + pointsAndLocalToWolrdMatricesArray, + ); + + /* TODO the min and max not change with position */ + WonderLog.Log.print((min, max)) |> ignore; + let center = AABBShapeUtils.getCenter({min, max}); + + (center, AABBShapeUtils.calcRadiusOfAABB({min, max}, center)); +}; + +let _calcArcballCameraControllerDistance = + (distance, targetGameObjectTransform, engineState) => + _getTargetGameObjectMaxScale(targetGameObjectTransform, engineState) + *. distance + *. 2. + +. FocusDataUtils.getSmallGameObjectFocusDeviation(); let setEditorCameraFocusTargetGameObject = (targetGameObject, editorState, engineState) => { @@ -281,15 +304,16 @@ let setEditorCameraFocusTargetGameObject = targetGameObject, ); - let targetGameObjectPosition = + let (center, radius) = engineState - |> TransformEngineService.getPosition(targetGameObjectTransform); + |> _calcGeometrySphereCenterAndRadius( + targetGameObject, + targetGameObjectTransform, + ); let arcballCameraControllerDistance = - _getMaxDistanceOfPointsToCenter(targetGameObject, engineState) - *. _getTargetGameObjectMaxScale(targetGameObjectTransform, engineState) - *. 2. - +. FocusDataUtils.getSmallGameObjectFocusDeviation(); + engineState + |> _calcArcballCameraControllerDistance(radius, targetGameObjectTransform); engineState |> SceneEngineService.isSceneGameObject(targetGameObject) ? _setArcballCameraControllerFocusRelatedAttribute( @@ -297,13 +321,13 @@ let setEditorCameraFocusTargetGameObject = ( arcballCameraControllerDistance +. FocusDataUtils.getSceneGameObjectArcballCameraDistance(), - targetGameObjectPosition, + center, ), engineState, ) : _setArcballCameraControllerFocusRelatedAttribute( editorCameraArcballControllerComponent, - (arcballCameraControllerDistance, targetGameObjectPosition), + (arcballCameraControllerDistance, center), engineState, ); }; \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index b978a34f0..7fb35f59b 100755 --- a/yarn.lock +++ b/yarn.lock @@ -7234,9 +7234,9 @@ wonder-webgl@^0.0.2, wonder-webgl@^0.0.6: dependencies: wonder-log "^0.2.2" -wonder.js@1.0.0-beta.1.1: - version "1.0.0-beta.1.1" - resolved "https://registry.yarnpkg.com/wonder.js/-/wonder.js-1.0.0-beta.1.1.tgz#74f52327ebe38bdc0257fd76c14c491895096550" +wonder.js@1.0.0-beta.1.2: + version "1.0.0-beta.1.2" + resolved "https://registry.yarnpkg.com/wonder.js/-/wonder.js-1.0.0-beta.1.2.tgz#46349b8bff379e24ec5cb476945d51b62b1ab140" dependencies: bs-fetch "^0.3.0" wonder-bs-json "^0.0.1"