Skip to content
This repository has been archived by the owner on Apr 25, 2023. It is now read-only.

Commit

Permalink
feat: editable box (#357)
Browse files Browse the repository at this point in the history
* feat: add clipping box

* feat: add non-animation feature to reearth.lookAt

* fix: disable debug flight

* chore: remove unused props

* chore: rename anime to animation

* chore: remove unnecessary disabling eslint comment

* fix: remove unnecessary equal callback for memo

* refactor: split Side to other file

* refactor: fix property type

* fix: clipping collection to experimental

* fix: use experimental clipping

* fix: lookAt without animation

* feat: expose emit method from context

* feat: add boxscale, boxrotate event

* feat: export sampleTerrainHeight from common

* feat: add some layer to Box

*  chore: fix type

* refactor: rename SelectedRearthEventType

* refactor: move translationWithClamping to Cesium/utils

* refactor: rename dotProductMousePosition

* refactor: return moveAmount in dotMousePosition

* refactor: rename computeMoveAmount

* refactor: rename isProgressSamplingTerrainHeight

* fix: assigning inProgressSamplingTerrainHeight inside of IF statement

* fix: use allowEnterGround

* refactor: separate component logic to hooks

* fix: sampleTerrainHeight args

* fix: use layeredit event to scale and rotate box

* chore: disable debug flight

* fix: rename rotation to rotate

* fix: scalePoint dimension calculation

* refactor: remove unnecessary if statement

* refactor: use sampleTerrainHeightFromCartesian
  • Loading branch information
keiya01 committed Nov 30, 2022
1 parent c828254 commit 92a159e
Show file tree
Hide file tree
Showing 16 changed files with 1,280 additions and 130 deletions.
73 changes: 73 additions & 0 deletions src/components/molecules/Visualizer/Engine/Cesium/Box/Edge.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import { ArcType, Cartesian3, Color, TranslationRotationScale } from "cesium";
import { FC, memo } from "react";
import { Entity, PolylineGraphics } from "resium";

import { EventCallback } from "@reearth/util/event";

import { useHooks } from "./hooks/edge";

export type EdgeEventCallback = EventCallback<
[
event: any,
edgeEvent: {
layerId: string;
index: number;
},
]
>;

export type EdgeProperties = { start: Cartesian3; end: Cartesian3; isDraggable?: boolean };

type Props = {
id: string;
index: number;
edge: EdgeProperties;
trs: TranslationRotationScale;
isHovered: boolean;
fillColor?: Color;
hoverColor?: Color;
width?: number;
onMouseDown?: EdgeEventCallback;
onMouseMove?: EdgeEventCallback;
onMouseUp?: EdgeEventCallback;
onMouseEnter?: EdgeEventCallback;
onMouseLeave?: EdgeEventCallback;
};

export const Edge: FC<Props> = memo(function EdgePresenter({
id,
index,
edge,
isHovered,
fillColor,
trs,
width,
hoverColor,
onMouseDown,
onMouseMove,
onMouseUp,
}) {
const { cbp, outlineColor } = useHooks({
id,
index,
edge,
isHovered,
fillColor,
trs,
hoverColor,
onMouseDown,
onMouseMove,
onMouseUp,
});

return (
<Entity id={id}>
<PolylineGraphics
positions={cbp}
width={width}
material={outlineColor}
arcType={ArcType.NONE}
/>
</Entity>
);
});
126 changes: 126 additions & 0 deletions src/components/molecules/Visualizer/Engine/Cesium/Box/ScalePoints.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
import { ArcType, Cartesian3, Color, TranslationRotationScale } from "cesium";
import { FC, memo } from "react";
import { BoxGraphics, Entity, PolylineGraphics } from "resium";

import { EventCallback } from "@reearth/util/event";

import { useHooks } from "./hooks/scalePoint";

export type ScalePointProperties = {
point: Cartesian3;
oppositePoint: Cartesian3;
};

export type PointEventCallback = EventCallback<
[
event: any,
pointEvent: {
index: number;
layerId: string;
opposite: boolean;
position?: Cartesian3;
oppositePosition?: Cartesian3;
pointLocal?: Cartesian3;
},
]
>;

type Props = {
id: string;
index: number;
scalePoint: ScalePointProperties;
trs: TranslationRotationScale;
isHovered: boolean;
pointFillColor?: Color;
pointOutlineColor?: Color;
hoverPointOutlineColor?: Color;
pointOutlineWidth?: number;
axisLineColor?: Color;
axisLineWidth?: number;
dimensions?: { width: number; height: number; length: number };
visiblePoint?: boolean;
visibleAxisLine?: boolean;
onPointMouseDown?: PointEventCallback;
onPointMouseMove?: PointEventCallback;
onPointMouseUp?: PointEventCallback;
};

export const ScalePoints: FC<Props> = memo(function ScalePointsPresenter({
id,
index,
scalePoint,
isHovered,
pointFillColor,
pointOutlineColor,
hoverPointOutlineColor,
pointOutlineWidth,
axisLineColor,
axisLineWidth,
trs,
dimensions,
visiblePoint,
visibleAxisLine,
onPointMouseDown,
onPointMouseMove,
onPointMouseUp,
}) {
const {
entitiesPosition,
pointOutlineColorCb,
cesiumDimensionsCallbackProperty,
orientation,
axisColorProperty,
} = useHooks({
id,
index,
scalePoint,
isHovered,
pointOutlineColor,
hoverPointOutlineColor,
axisLineColor,
trs,
dimensions,
onPointMouseDown,
onPointMouseMove,
onPointMouseUp,
});

return (
<>
<Entity id={`${id}-${index}`} position={entitiesPosition.point} orientation={orientation}>
<BoxGraphics
show={visiblePoint}
dimensions={cesiumDimensionsCallbackProperty}
material={pointFillColor}
fill={!!pointFillColor}
outline={!!pointOutlineColor}
outlineColor={pointOutlineColorCb}
outlineWidth={pointOutlineWidth}
/>
</Entity>
<Entity
id={`${id}-opposite-${index}`}
position={entitiesPosition.oppositePoint}
orientation={orientation}>
<BoxGraphics
show={visiblePoint}
dimensions={cesiumDimensionsCallbackProperty}
material={pointFillColor}
fill={!!pointFillColor}
outline={!!pointOutlineColor}
outlineColor={pointOutlineColorCb}
outlineWidth={pointOutlineWidth}
/>
</Entity>
<Entity id={`${id}-axis-line-${index}`}>
<PolylineGraphics
positions={entitiesPosition.axisLine}
show={visibleAxisLine}
material={axisColorProperty}
width={axisLineWidth}
arcType={ArcType.NONE}
/>
</Entity>
</>
);
});
91 changes: 31 additions & 60 deletions src/components/molecules/Visualizer/Engine/Cesium/Box/Side.tsx
Original file line number Diff line number Diff line change
@@ -1,75 +1,46 @@
import {
Axis,
CallbackProperty,
Cartesian2,
Cartesian3,
Color,
Matrix4,
Plane as CesiumPlane,
PositionProperty,
TranslationRotationScale,
} from "cesium";
import { useMemo, FC, memo } from "react";
import { Color, Plane as CesiumPlane, TranslationRotationScale } from "cesium";
import { FC, memo } from "react";
import { Entity, PlaneGraphics } from "resium";

// ref: https://github.com/TerriaJS/terriajs/blob/cad62a45cbee98c7561625458bec3a48510f6cbc/lib/Models/BoxDrawing.ts#L1446-L1461
function setPlaneDimensions(
boxDimensions: Cartesian3,
planeNormalAxis: Axis,
planeDimensions: Cartesian2,
) {
if (planeNormalAxis === Axis.X) {
planeDimensions.x = boxDimensions.y;
planeDimensions.y = boxDimensions.z;
} else if (planeNormalAxis === Axis.Y) {
planeDimensions.x = boxDimensions.x;
planeDimensions.y = boxDimensions.z;
} else if (planeNormalAxis === Axis.Z) {
planeDimensions.x = boxDimensions.x;
planeDimensions.y = boxDimensions.y;
}
}
import { useHooks } from "./hooks/side";

export const Side: FC<{
id: string;
planeLocal: CesiumPlane;
isActive: boolean;
trs: TranslationRotationScale;
style: {
fillColor?: Color;
outlineColor?: Color;
outlineWidth?: number;
fill?: boolean;
outline?: boolean;
};
}> = memo(function SidePresenter({ id, planeLocal, style, trs }) {
const normalAxis = planeLocal.normal.x ? Axis.X : planeLocal.normal.y ? Axis.Y : Axis.Z;
const cbRef = useMemo(
() => new CallbackProperty(() => trs.translation, false) as unknown as PositionProperty,
[trs],
);
const [plane, dimension] = useMemo(() => {
const dimension = new Cartesian3();
setPlaneDimensions(trs.scale, normalAxis, dimension);
const scratchScaleMatrix = new Matrix4();
const scaleMatrix = Matrix4.fromScale(trs.scale, scratchScaleMatrix);
const plane = CesiumPlane.transform(
planeLocal,
scaleMatrix,
new CesiumPlane(Cartesian3.UNIT_Z, 0),
);
return [plane, dimension];
}, [trs, normalAxis, planeLocal]);
fillColor?: Color;
outlineColor?: Color;
activeOutlineColor?: Color;
fill?: boolean;
}> = memo(function SidePresenter({
id,
planeLocal,
isActive,
fill,
fillColor,
outlineColor,
activeOutlineColor,
trs,
}) {
const { cbRef, plane, dimension, orientation, outlineColorCb } = useHooks({
planeLocal,
isActive,
outlineColor,
activeOutlineColor,
trs,
});

return (
<Entity id={id} position={cbRef}>
<Entity id={id} position={cbRef} orientation={orientation}>
<PlaneGraphics
plane={plane}
dimensions={dimension}
fill={style.fill}
outline={style.outline}
material={style.fillColor}
outlineColor={style.outlineColor}
outlineWidth={style.outlineWidth}
fill={fill}
material={fillColor}
outlineWidth={1}
outlineColor={outlineColorCb}
outline
/>
</Entity>
);
Expand Down
63 changes: 63 additions & 0 deletions src/components/molecules/Visualizer/Engine/Cesium/Box/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// The 6 box sides defined as planes in local coordinate space.

import { Cartesian3, Plane as CesiumPlane } from "cesium";

import { EdgeProperties } from "./Edge";

// ref: https://github.com/TerriaJS/terriajs/blob/cad62a45cbee98c7561625458bec3a48510f6cbc/lib/Models/BoxDrawing.ts#L161-L169
export const SIDE_PLANES: readonly CesiumPlane[] = [
new CesiumPlane(new Cartesian3(0, 0, 1), 0.5),
new CesiumPlane(new Cartesian3(0, 0, -1), 0.5),
new CesiumPlane(new Cartesian3(0, 1, 0), 0.5),
new CesiumPlane(new Cartesian3(0, -1, 0), 0.5),
new CesiumPlane(new Cartesian3(1, 0, 0), 0.5),
new CesiumPlane(new Cartesian3(-1, 0, 0), 0.5),
];

const CORNER_POINT_VECTORS = [
new Cartesian3(0.5, 0.5, 0.5),
new Cartesian3(0.5, -0.5, 0.5),
new Cartesian3(-0.5, -0.5, 0.5),
new Cartesian3(-0.5, 0.5, 0.5),
];

const FACE_POINT_VECTORS = [
new Cartesian3(0.5, 0.0, 0.0),
new Cartesian3(0.0, 0.5, 0.0),
new Cartesian3(0.0, 0.0, 0.5),
];

// The box has 8 corner points and 6 face points that act as scaling grips.
// Here we represent them as 7 vectors in local coordinates space.
// Each vector represents a point and its opposite points can be easily derived from it.
// @see https://github.com/TerriaJS/terriajs/blob/cad62a45cbee98c7561625458bec3a48510f6cbc/lib/Models/BoxDrawing.ts#L184-L187
const SCALE_POINT_VECTORS = [...CORNER_POINT_VECTORS, ...FACE_POINT_VECTORS];

export const SCALE_POINTS = SCALE_POINT_VECTORS.map(vector => {
return {
point: vector,
oppositePoint: Cartesian3.multiplyByScalar(vector, -1, new Cartesian3()),
};
});

// Calculate edge of box. The box has 12 edge.
// In this logic, calculate 3 edges(vertical edge, top edge, bottom edge) in each `CORNER_POINT_VECTORS`.
export const BOX_EDGES: EdgeProperties[] = CORNER_POINT_VECTORS.flatMap((vector, i) => {
const upPoint = vector;
const downPoint = Cartesian3.clone(upPoint, new Cartesian3());
// Set point to bottom
downPoint.z *= -1;

const nextUpPoint = CORNER_POINT_VECTORS[(i + 1) % 4];
const nextDownPoint = Cartesian3.clone(nextUpPoint, new Cartesian3());
nextDownPoint.z *= -1;

const verticalEdge: EdgeProperties = { start: upPoint, end: downPoint, isDraggable: true };
const topEdge: EdgeProperties = { start: nextUpPoint, end: upPoint };
const bottomEdge: EdgeProperties = { start: nextDownPoint, end: downPoint };
return [verticalEdge, topEdge, bottomEdge];
});

// This is used for plane ID.
// We can use this name, for example you want to move the box when front plane is dragged.
export const SIDE_PLANE_NAMES = ["bottom", "top", "front", "back", "left", "right"];
Loading

0 comments on commit 92a159e

Please sign in to comment.