updated
This commit is contained in:
@@ -1,142 +1,164 @@
|
||||
import { GLTF, GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader';
|
||||
import { toast } from 'react-toastify';
|
||||
import * as THREE from 'three';
|
||||
import { GLTF, GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
|
||||
import { toast } from "react-toastify";
|
||||
import * as THREE from "three";
|
||||
import * as Types from "../../../../types/world/worldTypes";
|
||||
import * as CONSTANTS from '../../../../types/world/worldConstants';
|
||||
import { Socket } from 'socket.io-client';
|
||||
import { retrieveGLTF, storeGLTF } from '../../../../utils/indexDB/idbUtils';
|
||||
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader';
|
||||
import * as CONSTANTS from "../../../../types/world/worldConstants";
|
||||
import { Socket } from "socket.io-client";
|
||||
import { retrieveGLTF, storeGLTF } from "../../../../utils/indexDB/idbUtils";
|
||||
import { DRACOLoader } from "three/examples/jsm/loaders/DRACOLoader";
|
||||
import { getUserData } from "../../../../functions/getUserData";
|
||||
|
||||
async function AddWallItems(
|
||||
selected: any,
|
||||
raycaster: THREE.Raycaster,
|
||||
CSGGroup: Types.RefMesh,
|
||||
setWallItems: Types.setWallItemSetState,
|
||||
socket: Socket<any>,
|
||||
projectId?: string
|
||||
selected: any,
|
||||
raycaster: THREE.Raycaster,
|
||||
CSGGroup: Types.RefMesh,
|
||||
setWallItems: Types.setWallItemSetState,
|
||||
socket: Socket<any>,
|
||||
projectId?: string,
|
||||
versionId?: string
|
||||
): Promise<void> {
|
||||
let intersects = raycaster?.intersectObject(CSGGroup.current!, true);
|
||||
const wallRaycastIntersection = intersects?.find((child) => child.object.name.includes("WallRaycastReference"));
|
||||
let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_MARKETPLACE_URL}`;
|
||||
|
||||
if (!wallRaycastIntersection) return;
|
||||
const { userId, organization } = getUserData();
|
||||
let intersects = raycaster?.intersectObject(CSGGroup.current!, true);
|
||||
const wallRaycastIntersection = intersects?.find((child) =>
|
||||
child.object.name.includes("WallRaycastReference")
|
||||
);
|
||||
let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_MARKETPLACE_URL}`;
|
||||
|
||||
const intersectionPoint = wallRaycastIntersection;
|
||||
const loader = new GLTFLoader();
|
||||
const dracoLoader = new DRACOLoader();
|
||||
if (!wallRaycastIntersection) return;
|
||||
|
||||
dracoLoader.setDecoderPath('https://cdn.jsdelivr.net/npm/three@0.160.0/examples/jsm/libs/draco/gltf/');
|
||||
loader.setDRACOLoader(dracoLoader);
|
||||
const intersectionPoint = wallRaycastIntersection;
|
||||
const loader = new GLTFLoader();
|
||||
const dracoLoader = new DRACOLoader();
|
||||
|
||||
// Check THREE.js cache first
|
||||
const cachedModel = THREE.Cache.get(selected.id);
|
||||
if (cachedModel) {
|
||||
handleModelLoad(cachedModel);
|
||||
return;
|
||||
dracoLoader.setDecoderPath(
|
||||
"https://cdn.jsdelivr.net/npm/three@0.160.0/examples/jsm/libs/draco/gltf/"
|
||||
);
|
||||
loader.setDRACOLoader(dracoLoader);
|
||||
|
||||
// Check THREE.js cache first
|
||||
const cachedModel = THREE.Cache.get(selected.id);
|
||||
if (cachedModel) {
|
||||
handleModelLoad(cachedModel);
|
||||
return;
|
||||
}
|
||||
|
||||
// Check IndexedDB cache
|
||||
const cachedModelBlob = await retrieveGLTF(selected.id);
|
||||
if (cachedModelBlob) {
|
||||
const blobUrl = URL.createObjectURL(cachedModelBlob);
|
||||
loader.load(blobUrl, (gltf) => {
|
||||
URL.revokeObjectURL(blobUrl);
|
||||
THREE.Cache.remove(blobUrl);
|
||||
THREE.Cache.add(selected.id, gltf);
|
||||
handleModelLoad(gltf);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// Load from backend if not in any cache
|
||||
loader.load(
|
||||
`${url_Backend_dwinzo}/api/v2/AssetFile/${selected.id}`,
|
||||
async (gltf) => {
|
||||
try {
|
||||
const modelBlob = await fetch(
|
||||
`${url_Backend_dwinzo}/api/v2/AssetFile/${selected.id}`
|
||||
).then((res) => res.blob());
|
||||
await storeGLTF(selected.id, modelBlob);
|
||||
THREE.Cache.add(selected.id, gltf);
|
||||
await handleModelLoad(gltf);
|
||||
} catch (error) {
|
||||
console.error("Failed to cache model:", error);
|
||||
handleModelLoad(gltf);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// Check IndexedDB cache
|
||||
const cachedModelBlob = await retrieveGLTF(selected.id);
|
||||
if (cachedModelBlob) {
|
||||
const blobUrl = URL.createObjectURL(cachedModelBlob);
|
||||
loader.load(blobUrl, (gltf) => {
|
||||
URL.revokeObjectURL(blobUrl);
|
||||
THREE.Cache.remove(blobUrl);
|
||||
THREE.Cache.add(selected.id, gltf);
|
||||
handleModelLoad(gltf);
|
||||
});
|
||||
return;
|
||||
}
|
||||
async function handleModelLoad(gltf: GLTF) {
|
||||
const model = gltf.scene.clone();
|
||||
model.userData = { wall: intersectionPoint.object.parent };
|
||||
|
||||
// Load from backend if not in any cache
|
||||
loader.load(`${url_Backend_dwinzo}/api/v2/AssetFile/${selected.id}`, async (gltf) => {
|
||||
try {
|
||||
const modelBlob = await fetch(`${url_Backend_dwinzo}/api/v2/AssetFile/${selected.id}`).then((res) => res.blob());
|
||||
await storeGLTF(selected.id, modelBlob);
|
||||
THREE.Cache.add(selected.id, gltf);
|
||||
await handleModelLoad(gltf);
|
||||
} catch (error) {
|
||||
console.error('Failed to cache model:', error);
|
||||
handleModelLoad(gltf);
|
||||
}
|
||||
model.children[0].children.forEach((child) => {
|
||||
if (child.name !== "CSG_REF") {
|
||||
child.castShadow = true;
|
||||
child.receiveShadow = true;
|
||||
}
|
||||
});
|
||||
|
||||
async function handleModelLoad(gltf: GLTF) {
|
||||
const model = gltf.scene.clone();
|
||||
model.userData = { wall: intersectionPoint.object.parent };
|
||||
const boundingBox = new THREE.Box3().setFromObject(model);
|
||||
const size = new THREE.Vector3();
|
||||
boundingBox.getSize(size);
|
||||
|
||||
model.children[0].children.forEach((child) => {
|
||||
if (child.name !== "CSG_REF") {
|
||||
child.castShadow = true;
|
||||
child.receiveShadow = true;
|
||||
}
|
||||
});
|
||||
const csgscale = [size.x, size.y, size.z] as [number, number, number];
|
||||
|
||||
const boundingBox = new THREE.Box3().setFromObject(model);
|
||||
const size = new THREE.Vector3();
|
||||
boundingBox.getSize(size);
|
||||
const center = new THREE.Vector3();
|
||||
boundingBox.getCenter(center);
|
||||
const csgposition = [center.x, center.y, center.z] as [
|
||||
number,
|
||||
number,
|
||||
number
|
||||
];
|
||||
|
||||
const csgscale = [size.x, size.y, size.z] as [number, number, number];
|
||||
|
||||
const center = new THREE.Vector3();
|
||||
boundingBox.getCenter(center);
|
||||
const csgposition = [center.x, center.y, center.z] as [number, number, number];
|
||||
|
||||
let positionY = selected.subCategory === 'fixed-move' ? 0 : intersectionPoint.point.y;
|
||||
if (positionY === 0) {
|
||||
positionY = Math.floor(intersectionPoint.point.y / CONSTANTS.wallConfig.height) * CONSTANTS.wallConfig.height;
|
||||
}
|
||||
|
||||
const newWallItem = {
|
||||
type: selected.subCategory,
|
||||
model: model,
|
||||
modelName: selected.name,
|
||||
assetId: selected.id,
|
||||
scale: [1, 1, 1] as [number, number, number],
|
||||
csgscale: csgscale,
|
||||
csgposition: csgposition,
|
||||
position: [intersectionPoint.point.x, positionY, intersectionPoint.point.z] as [number, number, number],
|
||||
quaternion: intersectionPoint.object.quaternion.clone() as Types.QuaternionType
|
||||
};
|
||||
|
||||
const email = localStorage.getItem('email');
|
||||
const organization = email ? (email.split("@")[1]).split(".")[0] : 'default';
|
||||
const userId = localStorage.getItem("userId");
|
||||
|
||||
const data = {
|
||||
organization: organization,
|
||||
modelUuid: model.uuid,
|
||||
modelName: newWallItem.modelName,
|
||||
assetId: selected.id,
|
||||
type: selected.subCategory,
|
||||
csgposition: newWallItem.csgposition,
|
||||
csgscale: newWallItem.csgscale,
|
||||
position: newWallItem.position,
|
||||
quaternion: newWallItem.quaternion,
|
||||
scale: newWallItem.scale,
|
||||
socketId: socket.id,
|
||||
projectId,
|
||||
userId
|
||||
};
|
||||
|
||||
socket.emit('v1:wallItems:set', data);
|
||||
|
||||
setWallItems((prevItems) => {
|
||||
const updatedItems = [...prevItems, newWallItem];
|
||||
|
||||
const WallItemsForStorage = updatedItems.map(item => {
|
||||
const { model, ...rest } = item;
|
||||
return {
|
||||
...rest,
|
||||
modelUuid: model?.uuid,
|
||||
};
|
||||
});
|
||||
|
||||
localStorage.setItem("WallItems", JSON.stringify(WallItemsForStorage));
|
||||
echo.success("Model Added!");
|
||||
return updatedItems;
|
||||
});
|
||||
let positionY =
|
||||
selected.subCategory === "fixed-move" ? 0 : intersectionPoint.point.y;
|
||||
if (positionY === 0) {
|
||||
positionY =
|
||||
Math.floor(intersectionPoint.point.y / CONSTANTS.wallConfig.height) *
|
||||
CONSTANTS.wallConfig.height;
|
||||
}
|
||||
|
||||
const newWallItem = {
|
||||
type: selected.subCategory,
|
||||
model: model,
|
||||
modelName: selected.name,
|
||||
assetId: selected.id,
|
||||
scale: [1, 1, 1] as [number, number, number],
|
||||
csgscale: csgscale,
|
||||
csgposition: csgposition,
|
||||
position: [
|
||||
intersectionPoint.point.x,
|
||||
positionY,
|
||||
intersectionPoint.point.z,
|
||||
] as [number, number, number],
|
||||
quaternion:
|
||||
intersectionPoint.object.quaternion.clone() as Types.QuaternionType,
|
||||
};
|
||||
|
||||
const data = {
|
||||
organization,
|
||||
modelUuid: model.uuid,
|
||||
modelName: newWallItem.modelName,
|
||||
assetId: selected.id,
|
||||
type: selected.subCategory,
|
||||
csgposition: newWallItem.csgposition,
|
||||
csgscale: newWallItem.csgscale,
|
||||
position: newWallItem.position,
|
||||
quaternion: newWallItem.quaternion,
|
||||
scale: newWallItem.scale,
|
||||
socketId: socket.id,
|
||||
versionId,
|
||||
projectId,
|
||||
userId,
|
||||
};
|
||||
|
||||
socket.emit("v1:wallItems:set", data);
|
||||
|
||||
setWallItems((prevItems) => {
|
||||
const updatedItems = [...prevItems, newWallItem];
|
||||
|
||||
const WallItemsForStorage = updatedItems.map((item) => {
|
||||
const { model, ...rest } = item;
|
||||
return {
|
||||
...rest,
|
||||
modelUuid: model?.uuid,
|
||||
};
|
||||
});
|
||||
|
||||
localStorage.setItem("WallItems", JSON.stringify(WallItemsForStorage));
|
||||
echo.success("Model Added!");
|
||||
return updatedItems;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export default AddWallItems;
|
||||
export default AddWallItems;
|
||||
|
||||
Reference in New Issue
Block a user