diff --git a/src/config-schemas b/src/config-schemas index f73a7130032a168919e06b5464297e588b838844..22c1d348e291f1d757dbbbacbfdfeee5355f6c62 160000 --- a/src/config-schemas +++ b/src/config-schemas @@ -1 +1 @@ -Subproject commit f73a7130032a168919e06b5464297e588b838844 +Subproject commit 22c1d348e291f1d757dbbbacbfdfeee5355f6c62 diff --git a/src/features/ship/ShipModel.tsx b/src/features/ship/ShipModel.tsx new file mode 100644 index 0000000000000000000000000000000000000000..d6b2cc5fbd95cea6c000faa6acbd06bb808bf09b --- /dev/null +++ b/src/features/ship/ShipModel.tsx @@ -0,0 +1,42 @@ +import { useStore } from "../../common/store"; +import StreamedMesh from "../viewport/Mesh"; +import MeshLoader from "../viewport/MeshLoader"; +import { Frame } from "../viewport/TF2"; +import { Object3D } from 'three'; +import { OBB } from "three-stdlib"; + +interface ShipModelProps { + onOBBCalculated?: (obb: OBB, parent: Object3D) => void; +} + +export default function ShipModel(props: ShipModelProps) { + const ship = useStore(state => state.ship); + + return ( + <> + { + /* Static Ship */ + ship && ship.static_mesh ? + <Frame frameId={ship.static_mesh.tf_frame}> + <MeshLoader + MeshURI={ship.static_mesh.uri} + rotation={ship.static_mesh.transform?.rotation} + position={ship.static_mesh.transform?.translation} + scale={ship.static_mesh.transform?.scale} + onOBBCalculated={props.onOBBCalculated} + /> + </Frame> + : null + } + { + /* Streamed Ship */ + ship && ship.topics && ship.topics.streamed_mesh ? + <StreamedMesh + rosbridgeURI={ship.rosbridge.uri} + topic={ship.topics.streamed_mesh} + /> + : null + } + </> + ); +} diff --git a/src/features/viewport/ImmersiveShip.tsx b/src/features/viewport/ImmersiveShip.tsx index fdb3d00675ffea430a364d08716ccd85fe9d9a47..27da19c388ca3aa0dfaf6bb3b82796c3998f5323 100644 --- a/src/features/viewport/ImmersiveShip.tsx +++ b/src/features/viewport/ImmersiveShip.tsx @@ -1,7 +1,7 @@ import { Interactive, useController, useXR } from "@react-three/xr"; import { useEffect, useLayoutEffect, useRef, useState } from "react"; import { ColorRepresentation, DoubleSide, Vector3 } from "three"; -import Mesh from './Mesh'; +import StreamedMesh from './Mesh'; import { useStore } from '../../common/store'; import { Text } from '@react-three/drei'; @@ -54,14 +54,14 @@ const ImmersiveShip = (props: ImmersiveShipProps) => { const [pointsComplete, setPointsComplete] = useState(false); const sphereSize = 0.1; - if (!ship || !ship.topics.mesh) { + if (!ship || !ship.topics || !ship.topics.mesh) { return null; } if (!props.isControlling) { return ( - <Mesh + <StreamedMesh rosbridgeURI={ship.rosbridge.uri} - topic={ship.topics.mesh} + topic={ship.topics?.streamed_mesh ? ship.topics.streamed_mesh : ""} /> ); } @@ -78,9 +78,9 @@ const ImmersiveShip = (props: ImmersiveShipProps) => { onMove={event => setNextP(event.intersection?.point)} onBlur={() => setNextP(undefined)} > - <Mesh + <StreamedMesh rosbridgeURI={ship.rosbridge.uri} - topic={ship.topics.mesh} + topic={ship.topics?.streamed_mesh ? ship.topics.streamed_mesh : ""} /> </Interactive> { diff --git a/src/features/viewport/Mesh.tsx b/src/features/viewport/Mesh.tsx index d160cdd9f3ee2f2057845bc5d07b6e38571455a1..5fa7f658883d42e0e141d23c880e12ec5ac59a7a 100644 --- a/src/features/viewport/Mesh.tsx +++ b/src/features/viewport/Mesh.tsx @@ -4,13 +4,13 @@ import { BufferGeometry, DoubleSide, Float32BufferAttribute, Uint32BufferAttribu import { Messages } from "../../common/ROS"; import { useTopic } from "../../common/store"; -export interface MeshProps extends EventHandlers { +export interface StreamedMeshProps extends EventHandlers { rosbridgeURI: string; topic: string; onGeometryUpdate?: (geometry?: BufferGeometry) => void; } -const Mesh = (props: MeshProps) => { +const StreamedMesh = (props: StreamedMeshProps) => { const mesh = useTopic(props.rosbridgeURI, props.topic, 'mesh_msgs/MeshGeometryStamped'); const [geometry, setGeometry] = useState<BufferGeometry>(); @@ -89,4 +89,4 @@ const Mesh = (props: MeshProps) => { ); } -export default Mesh +export default StreamedMesh diff --git a/src/features/viewport/Viewport.tsx b/src/features/viewport/Viewport.tsx index e155eacc8395b1c4c0a6bcd2d1c7820d3bb49fc6..eff28febb0254493cc72f31a9ae575369c560be4 100644 --- a/src/features/viewport/Viewport.tsx +++ b/src/features/viewport/Viewport.tsx @@ -10,10 +10,12 @@ import Robot from './Robot'; import TF2, { Frame } from './TF2'; import { MathUtils } from 'three' import FiducialVisualizer from './FiducialVisualizer'; +import Show from '../../common/Show'; +import StreamedMesh from './Mesh'; +import ShipModel from '../ship/ShipModel'; const Viewport = () => { const robots = useStore(state => state.robots); - const ship = useStore(state => state.ship); const showSkybox = useStore(state => state.appSettings.showSkybox); const showOcean = useStore(state => state.appSettings.showSea); const oceanLevelOffest = useStore(state => state.appSettings.oceanLevelOffset); @@ -36,32 +38,7 @@ const Viewport = () => { <Skybox baseURL="/skyboxes/clouds/" visible={showSkybox} /> <Water waterNormalsTexture='waternormals.jpg' size={1000} heightOffset={oceanLevelOffest} visible={showOcean} /> - {/* { - ship && ship.topics.mesh ? - <Mesh - rosbridgeURI={ship.rosbridge.uri} - topic={ship.topics.mesh} - /> : - null - } */} - - {/* Drone - <Frame frameId='/mussol/imu_dji'> - <MeshLoader MeshURI='meshes/drone/drone_body.gltf' scale={[0.02, 0.02, 0.02]} color="orange" /> - </Frame> - - Crawler - <Frame frameId='/crawler/imu'> - <group position={[0, 0, 0]}> - <MeshLoader MeshURI='meshes/crawler/Altiscan.gltf' position={[0, 0.1, 0]} rotation={[0, -90, 180]} scale={[1, 1, 1]} color="blue" /> - </group> - </Frame> */} - - {/* Ship Mesh */} - <Frame frameId='mesh_ref'> - <MeshLoader MeshURI='meshes/Porto_230616_122018.gltf' rotation={[-90, 0, 180]} /> - </Frame> - + <ShipModel /> <For each={Object.values(robots)}> {