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

feat: editable box #357

Merged
merged 41 commits into from
Nov 30, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
5bca349
feat: add clipping box
keiya01 Oct 27, 2022
91d5c4e
feat: add non-animation feature to reearth.lookAt
keiya01 Oct 28, 2022
730ff76
Merge branch 'main' into feature/box-api
keiya01 Oct 28, 2022
cb28dd4
Merge branch 'main' into feature/box-api
keiya01 Oct 29, 2022
d95f527
fix: disable debug flight
keiya01 Oct 29, 2022
b6c9f5c
chore: remove unused props
keiya01 Oct 30, 2022
2deb9c5
Merge branch 'main' into feature/box-api
keiya01 Nov 1, 2022
c5e3d6f
chore: rename anime to animation
keiya01 Nov 1, 2022
6f65b3b
chore: remove unnecessary disabling eslint comment
keiya01 Nov 1, 2022
97a8e1f
fix: remove unnecessary equal callback for memo
keiya01 Nov 1, 2022
e75b182
Merge remote-tracking branch 'origin/feature/box-api' into feature/bo…
keiya01 Nov 1, 2022
8305e30
refactor: split Side to other file
keiya01 Nov 1, 2022
9cecd3a
refactor: fix property type
keiya01 Nov 4, 2022
bf80000
fix: clipping collection to experimental
keiya01 Nov 4, 2022
60d8d4b
fix: use experimental clipping
keiya01 Nov 6, 2022
4aab4b1
fix: lookAt without animation
keiya01 Nov 6, 2022
f0ecd40
Merge branch 'main' into feature/box-api
keiya01 Nov 6, 2022
e533c15
Merge branch 'main' into feature/box-api
keiya01 Nov 13, 2022
9844ff3
feat: expose emit method from context
keiya01 Nov 15, 2022
a851faa
feat: add boxscale, boxrotate event
keiya01 Nov 15, 2022
ad35ee1
feat: export sampleTerrainHeight from common
keiya01 Nov 15, 2022
bfbe7bd
feat: add some layer to Box
keiya01 Nov 15, 2022
bb0c0d8
 chore: fix type
keiya01 Nov 15, 2022
7884c15
refactor: rename SelectedRearthEventType
keiya01 Nov 21, 2022
166258b
refactor: move translationWithClamping to Cesium/utils
keiya01 Nov 21, 2022
10dd8a5
refactor: rename dotProductMousePosition
keiya01 Nov 21, 2022
5a6dbc2
refactor: return moveAmount in dotMousePosition
keiya01 Nov 21, 2022
f89ea58
refactor: rename computeMoveAmount
keiya01 Nov 21, 2022
8b4ce98
refactor: rename isProgressSamplingTerrainHeight
keiya01 Nov 21, 2022
67e88b6
fix: assigning inProgressSamplingTerrainHeight inside of IF statement
keiya01 Nov 21, 2022
aa51cad
fix: use allowEnterGround
keiya01 Nov 21, 2022
630e6df
refactor: separate component logic to hooks
keiya01 Nov 21, 2022
60d3243
Merge branch 'main' into feature/box-api-interaction
keiya01 Nov 21, 2022
d0981d5
fix: sampleTerrainHeight args
keiya01 Nov 21, 2022
2636228
fix: use layeredit event to scale and rotate box
keiya01 Nov 23, 2022
0d9628b
chore: disable debug flight
keiya01 Nov 23, 2022
ae981b5
fix: rename rotation to rotate
keiya01 Nov 24, 2022
e8a4fce
fix: scalePoint dimension calculation
keiya01 Nov 24, 2022
f698800
refactor: remove unnecessary if statement
keiya01 Nov 25, 2022
376a678
refactor: use sampleTerrainHeightFromCartesian
keiya01 Nov 26, 2022
d61d8f3
Merge branch 'main' into feature/box-api-interaction
keiya01 Nov 30, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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>
);
});
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
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