Merge remote-tracking branch 'origin/main-dev' into main-demo
This commit is contained in:
@@ -1,110 +0,0 @@
|
||||
// import { GLTF, GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
|
||||
// import { DRACOLoader } from "three/examples/jsm/loaders/DRACOLoader";
|
||||
// import * as THREE from "three";
|
||||
// import * as Types from "../../../types/world/worldTypes";
|
||||
// import { getWallItems } from "../../../services/factoryBuilder/asset/wallAsset/getWallItemsApi";
|
||||
// import { retrieveGLTF, storeGLTF } from "../../../utils/indexDB/idbUtils";
|
||||
// import { getUserData } from "../../../functions/getUserData";
|
||||
|
||||
// async function loadInitialWallItems(
|
||||
// setWallItems: Types.setWallItemSetState,
|
||||
// projectId?: string,
|
||||
// versionId?: string
|
||||
// ): Promise<void> {
|
||||
// if (!projectId || !versionId) return;
|
||||
// try {
|
||||
// const { organization, email } = getUserData();
|
||||
|
||||
// if (!email) {
|
||||
// console.error("No email found in localStorage");
|
||||
// }
|
||||
|
||||
// const items = await getWallItems(organization, projectId, versionId);
|
||||
|
||||
// let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_MARKETPLACE_URL}`;
|
||||
|
||||
// if (!items || items.length === 0) {
|
||||
// localStorage.removeItem("WallItems");
|
||||
// return;
|
||||
// }
|
||||
|
||||
// localStorage.setItem("WallItems", JSON.stringify(items));
|
||||
|
||||
// const loader = new GLTFLoader();
|
||||
// const dracoLoader = new DRACOLoader();
|
||||
// dracoLoader.setDecoderPath(
|
||||
// "https://cdn.jsdelivr.net/npm/three@0.160.0/examples/jsm/libs/draco/gltf/"
|
||||
// );
|
||||
// loader.setDRACOLoader(dracoLoader);
|
||||
|
||||
// const loadedWallItems = await Promise.all(
|
||||
// items.map(async (item: Types.WallItem) => {
|
||||
// // Check THREE.js cache first
|
||||
// const cachedModel = THREE.Cache.get(item.assetId!);
|
||||
// if (cachedModel) {
|
||||
// return processModel(cachedModel, item);
|
||||
// }
|
||||
|
||||
// // Check IndexedDB cache
|
||||
// const cachedModelBlob = await retrieveGLTF(item.assetId!);
|
||||
// if (cachedModelBlob) {
|
||||
// const blobUrl = URL.createObjectURL(cachedModelBlob);
|
||||
// return new Promise<Types.WallItem>((resolve) => {
|
||||
// loader.load(blobUrl, (gltf) => {
|
||||
// URL.revokeObjectURL(blobUrl);
|
||||
// THREE.Cache.add(item.assetId!, gltf);
|
||||
// resolve(processModel(gltf, item));
|
||||
// });
|
||||
// });
|
||||
// }
|
||||
|
||||
// // Load from original URL if not cached
|
||||
// const modelUrl = `${url_Backend_dwinzo}/api/v2/AssetFile/${item.assetId!}`;
|
||||
// return new Promise<Types.WallItem>((resolve) => {
|
||||
// loader.load(modelUrl, async (gltf) => {
|
||||
// try {
|
||||
// // Cache the model
|
||||
// const modelBlob = await fetch(modelUrl).then((res) => res.blob());
|
||||
// await storeGLTF(item.assetId!, modelBlob);
|
||||
// THREE.Cache.add(item.assetId!, gltf);
|
||||
// resolve(processModel(gltf, item));
|
||||
// } catch (error) {
|
||||
// console.error("Failed to cache model:", error);
|
||||
// resolve(processModel(gltf, item));
|
||||
// }
|
||||
// });
|
||||
// });
|
||||
// })
|
||||
// );
|
||||
|
||||
// setWallItems(loadedWallItems);
|
||||
// } catch (error) {
|
||||
// console.error("Failed to load wall items:", error);
|
||||
// }
|
||||
// }
|
||||
|
||||
// function processModel(gltf: GLTF, item: Types.WallItem): Types.WallItem {
|
||||
// const model = gltf.scene.clone();
|
||||
// model.uuid = item.modelUuid!;
|
||||
|
||||
// model.children[0]?.children?.forEach((child: THREE.Object3D) => {
|
||||
// if (child.name !== "CSG_REF") {
|
||||
// child.castShadow = true;
|
||||
// child.receiveShadow = true;
|
||||
// }
|
||||
// });
|
||||
|
||||
// return {
|
||||
// type: item.type,
|
||||
// model: model,
|
||||
// modelName: item.modelName,
|
||||
// assetId: item.assetId,
|
||||
// scale: item.scale,
|
||||
// csgscale: item.csgscale,
|
||||
// csgposition: item.csgposition,
|
||||
// position: item.position,
|
||||
// quaternion: item.quaternion,
|
||||
// };
|
||||
// }
|
||||
|
||||
// export default loadInitialWallItems;
|
||||
@@ -44,6 +44,7 @@ function AssetsGroup({ plane }: { readonly plane: RefMesh }) {
|
||||
|
||||
useEffect(() => {
|
||||
if (!projectId || !selectedVersion) return;
|
||||
|
||||
clearEvents();
|
||||
|
||||
let totalAssets = 0;
|
||||
@@ -304,7 +305,7 @@ function AssetsGroup({ plane }: { readonly plane: RefMesh }) {
|
||||
pointer.x = (event.clientX / window.innerWidth) * 2 - 1;
|
||||
pointer.y = -(event.clientY / window.innerHeight) * 2 + 1;
|
||||
|
||||
addAssetModel(scene, raycaster, camera, pointer, socket, selectedItem, setSelectedItem, addEvent, addAsset, plane, selectedVersion, projectId, userId);
|
||||
addAssetModel(scene, raycaster, camera, pointer, socket, selectedItem, setSelectedItem, addEvent, addAsset, plane, loader, selectedVersion, projectId, userId);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -348,7 +349,7 @@ function AssetsGroup({ plane }: { readonly plane: RefMesh }) {
|
||||
}, [selectedItem, camera, activeModule, controls, isRenameMode]);
|
||||
|
||||
return (
|
||||
<Models />
|
||||
<Models loader={loader} />
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ async function addAssetModel(
|
||||
addEvent: (event: EventsSchema) => void,
|
||||
addAsset: (asset: Asset) => void,
|
||||
plane: Types.RefMesh,
|
||||
loader: GLTFLoader,
|
||||
selectedVersion?: Version | null,
|
||||
projectId?: string,
|
||||
userId?: string
|
||||
@@ -29,12 +30,6 @@ async function addAssetModel(
|
||||
let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_MARKETPLACE_URL}`;
|
||||
|
||||
try {
|
||||
const loader = new GLTFLoader();
|
||||
const dracoLoader = new DRACOLoader();
|
||||
|
||||
dracoLoader.setDecoderPath("https://cdn.jsdelivr.net/npm/three@0.160.0/examples/jsm/libs/draco/gltf/");
|
||||
loader.setDRACOLoader(dracoLoader);
|
||||
|
||||
raycaster.setFromCamera(pointer, camera);
|
||||
const wallFloorsGroup = scene.getObjectByName("Walls-Floors-Group") as Types.Group | null;
|
||||
const floorsGroup = scene.getObjectByName("Floors-Group") as Types.Group | null;
|
||||
|
||||
@@ -2,7 +2,6 @@ import * as THREE from 'three';
|
||||
import { useCallback, 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 { ThreeEvent, useThree } from '@react-three/fiber';
|
||||
import { useActiveTool, useDeletableFloorItem, useSelectedAssets, useSelectedFloorItem, useSocketStore, useToggleView, useToolMode } from '../../../../../store/builder/store';
|
||||
import { AssetBoundingBox } from '../../functions/assetBoundingBox';
|
||||
@@ -21,8 +20,7 @@ import { upsertProductOrEventApi } from '../../../../../services/simulation/prod
|
||||
import { getAssetIksApi } from '../../../../../services/simulation/ik/getAssetIKs';
|
||||
import { ModelAnimator } from './animator/modelAnimator';
|
||||
|
||||
|
||||
function Model({ asset, isRendered }: { readonly asset: Asset, isRendered: boolean }) {
|
||||
function Model({ asset, isRendered, loader }: { readonly asset: Asset, isRendered: boolean, loader: GLTFLoader }) {
|
||||
const url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_MARKETPLACE_URL}`;
|
||||
const savedTheme: string = localStorage.getItem("theme") || "light";
|
||||
const { controls, gl } = useThree();
|
||||
@@ -109,11 +107,6 @@ function Model({ asset, isRendered }: { readonly asset: Asset, isRendered: boole
|
||||
}, [isRendered, selectedFloorItem])
|
||||
|
||||
useEffect(() => {
|
||||
const loader = new GLTFLoader();
|
||||
const dracoLoader = new DRACOLoader();
|
||||
|
||||
dracoLoader.setDecoderPath('https://cdn.jsdelivr.net/npm/three@0.160.0/examples/jsm/libs/draco/gltf/');
|
||||
loader.setDRACOLoader(dracoLoader);
|
||||
const loadModel = async () => {
|
||||
try {
|
||||
|
||||
|
||||
@@ -7,10 +7,11 @@ import { useSelectedAsset } from '../../../../store/simulation/useSimulationStor
|
||||
import { useSceneContext } from '../../../scene/sceneContext';
|
||||
|
||||
import Model from './model/model';
|
||||
import { GLTFLoader } from "three/examples/jsm/Addons";
|
||||
|
||||
const distanceWorker = new Worker(new URL("../../../../services/factoryBuilder/webWorkers/distanceWorker.js", import.meta.url));
|
||||
|
||||
function Models() {
|
||||
function Models({ loader }: { loader: GLTFLoader }) {
|
||||
const { controls, camera } = useThree();
|
||||
const { assetStore } = useSceneContext();
|
||||
const { assets } = assetStore();
|
||||
@@ -57,7 +58,7 @@ function Models() {
|
||||
}}
|
||||
>
|
||||
{assets.map((asset) => (
|
||||
<Model key={asset.modelUuid} asset={asset} isRendered={renderMap[asset.modelUuid] ?? false} />
|
||||
<Model key={asset.modelUuid} asset={asset} isRendered={renderMap[asset.modelUuid] ?? false} loader={loader} />
|
||||
))}
|
||||
</group>
|
||||
);
|
||||
|
||||
@@ -95,7 +95,7 @@ export default function Builder() {
|
||||
|
||||
<AssetsGroup plane={plane} />
|
||||
|
||||
{/* <mesh name='Walls-And-WallAssets-Group'>
|
||||
<mesh name='Walls-And-WallAssets-Group'>
|
||||
<Geometry ref={csgRef} useGroups>
|
||||
|
||||
<WallGroup />
|
||||
@@ -103,7 +103,7 @@ export default function Builder() {
|
||||
<WallAssetGroup />
|
||||
|
||||
</Geometry>
|
||||
</mesh> */}
|
||||
</mesh>
|
||||
|
||||
<AislesGroup />
|
||||
|
||||
@@ -113,9 +113,9 @@ export default function Builder() {
|
||||
|
||||
<MeasurementTool />
|
||||
|
||||
{/* <CalculateAreaGroup /> */}
|
||||
<CalculateAreaGroup />
|
||||
|
||||
{/* <NavMesh /> */}
|
||||
<NavMesh />
|
||||
|
||||
<DxfFile />
|
||||
|
||||
|
||||
@@ -44,6 +44,7 @@ function WallAssetInstance({ wallAsset }: { wallAsset: WallAsset }) {
|
||||
|
||||
dracoLoader.setDecoderPath('https://cdn.jsdelivr.net/npm/three@0.160.0/examples/jsm/libs/draco/gltf/');
|
||||
loader.setDRACOLoader(dracoLoader);
|
||||
|
||||
const loadModel = async () => {
|
||||
try {
|
||||
// Check Cache
|
||||
|
||||
@@ -19,7 +19,7 @@ import { getUserData } from "../../../functions/getUserData";
|
||||
const CamModelsGroup = () => {
|
||||
const navigate = useNavigate();
|
||||
const groupRef = useRef<THREE.Group>(null);
|
||||
const { userId, organization, email } = getUserData();
|
||||
const { organization, email } = getUserData();
|
||||
const { setActiveUsers } = useActiveUsers();
|
||||
const { socket } = useSocketStore();
|
||||
const { activeModule } = useModuleStore();
|
||||
@@ -31,14 +31,11 @@ const CamModelsGroup = () => {
|
||||
dracoLoader.setDecoderPath("three/examples/jsm/libs/draco/gltf/");
|
||||
loader.setDRACOLoader(dracoLoader);
|
||||
|
||||
|
||||
const { camMode } = useCamMode();
|
||||
const { camera, controls } = useThree(); // Access R3F camera and controls
|
||||
const { camera, controls } = useThree();
|
||||
|
||||
useEffect(() => {
|
||||
if (camMode !== "FollowPerson") return;
|
||||
// If a user is selected, set the camera view to their location
|
||||
// and update the camera and controls accordingly
|
||||
if (selectedUser?.location) {
|
||||
const { position, rotation, target } = selectedUser.location;
|
||||
if (rotation && target)
|
||||
|
||||
@@ -31,7 +31,7 @@ const CopyPasteControls3D = ({
|
||||
const { assetStore, eventStore } = useSceneContext();
|
||||
const { addEvent } = eventStore();
|
||||
const { projectId } = useParams();
|
||||
const { assets, addAsset, setPosition, updateAsset, removeAsset, getAssetById } = assetStore();
|
||||
const { assets, addAsset, updateAsset, removeAsset, getAssetById } = assetStore();
|
||||
const { selectedVersionStore } = useVersionContext();
|
||||
const { selectedVersion } = selectedVersionStore();
|
||||
const { userId, organization } = getUserData();
|
||||
|
||||
@@ -339,7 +339,7 @@ function MoveControls3D({
|
||||
}
|
||||
|
||||
updateAsset(movedAsset.userData.modelUuid, {
|
||||
position: asset.position,
|
||||
position: [position.x, position.y, position.z],
|
||||
rotation: [movedAsset.rotation.x, movedAsset.rotation.y, movedAsset.rotation.z],
|
||||
});
|
||||
|
||||
|
||||
@@ -1,15 +1,27 @@
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
import { useFrame } from '@react-three/fiber';
|
||||
import { useFrame, useThree } from '@react-three/fiber';
|
||||
import * as THREE from 'three';
|
||||
import { Line, Text } from '@react-three/drei';
|
||||
import { useAnimationPlaySpeed, usePauseButtonStore, usePlayButtonStore, useResetButtonStore } from '../../../../../store/usePlayButtonStore';
|
||||
import { useSceneContext } from '../../../../scene/sceneContext';
|
||||
import { useProductContext } from '../../../products/productContext';
|
||||
|
||||
type PointWithDegree = {
|
||||
position: [number, number, number];
|
||||
degree: number;
|
||||
};
|
||||
|
||||
function RoboticArmAnimator({ HandleCallback, restPosition, ikSolver, targetBone, armBot, path }: any) {
|
||||
interface RoboticArmAnimatorProps {
|
||||
HandleCallback: () => void;
|
||||
restPosition: THREE.Vector3;
|
||||
ikSolver: any;
|
||||
targetBone: string;
|
||||
armBot: ArmBotStatus;
|
||||
path: [number, number, number][];
|
||||
currentPhase: string;
|
||||
}
|
||||
|
||||
function RoboticArmAnimator({ HandleCallback, restPosition, ikSolver, targetBone, armBot, path, currentPhase }: RoboticArmAnimatorProps) {
|
||||
const progressRef = useRef(0);
|
||||
const curveRef = useRef<THREE.Vector3[] | null>(null);
|
||||
const totalDistanceRef = useRef(0);
|
||||
@@ -19,6 +31,14 @@ function RoboticArmAnimator({ HandleCallback, restPosition, ikSolver, targetBone
|
||||
const [circlePoints, setCirclePoints] = useState<[number, number, number][]>([]);
|
||||
const [circlePointsWithDegrees, setCirclePointsWithDegrees] = useState<PointWithDegree[]>([]);
|
||||
const [customCurvePoints, setCustomCurvePoints] = useState<THREE.Vector3[] | null>(null);
|
||||
const { armBotStore, productStore, materialStore } = useSceneContext();
|
||||
const { getArmBotById } = armBotStore();
|
||||
const { getMaterialById } = materialStore();
|
||||
const { getEventByModelUuid } = productStore();
|
||||
const { selectedProductStore } = useProductContext();
|
||||
const { selectedProduct } = selectedProductStore();
|
||||
const { scene } = useThree();
|
||||
|
||||
let curveHeight = 1.75
|
||||
const CIRCLE_RADIUS = 1.6
|
||||
|
||||
@@ -145,8 +165,38 @@ function RoboticArmAnimator({ HandleCallback, restPosition, ikSolver, targetBone
|
||||
useEffect(() => {
|
||||
if (circlePoints.length > 0 && currentPath.length > 0) {
|
||||
|
||||
const start = currentPath[0];
|
||||
const end = currentPath[currentPath.length - 1];
|
||||
let start = currentPath[0];
|
||||
let end = currentPath[currentPath.length - 1];
|
||||
|
||||
const armbotStatus = getArmBotById(armBot.modelUuid);
|
||||
const currentMaterial = armbotStatus?.currentAction?.materialId;
|
||||
if (armbotStatus && currentMaterial && (currentPhase === 'rest-to-start' || currentPhase === 'start-to-end')) {
|
||||
const materialData = getMaterialById(currentMaterial);
|
||||
if (materialData) {
|
||||
const prevModel = getEventByModelUuid(selectedProduct.productUuid, materialData.current.modelUuid);
|
||||
|
||||
if (prevModel && prevModel.type === 'transfer') {
|
||||
const material = scene.getObjectByProperty("uuid", currentMaterial);
|
||||
const armbotModel = scene.getObjectByProperty("uuid", armBot.modelUuid);
|
||||
if (material && armbotModel) {
|
||||
const materialWorldPos = new THREE.Vector3();
|
||||
material.getWorldPosition(materialWorldPos);
|
||||
|
||||
const armbotWorldPos = new THREE.Vector3();
|
||||
armbotModel.getWorldPosition(armbotWorldPos);
|
||||
|
||||
const materialLocalPos = materialWorldPos.clone();
|
||||
armbotModel.worldToLocal(materialLocalPos);
|
||||
|
||||
if (currentPhase === 'rest-to-start') {
|
||||
end = [materialLocalPos.x, materialLocalPos.y + 0.35, materialLocalPos.z];
|
||||
} else if (currentPhase === 'start-to-end') {
|
||||
start = [materialLocalPos.x, materialLocalPos.y + 0.35, materialLocalPos.z];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const raisedStart = [start[0], start[1] + 0.5, start[2]] as [number, number, number];
|
||||
const raisedEnd = [end[0], end[1] + 0.5, end[2]] as [number, number, number];
|
||||
|
||||
@@ -334,7 +334,6 @@ function RoboticArmInstance({ armBot }: { readonly armBot: ArmBotStatus }) {
|
||||
|
||||
}, [currentPhase, armBot, isPlaying, isReset, ikSolver])
|
||||
|
||||
|
||||
function createCurveBetweenTwoPoints(p1: any, p2: any) {
|
||||
const mid = new THREE.Vector3().addVectors(p1, p2).multiplyScalar(0.5);
|
||||
const points = [p1, mid, p2];
|
||||
@@ -342,7 +341,6 @@ function RoboticArmInstance({ armBot }: { readonly armBot: ArmBotStatus }) {
|
||||
}
|
||||
|
||||
const HandleCallback = () => {
|
||||
|
||||
if (armBot.isActive && armBot.state == "running" && currentPhase == "init-to-rest") {
|
||||
logStatus(armBot.modelUuid, "Callback triggered: rest");
|
||||
setArmBotActive(armBot.modelUuid, false)
|
||||
@@ -370,7 +368,6 @@ function RoboticArmInstance({ armBot }: { readonly armBot: ArmBotStatus }) {
|
||||
setArmBotState(armBot.modelUuid, "idle")
|
||||
setCurrentPhase("rest");
|
||||
setPath([])
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -389,7 +386,6 @@ function RoboticArmInstance({ armBot }: { readonly armBot: ArmBotStatus }) {
|
||||
ikSolver={ikSolver}
|
||||
targetBone={targetBone}
|
||||
armBot={armBot}
|
||||
logStatus={logStatus}
|
||||
path={path}
|
||||
currentPhase={currentPhase}
|
||||
/>
|
||||
|
||||
@@ -183,7 +183,11 @@ export default function useDraggableGLTF(
|
||||
targetPosition.z = centerZ + finalLocal.z;
|
||||
|
||||
// Clamp Y axis using variables
|
||||
targetPosition.y = Math.min(Math.max(targetPosition.y, minHeight), maxHeight);
|
||||
|
||||
targetPosition.y = Math.min(
|
||||
Math.max(targetPosition.y, Math.min(minHeight, maxHeight)),
|
||||
Math.max(minHeight, maxHeight)
|
||||
);
|
||||
|
||||
// Convert to local if parent exists
|
||||
if (parent) {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
|
||||
import React, { useEffect, useMemo, useRef, useState } from 'react'
|
||||
import { useEffect, useRef, useState } from 'react'
|
||||
import { useFrame, useThree, ThreeEvent } from '@react-three/fiber';
|
||||
import * as THREE from 'three';
|
||||
import { Line, TransformControls } from '@react-three/drei';
|
||||
import { Line } from '@react-three/drei';
|
||||
import { useAnimationPlaySpeed, usePauseButtonStore, usePlayButtonStore, useResetButtonStore } from '../../../../../store/usePlayButtonStore';
|
||||
import { useSceneContext } from '../../../../scene/sceneContext';
|
||||
import { useActiveTool, useSelectedPath } from '../../../../../store/builder/store';
|
||||
|
||||
Reference in New Issue
Block a user