Merge remote-tracking branch 'origin/main-dev' into main-demo
This commit is contained in:
@@ -44,9 +44,7 @@ function AssetsGroup({ plane }: { readonly plane: RefMesh }) {
|
||||
const loader = new GLTFLoader();
|
||||
const dracoLoader = new DRACOLoader();
|
||||
|
||||
dracoLoader.setDecoderPath(
|
||||
"https://cdn.jsdelivr.net/npm/three@0.160.0/examples/jsm/libs/draco/gltf/"
|
||||
);
|
||||
dracoLoader.setDecoderPath("https://cdn.jsdelivr.net/npm/three@0.160.0/examples/jsm/libs/draco/gltf/");
|
||||
loader.setDRACOLoader(dracoLoader);
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
@@ -1,20 +1,51 @@
|
||||
import { Box3, BoxGeometry, EdgesGeometry, Vector3 } from "three";
|
||||
import { Line } from "@react-three/drei";
|
||||
import { Box3, Vector3 } from "three";
|
||||
import { useMemo } from "react";
|
||||
|
||||
export const AssetBoundingBox = ({ name, boundingBox, color, lineWidth }: { name: string; boundingBox: Box3 | null; color: string; lineWidth: number; }) => {
|
||||
const { points, size, center } = useMemo(() => {
|
||||
if (!boundingBox) { return { points: [], center: new Vector3(), size: new Vector3(), }; }
|
||||
|
||||
const min = boundingBox.min;
|
||||
const max = boundingBox.max;
|
||||
const center = boundingBox.getCenter(new Vector3());
|
||||
const size = boundingBox.getSize(new Vector3());
|
||||
|
||||
const edges: Array<[number, number, number]> = [
|
||||
[min.x, min.y, min.z], [max.x, min.y, min.z],
|
||||
[max.x, min.y, min.z], [max.x, max.y, min.z],
|
||||
[max.x, max.y, min.z], [min.x, max.y, min.z],
|
||||
[min.x, max.y, min.z], [min.x, min.y, min.z],
|
||||
|
||||
[min.x, min.y, max.z], [max.x, min.y, max.z],
|
||||
[max.x, min.y, max.z], [max.x, max.y, max.z],
|
||||
[max.x, max.y, max.z], [min.x, max.y, max.z],
|
||||
[min.x, max.y, max.z], [min.x, min.y, max.z],
|
||||
|
||||
[min.x, min.y, min.z], [min.x, min.y, max.z],
|
||||
[max.x, min.y, min.z], [max.x, min.y, max.z],
|
||||
[max.x, max.y, min.z], [max.x, max.y, max.z],
|
||||
[min.x, max.y, min.z], [min.x, max.y, max.z],
|
||||
];
|
||||
|
||||
return { points: edges, center, size };
|
||||
}, [boundingBox]);
|
||||
|
||||
export const AssetBoundingBox = ({ boundingBox }: { 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 (
|
||||
<group name='Asset FallBack'>
|
||||
<lineSegments position={center}>
|
||||
<bufferGeometry attach="geometry" {...edges} />
|
||||
<lineBasicMaterial depthWrite={false} attach="material" color="gray" linewidth={1} />
|
||||
</lineSegments>
|
||||
<group name={name}>
|
||||
<Line
|
||||
segments
|
||||
depthWrite={false}
|
||||
points={points}
|
||||
color={color}
|
||||
lineWidth={lineWidth}
|
||||
/>
|
||||
|
||||
<mesh visible={false} position={center}>
|
||||
<boxGeometry args={[size.x, size.y, size.z]} />
|
||||
</mesh>
|
||||
</group>
|
||||
);
|
||||
};
|
||||
};
|
||||
|
||||
@@ -4,7 +4,7 @@ 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, useFrame, useThree } from '@react-three/fiber';
|
||||
import { useActiveTool, useDeletableFloorItem, useLimitDistance, useRenderDistance, useSelectedFloorItem, useSocketStore, useToggleView, useToolMode } from '../../../../../store/builder/store';
|
||||
import { useActiveTool, useDeletableFloorItem, useLimitDistance, useRenderDistance, useSelectedAssets, useSelectedFloorItem, useSocketStore, useToggleView, useToolMode } from '../../../../../store/builder/store';
|
||||
import { AssetBoundingBox } from '../../functions/assetBoundingBox';
|
||||
import { CameraControls } from '@react-three/drei';
|
||||
import useModuleStore, { useSubModuleStore } from '../../../../../store/useModuleStore';
|
||||
@@ -22,6 +22,7 @@ import { getAssetIksApi } from '../../../../../services/simulation/ik/getAssetIK
|
||||
|
||||
function Model({ asset }: { readonly asset: Asset }) {
|
||||
const url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_MARKETPLACE_URL}`;
|
||||
const savedTheme: string = localStorage.getItem("theme") || "light";
|
||||
const { camera, controls, gl } = useThree();
|
||||
const { activeTool } = useActiveTool();
|
||||
const { toolMode } = useToolMode();
|
||||
@@ -51,6 +52,7 @@ function Model({ asset }: { readonly asset: Asset }) {
|
||||
const [isRendered, setIsRendered] = useState(false);
|
||||
const [gltfScene, setGltfScene] = useState<GLTF["scene"] | null>(null);
|
||||
const [boundingBox, setBoundingBox] = useState<THREE.Box3 | null>(null);
|
||||
const [isSelected, setIsSelected] = useState(false);
|
||||
const groupRef = useRef<THREE.Group>(null);
|
||||
const mixerRef = useRef<THREE.AnimationMixer>();
|
||||
const actions = useRef<{ [name: string]: THREE.AnimationAction }>({});
|
||||
@@ -62,6 +64,7 @@ function Model({ asset }: { readonly asset: Asset }) {
|
||||
const { selectedVersion } = selectedVersionStore();
|
||||
const { userId, organization } = getUserData();
|
||||
const { projectId } = useParams();
|
||||
const { selectedAssets } = useSelectedAssets();
|
||||
|
||||
const updateBackend = (
|
||||
productName: string,
|
||||
@@ -456,6 +459,18 @@ function Model({ asset }: { readonly asset: Asset }) {
|
||||
|
||||
}, [gl])
|
||||
|
||||
useEffect(() => {
|
||||
if (selectedAssets.length > 0) {
|
||||
if (selectedAssets.some((selectedAsset: THREE.Object3D) => selectedAsset.userData.modelUuid === asset.modelUuid)) {
|
||||
setIsSelected(true);
|
||||
} else {
|
||||
setIsSelected(false);
|
||||
}
|
||||
} else {
|
||||
setIsSelected(false);
|
||||
}
|
||||
}, [selectedAssets])
|
||||
|
||||
return (
|
||||
<group
|
||||
key={asset.modelUuid}
|
||||
@@ -496,11 +511,16 @@ function Model({ asset }: { readonly asset: Asset }) {
|
||||
}}
|
||||
>
|
||||
{gltfScene && (
|
||||
isRendered ? (
|
||||
<primitive object={gltfScene} />
|
||||
) : (
|
||||
<AssetBoundingBox boundingBox={boundingBox} />
|
||||
)
|
||||
<>
|
||||
{isRendered ? (
|
||||
<primitive object={gltfScene} />
|
||||
) : (
|
||||
<AssetBoundingBox name='Asset Fallback' boundingBox={boundingBox} color='gray' lineWidth={1} />
|
||||
)}
|
||||
{isSelected &&
|
||||
<AssetBoundingBox name='Asset BBox' boundingBox={boundingBox} color={savedTheme === "dark" ? "#c4abf1" : "#6f42c1"} lineWidth={2.7} />
|
||||
}
|
||||
</>
|
||||
)}
|
||||
</group>
|
||||
);
|
||||
|
||||
@@ -242,7 +242,7 @@ function WallAssetInstance({ wallAsset }: { wallAsset: WallAsset }) {
|
||||
visible={wallAsset.isVisible}
|
||||
userData={wallAsset}
|
||||
>
|
||||
<Subtraction position={[center.x, center.y, center.z]} scale={[size.x, size.y, wall.wallThickness + 0.05]}>
|
||||
<Subtraction position={[center.x, center.y, 0]} scale={[size.x, size.y, wall.wallThickness + 0.05]}>
|
||||
<Geometry>
|
||||
<Base geometry={new THREE.BoxGeometry()} />
|
||||
</Geometry>
|
||||
@@ -265,7 +265,7 @@ function WallAssetInstance({ wallAsset }: { wallAsset: WallAsset }) {
|
||||
e.stopPropagation();
|
||||
let currentObject = e.object as THREE.Object3D;
|
||||
while (currentObject) {
|
||||
if (currentObject.name === "Scene") {
|
||||
if (currentObject.userData.wallUuid) {
|
||||
break;
|
||||
}
|
||||
currentObject = currentObject.parent as THREE.Object3D;
|
||||
@@ -286,7 +286,7 @@ function WallAssetInstance({ wallAsset }: { wallAsset: WallAsset }) {
|
||||
e.stopPropagation();
|
||||
let currentObject = e.object as THREE.Object3D;
|
||||
while (currentObject) {
|
||||
if (currentObject.name === "Scene") {
|
||||
if (currentObject.userData.wallUuid) {
|
||||
break;
|
||||
}
|
||||
currentObject = currentObject.parent as THREE.Object3D;
|
||||
|
||||
Reference in New Issue
Block a user