diff --git a/app/src/modules/builder/assetGroup/assetsGroup.tsx b/app/src/modules/builder/assetGroup/assetsGroup.tsx
index 9e57fb7..5fabe2d 100644
--- a/app/src/modules/builder/assetGroup/assetsGroup.tsx
+++ b/app/src/modules/builder/assetGroup/assetsGroup.tsx
@@ -6,8 +6,8 @@ import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
import { DRACOLoader } from "three/examples/jsm/loaders/DRACOLoader";
import { FloorItems } from "../../../types/world/worldTypes";
import { useAssetsStore } from "../../../store/builder/useAssetStore";
+import { useEventsStore } from "../../../store/simulation/useEventsStore";
import Models from "./models/models";
-import { useGLTF } from "@react-three/drei";
const gltfLoaderWorker = new Worker(
new URL(
@@ -19,6 +19,7 @@ const gltfLoaderWorker = new Worker(
function AssetsGroup() {
const { setLoadingProgress } = useLoadingProgress();
const { setAssets } = useAssetsStore();
+ const { addEvent } = useEventsStore();
const loader = new GLTFLoader();
const dracoLoader = new DRACOLoader();
@@ -92,6 +93,133 @@ function AssetsGroup() {
opacity: 1,
eventData: item.eventData
})
+
+ if (item.eventData.type === "Vehicle") {
+ const vehicleEvent: VehicleEventSchema = {
+ modelUuid: item.modelUuid,
+ modelName: item.modelName,
+ position: item.position,
+ rotation: [item.rotation.x, item.rotation.y, item.rotation.z],
+ state: "idle",
+ type: "vehicle",
+ speed: 1,
+ point: {
+ uuid: item.eventData.point?.uuid || THREE.MathUtils.generateUUID(),
+ position: [item.eventData.point?.position[0] || 0, item.eventData.point?.position[1] || 0, item.eventData.point?.position[2] || 0],
+ rotation: [item.eventData.point?.rotation[0] || 0, item.eventData.point?.rotation[1] || 0, item.eventData.point?.rotation[2] || 0],
+ action: {
+ actionUuid: THREE.MathUtils.generateUUID(),
+ actionName: "Action 1",
+ actionType: "travel",
+ unLoadDuration: 5,
+ loadCapacity: 1,
+ steeringAngle: 0,
+ pickUpPoint: null,
+ unLoadPoint: null,
+ triggers: []
+ }
+ }
+ };
+ addEvent(vehicleEvent);
+ } else if (item.eventData.type === "Conveyor") {
+ const ConveyorEvent: ConveyorEventSchema = {
+ modelUuid: item.modelUuid,
+ modelName: item.modelName,
+ position: item.position,
+ rotation: [item.rotation.x, item.rotation.y, item.rotation.z],
+ state: "idle",
+ type: "transfer",
+ speed: 1,
+ points: item.eventData.points?.map((point: any, index: number) => ({
+ uuid: point.uuid || THREE.MathUtils.generateUUID(),
+ position: [point.position[0], point.position[1], point.position[2]],
+ rotation: [point.rotation[0], point.rotation[1], point.rotation[2]],
+ action: {
+ actionUuid: THREE.MathUtils.generateUUID(),
+ actionName: `Action 1`,
+ actionType: 'default',
+ material: 'Default material',
+ delay: 0,
+ spawnInterval: 5,
+ spawnCount: 1,
+ triggers: []
+ }
+ })) || [],
+ };
+ addEvent(ConveyorEvent);
+ } else if (item.eventData.type === "StaticMachine") {
+ const machineEvent: MachineEventSchema = {
+ modelUuid: item.modelUuid,
+ modelName: item.modelName,
+ position: item.position,
+ rotation: [item.rotation.x, item.rotation.y, item.rotation.z],
+ state: "idle",
+ type: "machine",
+ point: {
+ uuid: item.eventData.point?.uuid || THREE.MathUtils.generateUUID(),
+ position: [item.eventData.point?.position[0] || 0, item.eventData.point?.position[1] || 0, item.eventData.point?.position[2] || 0],
+ rotation: [item.eventData.point?.rotation[0] || 0, item.eventData.point?.rotation[1] || 0, item.eventData.point?.rotation[2] || 0],
+ action: {
+ actionUuid: THREE.MathUtils.generateUUID(),
+ actionName: "Action 1",
+ actionType: "process",
+ processTime: 10,
+ swapMaterial: "material-id",
+ triggers: []
+ }
+ }
+ };
+ addEvent(machineEvent);
+ } else if (item.eventData.type === "ArmBot") {
+ const roboticArmEvent: RoboticArmEventSchema = {
+ modelUuid: item.modelUuid,
+ modelName: item.modelName,
+ position: item.position,
+ rotation: [item.rotation.x, item.rotation.y, item.rotation.z],
+ state: "idle",
+ type: "roboticArm",
+ speed: 1,
+ point: {
+ uuid: item.eventData.point?.uuid || THREE.MathUtils.generateUUID(),
+ position: [item.eventData.point?.position[0] || 0, item.eventData.point?.position[1] || 0, item.eventData.point?.position[2] || 0],
+ rotation: [item.eventData.point?.rotation[0] || 0, item.eventData.point?.rotation[1] || 0, item.eventData.point?.rotation[2] || 0],
+ actions: [
+ {
+ actionUuid: THREE.MathUtils.generateUUID(),
+ actionName: "Action 1",
+ actionType: "pickAndPlace",
+ process: {
+ startPoint: null,
+ endPoint: null
+ },
+ triggers: []
+ }
+ ]
+ }
+ };
+ addEvent(roboticArmEvent);
+ } else if (item.eventData.type === 'Storage') {
+ const storageEvent: StorageEventSchema = {
+ modelUuid: item.modelUuid,
+ modelName: item.modelName,
+ position: item.position,
+ rotation: [item.rotation.x, item.rotation.y, item.rotation.z], state: "idle",
+ type: "storageUnit",
+ point: {
+ uuid: item.eventData.point?.uuid || THREE.MathUtils.generateUUID(),
+ position: [item.eventData.point?.position[0] || 0, item.eventData.point?.position[1] || 0, item.eventData.point?.position[2] || 0],
+ rotation: [item.eventData.point?.rotation[0] || 0, item.eventData.point?.rotation[1] || 0, item.eventData.point?.rotation[2] || 0],
+ action: {
+ actionUuid: THREE.MathUtils.generateUUID(),
+ actionName: "Action 1",
+ actionType: "store",
+ storageCapacity: 10,
+ triggers: []
+ }
+ }
+ };
+ addEvent(storageEvent);
+ }
} else {
assets.push({
modelUuid: item.modelUuid,
diff --git a/app/src/modules/builder/assetGroup/models/model/assetBoundingBox.tsx b/app/src/modules/builder/assetGroup/models/model/assetBoundingBox.tsx
new file mode 100644
index 0000000..c1d4881
--- /dev/null
+++ b/app/src/modules/builder/assetGroup/models/model/assetBoundingBox.tsx
@@ -0,0 +1,20 @@
+import { Box3, BoxGeometry, EdgesGeometry, Vector3 } from "three";
+
+export const AssetBoundingBox = ({ asset, boundingBox }: { asset: Asset, boundingBox: Box3 | null }) => {
+ if (!boundingBox) return null;
+
+ const size = boundingBox.getSize(new Vector3());
+ const center = boundingBox.getCenter(new Vector3());
+
+ const boxGeometry = new BoxGeometry(size.x, size.y, size.z);
+ const edges = new EdgesGeometry(boxGeometry);
+
+ return (
+
+
+
+
+
+
+ );
+};
\ No newline at end of file
diff --git a/app/src/modules/builder/assetGroup/models/model/model.tsx b/app/src/modules/builder/assetGroup/models/model/model.tsx
index 55eb1a6..e58ef9f 100644
--- a/app/src/modules/builder/assetGroup/models/model/model.tsx
+++ b/app/src/modules/builder/assetGroup/models/model/model.tsx
@@ -1,13 +1,24 @@
-import { Outlines } from '@react-three/drei';
-import { useEffect, useState } from 'react';
+import * as THREE from 'three';
+import { useEffect, useRef, useState } from 'react';
import { retrieveGLTF, storeGLTF } from '../../../../../utils/indexDB/idbUtils';
import { GLTF, GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader';
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader';
-import * as THREE from 'three';
+import { useFrame, useThree } from '@react-three/fiber';
+import { useActiveTool, useDeletableFloorItem, useRenderDistance, useSelectedFloorItem } from '../../../../../store/builder/store';
+import { AssetBoundingBox } from './assetBoundingBox';
+import { CameraControls } from '@react-three/drei';
function Model({ asset }: { asset: Asset }) {
+ const { camera, controls } = useThree();
+ const { activeTool } = useActiveTool();
+ const { deletableFloorItem, setDeletableFloorItem } = useDeletableFloorItem();
+ const { selectedFloorItem, setSelectedFloorItem } = useSelectedFloorItem();
+ const { renderDistance } = useRenderDistance();
+ const [isRendered, setIsRendered] = useState(false);
const url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_MARKETPLACE_URL}`;
const [gltfScene, setGltfScene] = useState(null);
+ const [boundingBox, setBoundingBox] = useState(null);
+ const groupRef = useRef(null);
useEffect(() => {
const loader = new GLTFLoader();
@@ -17,9 +28,11 @@ function Model({ asset }: { asset: Asset }) {
loader.setDRACOLoader(dracoLoader);
const loadModel = async () => {
try {
+ // Check Cache
const cachedModel = THREE.Cache.get(asset.assetId!);
if (cachedModel) {
setGltfScene(cachedModel);
+ calculateBoundingBox(cachedModel.scene);
return;
}
@@ -32,6 +45,7 @@ function Model({ asset }: { asset: Asset }) {
THREE.Cache.remove(blobUrl);
THREE.Cache.add(asset.assetId!, gltf);
setGltfScene(gltf);
+ calculateBoundingBox(gltf.scene);
},
undefined,
(error) => {
@@ -49,6 +63,7 @@ function Model({ asset }: { asset: Asset }) {
await storeGLTF(asset.assetId!, modelBlob);
THREE.Cache.add(asset.assetId!, gltf);
setGltfScene(gltf);
+ calculateBoundingBox(gltf.scene);
},
undefined,
(error) => {
@@ -60,22 +75,79 @@ function Model({ asset }: { asset: Asset }) {
}
};
+ const calculateBoundingBox = (scene: THREE.Object3D) => {
+ const box = new THREE.Box3().setFromObject(scene);
+ setBoundingBox(box);
+ };
+
loadModel();
- }, [asset.assetId]);
+ }, []);
+
+ useFrame(() => {
+ const assetPosition = new THREE.Vector3(...asset.position);
+ if (!isRendered && assetPosition.distanceTo(camera.position) <= renderDistance) {
+ setIsRendered(true);
+ } else if (isRendered && assetPosition.distanceTo(camera.position) > renderDistance) {
+ setIsRendered(false);
+ }
+ })
+
+ const handleAssetDouble = (asset: Asset) => {
+ if (asset) {
+ if (activeTool === "cursor" && boundingBox && groupRef.current) {
+ const size = boundingBox.getSize(new THREE.Vector3());
+ const center = boundingBox.getCenter(new THREE.Vector3());
+
+ const front = new THREE.Vector3(0, 0, 1);
+ groupRef.current.localToWorld(front);
+ front.sub(groupRef.current.position).normalize();
+
+ const distance = Math.max(size.x, size.y, size.z) * 2;
+ const newPosition = center.clone().addScaledVector(front, distance);
+
+ (controls as CameraControls).setPosition(
+ newPosition.x,
+ newPosition.y,
+ newPosition.z,
+ true
+ );
+ (controls as CameraControls).setTarget(center.x, center.y, center.z, true);
+ (controls as CameraControls).fitToBox(groupRef.current!, true, {
+ cover: true,
+ paddingTop: 5,
+ paddingLeft: 5,
+ paddingBottom: 5,
+ paddingRight: 5,
+ });
+ setSelectedFloorItem(groupRef.current);
+
+ }
+ }
+ };
return (
- <>
- {gltfScene &&
-
+ {
+ e.stopPropagation();
+ handleAssetDouble(asset);
+ }}
+ >
+ {gltfScene && (
+ isRendered ? (
-
- }
- >
+ ) : (
+
+ )
+ )}
+
);
}
diff --git a/app/src/modules/builder/assetGroup/models/models.tsx b/app/src/modules/builder/assetGroup/models/models.tsx
index 7378812..4553531 100644
--- a/app/src/modules/builder/assetGroup/models/models.tsx
+++ b/app/src/modules/builder/assetGroup/models/models.tsx
@@ -1,16 +1,31 @@
-import React from 'react'
import { useAssetsStore } from '../../../../store/builder/useAssetStore';
import Model from './model/model';
+import { useThree } from '@react-three/fiber';
+import { CameraControls } from '@react-three/drei';
+import { Vector3 } from 'three';
+import { useSelectedFloorItem } from '../../../../store/builder/store';
function Models() {
+ const { controls } = useThree();
const { assets } = useAssetsStore();
+ const { selectedFloorItem, setSelectedFloorItem } = useSelectedFloorItem();
return (
- <>
+ {
+ e.stopPropagation();
+ if (selectedFloorItem) {
+ const target = (controls as CameraControls).getTarget(new Vector3());
+ (controls as CameraControls).setTarget(target.x, 0, target.z, true);
+ setSelectedFloorItem(null);
+ }
+ }}
+ >
{assets.map((asset) =>
)}
- >
+
)
}
diff --git a/app/src/modules/builder/builder.tsx b/app/src/modules/builder/builder.tsx
index 18d407b..3189968 100644
--- a/app/src/modules/builder/builder.tsx
+++ b/app/src/modules/builder/builder.tsx
@@ -243,7 +243,7 @@ export default function Builder() {
/>
-
+ /> */}
- {/* */}
+
diff --git a/app/src/modules/scene/controls/selectionControls/selectionControls.tsx b/app/src/modules/scene/controls/selectionControls/selectionControls.tsx
index 16f992b..763faa3 100644
--- a/app/src/modules/scene/controls/selectionControls/selectionControls.tsx
+++ b/app/src/modules/scene/controls/selectionControls/selectionControls.tsx
@@ -49,10 +49,10 @@ const SelectionControls: React.FC = () => {
const helper = new SelectionHelper(gl);
- if (!itemsGroup) {
- echo.warn("itemsGroup not found in the scene.");
- return;
- }
+ // if (!itemsGroup) {
+ // echo.warn("itemsGroup not found in the scene.");
+ // return;
+ // }
const onPointerDown = (event: PointerEvent) => {
if (event.button === 2) {
@@ -169,7 +169,7 @@ const SelectionControls: React.FC = () => {
selectedObjects.map((object) => {
let currentObject: THREE.Object3D | null = object;
while (currentObject) {
- if (currentObject.userData.modelId) {
+ if (currentObject.userData.modelUuid) {
Objects.add(currentObject);
break;
}
diff --git a/app/src/modules/scene/postProcessing/postProcessing.tsx b/app/src/modules/scene/postProcessing/postProcessing.tsx
index 426e199..7c5db64 100644
--- a/app/src/modules/scene/postProcessing/postProcessing.tsx
+++ b/app/src/modules/scene/postProcessing/postProcessing.tsx
@@ -1,4 +1,3 @@
-import * as THREE from "three";
import { EffectComposer, N8AO, Outline } from "@react-three/postprocessing";
import { BlendFunction } from "postprocessing";
import {
@@ -6,15 +5,14 @@ import {
useSelectedWallItem,
useSelectedFloorItem,
} from "../../../store/builder/store";
-import * as Types from "../../../types/world/worldTypes";
import * as CONSTANTS from "../../../types/world/worldConstants";
-import { useEffect } from "react";
import { useSelectedEventSphere } from "../../../store/simulation/useSimulationStore";
+import { useEffect } from "react";
export default function PostProcessing() {
- const { deletableFloorItem, setDeletableFloorItem } = useDeletableFloorItem();
- const { selectedWallItem, setSelectedWallItem } = useSelectedWallItem();
- const { selectedFloorItem, setSelectedFloorItem } = useSelectedFloorItem();
+ const { deletableFloorItem } = useDeletableFloorItem();
+ const { selectedWallItem } = useSelectedWallItem();
+ const { selectedFloorItem } = useSelectedFloorItem();
const { selectedEventSphere } = useSelectedEventSphere();
function flattenChildren(children: any[]) {
@@ -28,6 +26,10 @@ export default function PostProcessing() {
return allChildren;
}
+ useEffect(()=>{
+ console.log('selectedFloorItem: ', selectedFloorItem);
+ },[selectedFloorItem])
+
return (
<>