realTimeVisulization #34

Merged
Vishnu merged 12 commits from realTimeVisulization into main 2025-04-02 12:57:21 +00:00
10 changed files with 247 additions and 137 deletions
Showing only changes of commit d2be2094eb - Show all commits

View File

@@ -24,26 +24,42 @@ interface AssetProp {
price?: number; price?: number;
CreatedBy?: String; CreatedBy?: String;
} }
interface CategoryListProp {
assetImage?: string;
assetName?: string;
categoryImage: string;
category: string;
}
const Assets: React.FC = () => { const Assets: React.FC = () => {
const { setSelectedItem } = useSelectedItem(); const { setSelectedItem } = useSelectedItem();
const [searchValue, setSearchValue] = useState<string>(""); const [searchValue, setSearchValue] = useState<string>("");
const [selectedCategory, setSelectedCategory] = useState<string | null>(null); const [selectedCategory, setSelectedCategory] = useState<string | null>(null);
const [categoryAssets, setCategoryAssets] = useState<AssetProp[]>([]); const [categoryAssets, setCategoryAssets] = useState<AssetProp[]>([]);
const [filtereredAssets, setFiltereredAssets] = useState<AssetProp[]>([]); const [filtereredAssets, setFiltereredAssets] = useState<AssetProp[]>([]);
const [categoryList, setCategoryList] = useState<CategoryListProp[]>([]);
const handleSearchChange = (value: string) => { const handleSearchChange = (value: string) => {
const searchTerm = value.toLowerCase();
setSearchValue(value); setSearchValue(value);
setSelectedCategory(null); if (searchTerm.trim() === "" && !selectedCategory) {
const searchTerm = value.toLowerCase(); // Convert input to lowercase setCategoryAssets([]);
return;
}
const filteredModels = filtereredAssets?.filter((model) => { const filteredModels = filtereredAssets?.filter((model) => {
if (!model?.tags || !model?.filename) return false; if (!model?.tags || !model?.filename || !model?.category) return false;
if (searchTerm.startsWith(":") && searchTerm.length > 1) { if (searchTerm.startsWith(":") && searchTerm.length > 1) {
const tagSearchTerm = searchTerm.slice(1); const tagSearchTerm = searchTerm.slice(1);
return model.tags.toLowerCase().includes(tagSearchTerm); return model.tags.toLowerCase().includes(tagSearchTerm);
} else if (!searchTerm.startsWith(":")) { } else if (selectedCategory) {
return (
model.category
.toLowerCase()
.includes(selectedCategory.toLowerCase()) &&
model.filename.toLowerCase().includes(searchTerm)
);
} else {
return model.filename.toLowerCase().includes(searchTerm); return model.filename.toLowerCase().includes(searchTerm);
} }
return false;
}); });
setCategoryAssets(filteredModels); setCategoryAssets(filteredModels);
@@ -56,10 +72,10 @@ const Assets: React.FC = () => {
} catch {} } catch {}
}; };
filteredAssets(); filteredAssets();
}, []); }, [categoryAssets]);
const categoryList = useMemo( useEffect(() => {
() => [ setCategoryList([
{ {
assetName: "Doors", assetName: "Doors",
assetImage: "", assetImage: "",
@@ -82,10 +98,8 @@ const Assets: React.FC = () => {
{ category: "Workstation", categoryImage: workStation }, { category: "Workstation", categoryImage: workStation },
{ category: "Machines", categoryImage: machines }, { category: "Machines", categoryImage: machines },
{ category: "Workers", categoryImage: worker }, { category: "Workers", categoryImage: worker },
], ]);
[] }, []);
);
const fetchCategoryAssets = async (asset: any) => { const fetchCategoryAssets = async (asset: any) => {
setSelectedCategory(asset); setSelectedCategory(asset);
if (asset === "Feneration") { if (asset === "Feneration") {
@@ -127,7 +141,7 @@ const Assets: React.FC = () => {
<div className="assets-result"> <div className="assets-result">
<div className="assets-wrapper"> <div className="assets-wrapper">
<div className="searched-content"> <div className="searched-content">
<p>Results for "{searchValue}"</p> <p>Results for {searchValue}</p>
</div> </div>
</div> </div>
<div className="assets-container"> <div className="assets-container">
@@ -155,10 +169,12 @@ const Assets: React.FC = () => {
</div> </div>
) : selectedCategory ? ( ) : selectedCategory ? (
<div className="assets-wrapper"> <div className="assets-wrapper">
{/* Back Button */}
<div <div
className="back-button" className="back-button"
onClick={() => setSelectedCategory(null)} onClick={() => {
setSelectedCategory(null);
setCategoryAssets([]);
}}
> >
Back Back
</div> </div>

View File

@@ -13,6 +13,7 @@ import {
useSelectedWallItem, useSelectedWallItem,
useShadows, useShadows,
useSocketStore, useSocketStore,
useTileDistance,
useToggleView, useToggleView,
useWallVisibility, useWallVisibility,
} from "../../../../store/store"; } from "../../../../store/store";
@@ -29,14 +30,18 @@ const GlobalProperties: React.FC = () => {
const { elevation, setElevation } = useElevation(); const { elevation, setElevation } = useElevation();
const { azimuth, setAzimuth } = useAzimuth(); const { azimuth, setAzimuth } = useAzimuth();
const { renderDistance, setRenderDistance } = useRenderDistance(); const { renderDistance, setRenderDistance } = useRenderDistance();
const { setPlaneValue, setGridValue, planeValue, gridValue } =
useTileDistance();
useEffect(() => {
console.log(gridValue, planeValue, "values");
}, [gridValue, planeValue]);
const { socket } = useSocketStore(); const { socket } = useSocketStore();
const { limitDistance, setLimitDistance } = useLimitDistance(); const { limitDistance, setLimitDistance } = useLimitDistance();
const [distance, setDistance] = useState<number>(40); const [distance, setDistance] = useState<number>(40);
useEffect(() => {}, [limitDistance]); useEffect(() => {}, [limitDistance]);
const [limitGridDistance, setLimitGridDistance] = useState(false); const [limitGridDistance, setLimitGridDistance] = useState(false);
const [gridDistance, setGridDistance] = useState<number>(5); const [gridDistance, setGridDistance] = useState<number>(3);
const optimizeScene = async (value: any) => { const optimizeScene = async (value: any) => {
const email = localStorage.getItem("email"); const email = localStorage.getItem("email");
@@ -89,7 +94,15 @@ const GlobalProperties: React.FC = () => {
} }
function updateGridDistance(value: number) { function updateGridDistance(value: number) {
setGridDistance(value); setGridDistance(value);
// setGridValue({ size: value * 100, divisions: (value * 100) / 4 });
// setPlaneValue({ height: value * 100, width: value * 100 });
} }
function updatedGrid(value: number) {
console.log(" (value * 100) / 4 : ", (value * 100) / 4);
setGridValue({ size: value * 100, divisions: (value * 100) / 4 });
setPlaneValue({ height: value * 100, width: value * 100 });
}
const updatedDist = async (value: number) => { const updatedDist = async (value: number) => {
const email = localStorage.getItem("email"); const email = localStorage.getItem("email");
const organization = email?.split("@")[1]?.split(".")[0] || "defaultOrg"; const organization = email?.split("@")[1]?.split(".")[0] || "defaultOrg";
@@ -266,6 +279,7 @@ const GlobalProperties: React.FC = () => {
max={CONSTANTS.distanceConfig.maxDistance} max={CONSTANTS.distanceConfig.maxDistance}
onChange={(value: number) => updateDistance(value)} onChange={(value: number) => updateDistance(value)}
onPointerUp={updatedDist} onPointerUp={updatedDist}
key={"6"}
/> />
<div className="split"></div> <div className="split"></div>
@@ -283,7 +297,10 @@ const GlobalProperties: React.FC = () => {
disabled={!limitGridDistance} disabled={!limitGridDistance}
value={gridDistance} value={gridDistance}
key={"7"} key={"7"}
min={1}
max={5}
onChange={(value: number) => updateGridDistance(value)} onChange={(value: number) => updateGridDistance(value)}
onPointerUp={updatedGrid}
/> />
</div> </div>
); );

View File

@@ -1,10 +1,11 @@
import React, { useState } from "react"; import React, { useEffect, useState } from "react";
import RenderOverlay from "./Overlay"; import RenderOverlay from "./Overlay";
import { ArrowIcon, CloseIcon } from "../icons/ExportCommonIcons"; import { ArrowIcon, CloseIcon } from "../icons/ExportCommonIcons";
import { AccessOption, User } from "../../types/users"; import { AccessOption, User } from "../../types/users";
import RegularDropDown from "../ui/inputs/RegularDropDown"; import RegularDropDown from "../ui/inputs/RegularDropDown";
import { access } from "fs"; import { access } from "fs";
import MultiEmailInvite from "../ui/inputs/MultiEmailInvite"; import MultiEmailInvite from "../ui/inputs/MultiEmailInvite";
import { useActiveUsers } from "../../store/store";
interface UserListTemplateProps { interface UserListTemplateProps {
user: User; user: User;
@@ -57,6 +58,10 @@ interface CollaborateProps {
const CollaborationPopup: React.FC<CollaborateProps> = ({ const CollaborationPopup: React.FC<CollaborateProps> = ({
setUserManagement, setUserManagement,
}) => { }) => {
const { activeUsers } = useActiveUsers();
useEffect(() => {
console.log("activeUsers: ", activeUsers);
}, [activeUsers]);
const userName = localStorage.getItem("userName") || "Anonymous"; const userName = localStorage.getItem("userName") || "Anonymous";
const users = [ const users = [
{ {

View File

@@ -38,7 +38,6 @@ const Card: React.FC<CardProps> = ({
description, description,
onSelectCard, onSelectCard,
}) => { }) => {
console.log('description: ', description);
const handleCardSelect = () => { const handleCardSelect = () => {
onSelectCard({ assetName, uploadedOn, price, rating, views, description }); onSelectCard({ assetName, uploadedOn, price, rating, views, description });
}; };

View File

@@ -25,7 +25,6 @@ const MarketPlace = () => {
const filteredAssets = async () => { const filteredAssets = async () => {
try { try {
const filt = await getAssetImages("67d934ad0f42a1fdadb19aa6"); const filt = await getAssetImages("67d934ad0f42a1fdadb19aa6");
setModels(filt.items); setModels(filt.items);
setFilteredModels(filt.items); setFilteredModels(filt.items);
} catch {} } catch {}

View File

@@ -1,22 +1,52 @@
import { useToggleView } from '../../../store/store'; import { useTileDistance, useToggleView } from "../../../store/store";
import * as CONSTANTS from '../../../types/world/worldConstants'; import * as CONSTANTS from "../../../types/world/worldConstants";
const Ground = ({ grid, plane }: any) => { const Ground = ({ grid, plane }: any) => {
const { toggleView } = useToggleView(); const { toggleView } = useToggleView();
const savedTheme: string | null = localStorage.getItem('theme'); const savedTheme: string | null = localStorage.getItem("theme");
const { planeValue, gridValue } = useTileDistance();
return ( return (
<mesh name="Ground">
<mesh name="Ground"> <mesh
<mesh ref={grid} name="Grid" position={!toggleView ? CONSTANTS.gridConfig.position3D : CONSTANTS.gridConfig.position2D}> ref={grid}
<gridHelper args={[CONSTANTS.gridConfig.size, CONSTANTS.gridConfig.divisions, CONSTANTS.gridConfig.primaryColor, CONSTANTS.gridConfig.secondaryColor]} /> name="Grid"
</mesh> position={
<mesh ref={plane} rotation-x={CONSTANTS.planeConfig.rotation} position={!toggleView ? CONSTANTS.planeConfig.position3D : CONSTANTS.planeConfig.position2D} name="Plane" receiveShadow> !toggleView
<planeGeometry args={[CONSTANTS.planeConfig.width, CONSTANTS.planeConfig.height]} /> ? CONSTANTS.gridConfig.position3D
<meshBasicMaterial color={CONSTANTS.planeConfig.color} /> : CONSTANTS.gridConfig.position2D
</mesh> }
</mesh> >
) <gridHelper
} args={[
gridValue.size,
gridValue.divisions,
// CONSTANTS.gridConfig.size,
// CONSTANTS.gridConfig.divisions,
CONSTANTS.gridConfig.primaryColor,
CONSTANTS.gridConfig.secondaryColor,
]}
/>
</mesh>
<mesh
ref={plane}
rotation-x={CONSTANTS.planeConfig.rotation}
position={
!toggleView
? CONSTANTS.planeConfig.position3D
: CONSTANTS.planeConfig.position2D
}
name="Plane"
receiveShadow
>
<planeGeometry
args={[planeValue.width, planeValue.height]}
// args={[CONSTANTS.planeConfig.width, CONSTANTS.planeConfig.height]}
/>
<meshBasicMaterial color={CONSTANTS.planeConfig.color} />
</mesh>
</mesh>
);
};
export default Ground; export default Ground;

View File

@@ -1,9 +1,22 @@
import { useRef, useEffect} from 'react'; import { useRef, useEffect } from "react";
import { useThree } from '@react-three/fiber'; import { useThree } from "@react-three/fiber";
import * as THREE from 'three'; import * as THREE from "three";
import { useAzimuth, useElevation, useShadows, useSunPosition, useFloorItems, useWallItems } from '../../../store/store'; import {
import * as CONSTANTS from '../../../types/world/worldConstants'; useAzimuth,
const shadowWorker = new Worker(new URL('../../../services/factoryBuilder/webWorkers/shadowWorker', import.meta.url)); useElevation,
useShadows,
useSunPosition,
useFloorItems,
useWallItems,
useTileDistance,
} from "../../../store/store";
import * as CONSTANTS from "../../../types/world/worldConstants";
const shadowWorker = new Worker(
new URL(
"../../../services/factoryBuilder/webWorkers/shadowWorker",
import.meta.url
)
);
export default function Shadows() { export default function Shadows() {
const { shadows, setShadows } = useShadows(); const { shadows, setShadows } = useShadows();
@@ -15,6 +28,7 @@ export default function Shadows() {
const { azimuth, setAzimuth } = useAzimuth(); const { azimuth, setAzimuth } = useAzimuth();
const { floorItems } = useFloorItems(); const { floorItems } = useFloorItems();
const { wallItems } = useWallItems(); const { wallItems } = useWallItems();
const { planeValue } = useTileDistance();
useEffect(() => { useEffect(() => {
gl.shadowMap.enabled = true; gl.shadowMap.enabled = true;
@@ -48,9 +62,9 @@ export default function Shadows() {
useEffect(() => { useEffect(() => {
if (controls && shadows) { if (controls && shadows) {
updateShadows(); updateShadows();
(controls as any).addEventListener('update', updateShadows); (controls as any).addEventListener("update", updateShadows);
return () => { return () => {
(controls as any).removeEventListener('update', updateShadows); (controls as any).removeEventListener("update", updateShadows);
}; };
} }
}, [controls, elevation, azimuth, shadows]); }, [controls, elevation, azimuth, shadows]);
@@ -75,10 +89,24 @@ export default function Shadows() {
shadow-normalBias={CONSTANTS.shadowConfig.shadownormalBias} shadow-normalBias={CONSTANTS.shadowConfig.shadownormalBias}
/> />
<object3D ref={targetRef} /> <object3D ref={targetRef} />
<mesh position={CONSTANTS.shadowConfig.shadowMaterialPosition} rotation={CONSTANTS.shadowConfig.shadowMaterialRotation} receiveShadow> <mesh
<planeGeometry args={[CONSTANTS.planeConfig.width, CONSTANTS.planeConfig.height]} /> position={CONSTANTS.shadowConfig.shadowMaterialPosition}
<shadowMaterial opacity={CONSTANTS.shadowConfig.shadowMaterialOpacity} transparent /> rotation={CONSTANTS.shadowConfig.shadowMaterialRotation}
receiveShadow
>
{/* <planeGeometry
args={[CONSTANTS.planeConfig.width, CONSTANTS.planeConfig.height]}
/>
<shadowMaterial
opacity={CONSTANTS.shadowConfig.shadowMaterialOpacity}
transparent
/> */}
<planeGeometry args={[planeValue.width, planeValue.height]} />
<shadowMaterial
opacity={CONSTANTS.shadowConfig.shadowMaterialOpacity}
transparent
/>
</mesh> </mesh>
</> </>
); );
} }

View File

@@ -11,10 +11,13 @@ export const useSocketStore = create<any>((set: any, get: any) => ({
return; return;
} }
const socket = io(`http://${process.env.REACT_APP_SERVER_SOCKET_API_BASE_URL}/Builder`, { const socket = io(
reconnection: false, `http://${process.env.REACT_APP_SERVER_SOCKET_API_BASE_URL}/Builder`,
auth: { email, organization }, {
}); reconnection: false,
auth: { email, organization },
}
);
set({ socket }); set({ socket });
}, },
@@ -401,3 +404,18 @@ export const useLimitDistance = create<any>((set: any) => ({
limitDistance: true, limitDistance: true,
setLimitDistance: (x: any) => set({ limitDistance: x }), setLimitDistance: (x: any) => set({ limitDistance: x }),
})); }));
export const useTileDistance = create<any>((set: any) => ({
gridValue: { size: 300, divisions: 75 },
planeValue: { height: 300, width: 300 },
setGridValue: (value: any) =>
set((state: any) => ({
gridValue: { ...state.gridValue, ...value },
})),
setPlaneValue: (value: any) =>
set((state: any) => ({
planeValue: { ...state.planeValue, ...value },
})),
}));

View File

@@ -1052,7 +1052,6 @@
position: relative; position: relative;
z-index: 3; z-index: 3;
font-size: var(--font-size-regular); font-size: var(--font-size-regular);
color: var(--background-color);
} }
.asset-image { .asset-image {
@@ -1103,7 +1102,6 @@
position: relative; position: relative;
z-index: 3; z-index: 3;
font-size: var(--font-size-regular); font-size: var(--font-size-regular);
color: var(--background-color);
} }
.asset-image { .asset-image {

View File

@@ -59,39 +59,39 @@ export type ThreeDimension = {
}; };
export type GridConfig = { export type GridConfig = {
size: number; size: number;
divisions: number; divisions: number;
primaryColor: string; primaryColor: string;
secondaryColor: string; secondaryColor: string;
position2D: [x: number, y: number, z: number]; position2D: [x: number, y: number, z: number];
position3D: [x: number, y: number, z: number]; position3D: [x: number, y: number, z: number];
} };
export type PlaneConfig = { export type PlaneConfig = {
position2D: [x: number, y: number, z: number]; position2D: [x: number, y: number, z: number];
position3D: [x: number, y: number, z: number]; position3D: [x: number, y: number, z: number];
rotation: number; rotation: number;
width: number; width: number;
height: number; height: number;
color: string; color: string;
} };
export type ShadowConfig = { export type ShadowConfig = {
shadowOffset: number, shadowOffset: number;
shadowmapSizewidth: number, shadowmapSizewidth: number;
shadowmapSizeheight: number, shadowmapSizeheight: number;
shadowcamerafar: number, shadowcamerafar: number;
shadowcameranear: number, shadowcameranear: number;
shadowcameratop: number, shadowcameratop: number;
shadowcamerabottom: number, shadowcamerabottom: number;
shadowcameraleft: number, shadowcameraleft: number;
shadowcameraright: number, shadowcameraright: number;
shadowbias: number, shadowbias: number;
shadownormalBias: number, shadownormalBias: number;
shadowMaterialPosition: [x: number, y: number, z: number], shadowMaterialPosition: [x: number, y: number, z: number];
shadowMaterialRotation: [x: number, y: number, z: number], shadowMaterialRotation: [x: number, y: number, z: number];
shadowMaterialOpacity: number, shadowMaterialOpacity: number;
} };
export type SkyConfig = { export type SkyConfig = {
defaultTurbidity: number; defaultTurbidity: number;
@@ -109,34 +109,34 @@ export type AssetConfig = {
}; };
export type PointConfig = { export type PointConfig = {
defaultInnerColor: string; defaultInnerColor: string;
defaultOuterColor: string; defaultOuterColor: string;
deleteColor: string; deleteColor: string;
boxScale: [number, number, number]; boxScale: [number, number, number];
wallOuterColor: string; wallOuterColor: string;
floorOuterColor: string; floorOuterColor: string;
aisleOuterColor: string; aisleOuterColor: string;
zoneOuterColor: string; zoneOuterColor: string;
snappingThreshold: number; snappingThreshold: number;
} };
export type LineConfig = { export type LineConfig = {
tubularSegments: number; tubularSegments: number;
radius: number; radius: number;
radialSegments: number; radialSegments: number;
wallName: string; wallName: string;
floorName: string; floorName: string;
aisleName: string; aisleName: string;
zoneName: string; zoneName: string;
referenceName: string; referenceName: string;
lineIntersectionPoints: number; lineIntersectionPoints: number;
defaultColor: string; defaultColor: string;
wallColor: string; wallColor: string;
floorColor: string; floorColor: string;
aisleColor: string; aisleColor: string;
zoneColor: string; zoneColor: string;
helperColor: string; helperColor: string;
} };
export type WallConfig = { export type WallConfig = {
defaultColor: string; defaultColor: string;
@@ -145,10 +145,10 @@ export type WallConfig = {
}; };
export type FloorConfig = { export type FloorConfig = {
defaultColor: string; defaultColor: string;
height: number; height: number;
textureScale: number; textureScale: number;
} };
export type RoofConfig = { export type RoofConfig = {
defaultColor: string; defaultColor: string;
@@ -156,16 +156,16 @@ export type RoofConfig = {
}; };
export type AisleConfig = { export type AisleConfig = {
width: number; width: number;
height: number; height: number;
defaultColor: number; defaultColor: number;
} };
export type ZoneConfig = { export type ZoneConfig = {
defaultColor: string; defaultColor: string;
height: number; height: number;
color: string; color: string;
} };
export type ColumnConfig = { export type ColumnConfig = {
defaultColor: string; defaultColor: string;
@@ -242,24 +242,24 @@ export const threeDimension: ThreeDimension = {
export const camPositionUpdateInterval: number = 200; // Interval for updating the camera position export const camPositionUpdateInterval: number = 200; // Interval for updating the camera position
export const gridConfig: GridConfig = { export const gridConfig: GridConfig = {
size: 300, // Size of the grid size: 300, // Size of the grid
divisions: 75, // Number of divisions in the grid divisions: 75, // Number of divisions in the grid
primaryColor: savedTheme === "dark" ? "#131313" : "#d5d5d5", // Primary color of the grid primaryColor: savedTheme === "dark" ? "#131313" : "#d5d5d5", // Primary color of the grid
secondaryColor: savedTheme === "dark" ? "#434343" : "#e3e3e3", // Secondary color of the grid secondaryColor: savedTheme === "dark" ? "#434343" : "#e3e3e3", // Secondary color of the grid
position2D: [0, 0.1, 0], // Position of the grid in 2D view position2D: [0, 0.1, 0], // Position of the grid in 2D view
position3D: [0, -0.5, 0], // Position of the grid in 3D view position3D: [0, -0.5, 0], // Position of the grid in 3D view
} };
export const planeConfig: PlaneConfig = { export const planeConfig: PlaneConfig = {
position2D: [0, -0.5, 0], // Position of the plane position2D: [0, -0.5, 0], // Position of the plane
position3D: [0, -0.65, 0], // Position of the plane position3D: [0, -0.65, 0], // Position of the plane
rotation: -Math.PI / 2, // Rotation of the plane rotation: -Math.PI / 2, // Rotation of the plane
width: 300, // Width of the plane width: 300, // Width of the plane
height: 300, // Height of the plane height: 300, // Height of the plane
color: savedTheme === "dark" ? "#323232" : "#f3f3f3" // Color of the plane color: savedTheme === "dark" ? "#323232" : "#f3f3f3", // Color of the plane
} };
export const shadowConfig: ShadowConfig = { export const shadowConfig: ShadowConfig = {
shadowOffset: 50, // Offset of the shadow shadowOffset: 50, // Offset of the shadow
@@ -349,10 +349,10 @@ export const aisleConfig: AisleConfig = {
}; };
export const zoneConfig: ZoneConfig = { export const zoneConfig: ZoneConfig = {
defaultColor: "black", // Default color of the zones defaultColor: "black", // Default color of the zones
height: 3, height: 3,
color: "#8656DF" // Color of the zones color: "#8656DF", // Color of the zones
} };
export const columnConfig: ColumnConfig = { export const columnConfig: ColumnConfig = {
defaultColor: "White", // Default color of the columns defaultColor: "White", // Default color of the columns