add new features and optimizations to simulation and builder modules

This commit is contained in:
Jerald-Golden-B 2025-03-25 16:35:54 +05:30
parent 2303682a15
commit 1259b5fcc8
18 changed files with 601 additions and 178 deletions

View File

@ -1,6 +1,6 @@
import React, { useEffect, useState } from "react";
import Header from "./Header";
import useModuleStore from "../../../store/useModuleStore";
import useModuleStore, { useSubModuleStore } from "../../../store/useModuleStore";
import {
AnalysisIcon,
MechanicsIcon,
@ -14,15 +14,17 @@ import GlobalProperties from "./properties/GlobalProperties";
import AsstePropertiies from "./properties/AssetProperties";
import Analysis from "./analysis/Analysis";
import Simulations from "./simulation/Simulations";
import { useSelectedActionSphere } from "../../../store/store";
const SideBarRight: React.FC = () => {
const { activeModule } = useModuleStore();
const [activeList, setActiveList] = useState("properties");
const { selectedActionSphere } = useSelectedActionSphere();
const { subModule, setSubModule } = useSubModuleStore();
const { toggleUI } = useToggleStore();
// Reset activeList whenever activeModule changes
// Reset subModule whenever activeModule changes
useEffect(() => {
setActiveList("properties");
setSubModule("properties");
}, [activeModule]);
return (
@ -31,38 +33,34 @@ const SideBarRight: React.FC = () => {
{toggleUI && (
<div className="sidebar-actions-container">
<div
className={`sidebar-action-list ${
activeList === "properties" ? "active" : ""
className={`sidebar-action-list ${subModule === "properties" ? "active" : ""
}`}
onClick={() => setActiveList("properties")}
onClick={() => setSubModule("properties")}
>
<PropertiesIcon isActive={activeList === "properties"} />
<PropertiesIcon isActive={subModule === "properties"} />
</div>
{activeModule === "simulation" && (
<>
<div
className={`sidebar-action-list ${
activeList === "mechanics" ? "active" : ""
className={`sidebar-action-list ${subModule === "mechanics" ? "active" : ""
}`}
onClick={() => setActiveList("mechanics")}
onClick={() => setSubModule("mechanics")}
>
<MechanicsIcon isActive={activeList === "mechanics"} />
<MechanicsIcon isActive={subModule === "mechanics"} />
</div>
<div
className={`sidebar-action-list ${
activeList === "simulations" ? "active" : ""
className={`sidebar-action-list ${subModule === "simulations" ? "active" : ""
}`}
onClick={() => setActiveList("simulations")}
onClick={() => setSubModule("simulations")}
>
<SimulationIcon isActive={activeList === "simulations"} />
<SimulationIcon isActive={subModule === "simulations"} />
</div>
<div
className={`sidebar-action-list ${
activeList === "analysis" ? "active" : ""
className={`sidebar-action-list ${subModule === "analysis" ? "active" : ""
}`}
onClick={() => setActiveList("analysis")}
onClick={() => setSubModule("analysis")}
>
<AnalysisIcon isActive={activeList === "analysis"} />
<AnalysisIcon isActive={subModule === "analysis"} />
</div>
</>
)}
@ -70,7 +68,7 @@ const SideBarRight: React.FC = () => {
)}
{/* process builder */}
{toggleUI &&
activeList === "properties" &&
subModule === "properties" &&
activeModule !== "visualization" && (
<div className="sidebar-right-container">
<div className="sidebar-right-content-container">
@ -84,21 +82,28 @@ const SideBarRight: React.FC = () => {
{toggleUI && activeModule === "simulation" && (
<>
{activeList === "mechanics" && (
{(subModule === "mechanics" && selectedActionSphere) && (
<div className="sidebar-right-container">
<div className="sidebar-right-content-container">
<MachineMechanics />
</div>
</div>
)}
{activeList === "analysis" && (
{(subModule === "mechanics" && !selectedActionSphere) && (
<div className="sidebar-right-container">
<div className="sidebar-right-content-container">
{/* <MachineMechanics /> */}
</div>
</div>
)}
{subModule === "analysis" && (
<div className="sidebar-right-container">
<div className="sidebar-right-content-container">
<Analysis />
</div>
</div>
)}
{activeList === "simulations" && (
{subModule === "simulations" && (
<div className="sidebar-right-container">
<div className="sidebar-right-content-container">
<Simulations />

View File

@ -11,8 +11,11 @@ import LabledDropdown from "../../../ui/inputs/LabledDropdown";
import RegularDropDown from "../../../ui/inputs/RegularDropDown";
import { handleResize } from "../../../../functions/handleResizePannel";
import EyeDropInput from "../../../ui/inputs/EyeDropInput";
import { useSelectedActionSphere } from "../../../../store/store";
const MachineMechanics: React.FC = () => {
const { selectedActionSphere, setSelectedActionSphere } = useSelectedActionSphere();
console.log('selectedActionSphere: ', selectedActionSphere);
const [actionList, setActionList] = useState<string[]>([]);
const [triggerList, setTriggerList] = useState<string[]>([]);
const [selectedItem, setSelectedItem] = useState<{
@ -68,8 +71,8 @@ const MachineMechanics: React.FC = () => {
return (
<div className="machine-mechanics-container">
<div className="machine-mechanics-header">Selected Object</div>
<div className="process-list-container">
<div className="machine-mechanics-header">{selectedActionSphere.path.modelName}</div>
{/* <div className="process-list-container">
<div className="label">Process:</div>
<RegularDropDown
header={activeProcess || "add process ->"}
@ -79,7 +82,7 @@ const MachineMechanics: React.FC = () => {
<div className="add-new-process" onClick={handleAddProcess}>
<AddIcon />
</div>
</div>
</div> */}
<div className="machine-mechanics-content-container">
<div className="actions">
<div className="header">
@ -97,8 +100,7 @@ const MachineMechanics: React.FC = () => {
{actionList.map((action, index) => (
<div
key={index}
className={`list-item ${
selectedItem?.type === "action" &&
className={`list-item ${selectedItem?.type === "action" &&
selectedItem.name === action
? "active"
: ""
@ -144,8 +146,7 @@ const MachineMechanics: React.FC = () => {
{triggerList.map((trigger, index) => (
<div
key={index}
className={`list-item ${
selectedItem?.type === "trigger" &&
className={`list-item ${selectedItem?.type === "trigger" &&
selectedItem.name === trigger
? "active"
: ""

View File

@ -55,9 +55,9 @@ const DisplayZone: React.FC<DisplayZoneProps> = ({
const [selectedOption, setSelectedOption] = React.useState<string | null>(
null
);
console.log('setSelectedOption: ', setSelectedOption);
// console.log('setSelectedOption: ', setSelectedOption);
const [options, setOptions] = React.useState<string[]>([]);
console.log('setOptions: ', setOptions);
// console.log('setOptions: ', setOptions);
// Scroll to the selected option when it changes
useEffect(() => {

View File

@ -83,7 +83,7 @@ const ZoneGroup: React.FC = () => {
useEffect(() => {
localStorage.setItem('zones', zones);
localStorage.setItem('zones', JSON.stringify(zones));
}, [zones])

View File

@ -1,7 +1,7 @@
import * as THREE from 'three'
import { EffectComposer, N8AO, Outline } from '@react-three/postprocessing'
import { BlendFunction } from 'postprocessing'
import { useDeletableFloorItem, useSelectedEventSphere, useSelectedPath, useSelectedWallItem, useselectedFloorItem } from '../../../store/store';
import { useDeletableFloorItem, useSelectedActionSphere, useSelectedPath, useSelectedWallItem, useselectedFloorItem } from '../../../store/store';
import * as Types from '../../../types/world/worldTypes'
import * as CONSTANTS from '../../../types/world/worldConstants';
@ -9,7 +9,7 @@ export default function PostProcessing() {
const { deletableFloorItem, setDeletableFloorItem } = useDeletableFloorItem();
const { selectedWallItem, setSelectedWallItem } = useSelectedWallItem();
const { selectedFloorItem, setselectedFloorItem } = useselectedFloorItem();
const { selectedEventSphere } = useSelectedEventSphere();
const { selectedActionSphere } = useSelectedActionSphere();
const { selectedPath } = useSelectedPath();
function flattenChildren(children: any[]) {
@ -75,9 +75,9 @@ export default function PostProcessing() {
xRay={true}
/>
}
{selectedEventSphere &&
{selectedActionSphere &&
<Outline
selection={[selectedEventSphere.point]}
selection={[selectedActionSphere.point]}
selectionLayer={10}
width={750}
blendFunction={BlendFunction.ALPHA}

View File

@ -6,11 +6,12 @@ import { useEffect } from 'react';
interface Path {
modeluuid: string;
modelName: string;
points: {
uuid: string;
position: [number, number, number];
rotation: [number, number, number];
events: { uuid: string; type: string; material: string; delay: number | string; spawnInterval: number | string; isUsed: boolean }[] | [];
actions: { uuid: string; type: string; material: string; delay: number | string; spawnInterval: number | string; isUsed: boolean }[] | [];
triggers: { uuid: string; type: string; isUsed: boolean }[] | [];
}[];
pathPosition: [number, number, number];
@ -36,26 +37,27 @@ function Behaviour({ setSimulationPaths }: { setSimulationPaths: any }) {
const newPath: Path = {
modeluuid: item.modeluuid,
modelName: item.modelname,
points: [
{
uuid: point1UUID,
position: [point1Position.x, point1Position.y, point1Position.z],
rotation: [0, 0, 0],
events: [{ uuid: THREE.MathUtils.generateUUID(), type: 'Inherit', material: 'Inherit', delay: 'Inherit', spawnInterval: 'Inherit', isUsed: false }],
actions: [{ uuid: THREE.MathUtils.generateUUID(), type: 'Inherit', material: 'Inherit', delay: 'Inherit', spawnInterval: 'Inherit', isUsed: false }],
triggers: [],
},
{
uuid: middlePointUUID,
position: [middlePointPosition.x, middlePointPosition.y, middlePointPosition.z],
rotation: [0, 0, 0],
events: [{ uuid: THREE.MathUtils.generateUUID(), type: 'Inherit', material: 'Inherit', delay: 'Inherit', spawnInterval: 'Inherit', isUsed: false }],
actions: [{ uuid: THREE.MathUtils.generateUUID(), type: 'Inherit', material: 'Inherit', delay: 'Inherit', spawnInterval: 'Inherit', isUsed: false }],
triggers: [],
},
{
uuid: point2UUID,
position: [point2Position.x, point2Position.y, point2Position.z],
rotation: [0, 0, 0],
events: [{ uuid: THREE.MathUtils.generateUUID(), type: 'Inherit', material: 'Inherit', delay: 'Inherit', spawnInterval: 'Inherit', isUsed: false }],
actions: [{ uuid: THREE.MathUtils.generateUUID(), type: 'Inherit', material: 'Inherit', delay: 'Inherit', spawnInterval: 'Inherit', isUsed: false }],
triggers: [],
},
],

View File

@ -1,55 +0,0 @@
import { useControls } from 'leva';
import { useSelectedEventSphere } from '../../../store/store';
interface Path {
modeluuid: string;
points: {
uuid: string;
position: [number, number, number];
rotation: [number, number, number];
events: string;
triggers: string;
}[];
position: [number, number, number];
rotation: [number, number, number];
}
const EventsControl = ({ simulationPaths, setSimulationPaths }: { simulationPaths: Path[], setSimulationPaths: any }) => {
const { selectedEventSphere, setSelectedEventSphere } = useSelectedEventSphere();
const { events, triggers }: any = useControls({
events: {
value: selectedEventSphere?.point?.userData?.events || '',
options: ['Event1', 'Event2', 'Event3'],
onChange: (newEvent: string) => updatePathData(newEvent, 'events')
},
triggers: {
value: selectedEventSphere?.point?.userData?.triggers || '',
options: ['None', 'Trigger1', 'Trigger2', 'Trigger3'],
onChange: (newTrigger: string) => updatePathData(newTrigger, 'triggers')
},
});
function updatePathData(value: string, key: 'events' | 'triggers') {
if (!selectedEventSphere) return;
const updatedPaths = simulationPaths.map((path) =>
path.modeluuid === selectedEventSphere.path.modeluuid
? {
...path,
points: path.points.map((point) =>
point.uuid === selectedEventSphere.point.uuid
? { ...point, [key]: value }
: point
),
}
: path
);
console.log('updatedPaths: ', updatedPaths);
setSimulationPaths(updatedPaths);
}
return null;
};
export default EventsControl;

View File

@ -1,16 +1,18 @@
import * as THREE from 'three';
import { useRef, useState, useEffect } from 'react';
import { Sphere, TransformControls } from '@react-three/drei';
import { useIsConnecting, useRenderDistance, useSelectedEventSphere, useSelectedPath, useSimulationPaths } from '../../../store/store';
import { useIsConnecting, useRenderDistance, useSelectedActionSphere, useSelectedPath, useSimulationPaths } from '../../../store/store';
import { useFrame, useThree } from '@react-three/fiber';
import { useSubModuleStore } from '../../../store/useModuleStore';
interface Path {
modeluuid: string;
modelName: string;
points: {
uuid: string;
position: [number, number, number];
rotation: [number, number, number];
events: { uuid: string; type: string; material: string; delay: number | string; spawnInterval: number | string; isUsed: boolean }[] | [];
actions: { uuid: string; type: string; material: string; delay: number | string; spawnInterval: number | string; isUsed: boolean }[] | [];
triggers: { uuid: string; type: string; isUsed: boolean }[] | [];
}[];
pathPosition: [number, number, number];
@ -20,7 +22,8 @@ interface Path {
function PathCreation({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObject<THREE.Group> }) {
const { renderDistance } = useRenderDistance();
const { setSelectedEventSphere, selectedEventSphere } = useSelectedEventSphere();
const { setSubModule } = useSubModuleStore();
const { setSelectedActionSphere, selectedActionSphere } = useSelectedActionSphere();
const { setSelectedPath } = useSelectedPath();
const { simulationPaths, setSimulationPaths } = useSimulationPaths();
const { isConnecting, setIsConnecting } = useIsConnecting();
@ -34,7 +37,7 @@ function PathCreation({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObject
useEffect(() => {
setTransformMode(null);
const handleKeyDown = (e: KeyboardEvent) => {
if (!selectedEventSphere) return;
if (!selectedActionSphere) return;
if (e.key === 'g') {
setTransformMode(prev => prev === 'translate' ? null : 'translate');
}
@ -45,7 +48,7 @@ function PathCreation({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObject
window.addEventListener('keydown', handleKeyDown);
return () => window.removeEventListener('keydown', handleKeyDown);
}, [selectedEventSphere]);
}, [selectedActionSphere]);
useFrame(() => {
Object.values(groupRefs.current).forEach(group => {
@ -57,23 +60,23 @@ function PathCreation({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObject
});
const updateSimulationPaths = () => {
if (!selectedEventSphere) return;
if (!selectedActionSphere) return;
const updatedPaths: Path[] = simulationPaths.map((path) => ({
...path,
points: path.points.map((point) =>
point.uuid === selectedEventSphere.point.uuid
point.uuid === selectedActionSphere.point.uuid
? {
...point,
position: [
selectedEventSphere.point.position.x,
selectedEventSphere.point.position.y,
selectedEventSphere.point.position.z,
selectedActionSphere.point.position.x,
selectedActionSphere.point.position.y,
selectedActionSphere.point.position.z,
],
rotation: [
selectedEventSphere.point.rotation.x,
selectedEventSphere.point.rotation.y,
selectedEventSphere.point.rotation.z,
selectedActionSphere.point.rotation.x,
selectedActionSphere.point.rotation.y,
selectedActionSphere.point.rotation.z,
]
}
: point
@ -100,11 +103,12 @@ function PathCreation({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObject
if (isConnecting) return;
e.stopPropagation();
setSelectedPath({ path, group: groupRefs.current[path.modeluuid] });
setSelectedEventSphere(null);
setSelectedActionSphere(null);
setTransformMode(null);
}}
onPointerMissed={() => {
setSelectedPath(null);
setSubModule('properties');
}}
>
{path.points.map((point, index) => (
@ -118,14 +122,18 @@ function PathCreation({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObject
onClick={(e) => {
if (isConnecting) return;
e.stopPropagation();
setSelectedEventSphere({
setSelectedActionSphere({
path,
point: sphereRefs.current[point.uuid]
});
setSubModule('mechanics');
setSelectedPath(null);
}}
userData={{ point, path }}
onPointerMissed={() => setSelectedEventSphere(null)}
onPointerMissed={() => {
setSubModule('properties');
setSelectedActionSphere(null)
}}
>
<meshStandardMaterial
color={index === 0 ? 'orange' : index === path.points.length - 1 ? 'blue' : 'green'}
@ -148,10 +156,10 @@ function PathCreation({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObject
);
})}
{selectedEventSphere && transformMode && (
{selectedActionSphere && transformMode && (
<TransformControls
ref={transformRef}
object={selectedEventSphere.point}
object={selectedActionSphere.point}
mode={transformMode}
onObjectChange={updateSimulationPaths}
/>

View File

@ -1,5 +1,5 @@
import { useState, useEffect, useRef } from 'react';
import { useConnections, useFloorItems, useSelectedEventSphere, useSelectedPath, useSimulationPaths } from '../../store/store';
import { useConnections, useFloorItems, useSelectedActionSphere, useSelectedPath, useSimulationPaths } from '../../store/store';
import { useThree } from '@react-three/fiber';
import * as THREE from 'three';
import Behaviour from './behaviour/behaviour';
@ -19,10 +19,10 @@ function Simulation() {
}, [simulationPaths]);
// useEffect(() => {
// if (selectedEventSphere) {
// console.log('selectedEventSphere: ', selectedEventSphere);
// if (selectedActionSphere) {
// console.log('selectedActionSphere: ', selectedActionSphere);
// }
// }, [selectedEventSphere]);
// }, [selectedActionSphere]);
// useEffect(() => {
// if (selectedPath) {

View File

@ -0,0 +1,381 @@
import { useMemo, useState } from 'react';
import { useSelectedActionSphere, useToggleView, useSimulationPaths, useSelectedPath, useStartSimulation } from '../../store/store';
import * as THREE from 'three';
import useModuleStore from '../../store/useModuleStore';
function SimulationUI() {
const { ToggleView } = useToggleView();
const { activeModule } = useModuleStore();
const { startSimulation, setStartSimulation } = useStartSimulation();
const { selectedActionSphere } = useSelectedActionSphere();
const { selectedPath, setSelectedPath } = useSelectedPath();
const { simulationPaths, setSimulationPaths } = useSimulationPaths();
const handleAddAction = () => {
if (!selectedActionSphere) return;
const newAction = { uuid: THREE.MathUtils.generateUUID(), type: 'Inherit', material: 'Inherit', delay: 'Inherit', spawnInterval: 'Inherit', isUsed: false };
const updatedPaths = simulationPaths.map((path) => ({
...path,
points: path.points.map((point) =>
point.uuid === selectedActionSphere.point.uuid
? { ...point, actions: [...point.actions, newAction] }
: point
),
}));
setSimulationPaths(updatedPaths);
};
const handleDeleteAction = (uuid: string) => {
if (!selectedActionSphere) return;
const updatedPaths = simulationPaths.map((path) => ({
...path,
points: path.points.map((point) =>
point.uuid === selectedActionSphere.point.uuid
? { ...point, actions: point.actions.filter(action => action.uuid !== uuid) }
: point
),
}));
setSimulationPaths(updatedPaths);
};
const handleActionSelect = (uuid: string, actionType: string) => {
if (!selectedActionSphere) return;
const updatedPaths = simulationPaths.map((path) => ({
...path,
points: path.points.map((point) =>
point.uuid === selectedActionSphere.point.uuid
? {
...point,
actions: point.actions.map((action) =>
action.uuid === uuid ? { ...action, type: actionType } : action
),
}
: point
),
}));
setSimulationPaths(updatedPaths);
};
const handleMaterialSelect = (uuid: string, material: string) => {
if (!selectedActionSphere) return;
const updatedPaths = simulationPaths.map((path) => ({
...path,
points: path.points.map((point) =>
point.uuid === selectedActionSphere.point.uuid
? {
...point,
actions: point.actions.map((action) =>
action.uuid === uuid ? { ...action, material } : action
),
}
: point
),
}));
setSimulationPaths(updatedPaths);
};
const handleDelayChange = (uuid: string, delay: number | string) => {
if (!selectedActionSphere) return;
const updatedPaths = simulationPaths.map((path) => ({
...path,
points: path.points.map((point) =>
point.uuid === selectedActionSphere.point.uuid
? {
...point,
actions: point.actions.map((action) =>
action.uuid === uuid ? { ...action, delay } : action
),
}
: point
),
}));
setSimulationPaths(updatedPaths);
};
const handleSpawnIntervalChange = (uuid: string, spawnInterval: number | string) => {
if (!selectedActionSphere) return;
const updatedPaths = simulationPaths.map((path) => ({
...path,
points: path.points.map((point) =>
point.uuid === selectedActionSphere.point.uuid
? {
...point,
actions: point.actions.map((action) =>
action.uuid === uuid ? { ...action, spawnInterval } : action
),
}
: point
),
}));
setSimulationPaths(updatedPaths);
};
const handleSpeedChange = (speed: number) => {
if (!selectedPath) return;
const updatedPaths = simulationPaths.map((path) =>
path.modeluuid === selectedPath.path.modeluuid ? { ...path, speed } : path
);
setSimulationPaths(updatedPaths);
setSelectedPath({ ...selectedPath, path: { ...selectedPath.path, speed } });
};
const handleAddTrigger = () => {
if (!selectedActionSphere) return;
const newTrigger = { uuid: THREE.MathUtils.generateUUID(), type: '', isUsed: false };
const updatedPaths = simulationPaths.map((path) => ({
...path,
points: path.points.map((point) =>
point.uuid === selectedActionSphere.point.uuid
? { ...point, triggers: [...point.triggers, newTrigger] }
: point
),
}));
setSimulationPaths(updatedPaths);
};
const handleDeleteTrigger = (uuid: string) => {
if (!selectedActionSphere) return;
const updatedPaths = simulationPaths.map((path) => ({
...path,
points: path.points.map((point) =>
point.uuid === selectedActionSphere.point.uuid
? { ...point, triggers: point.triggers.filter(trigger => trigger.uuid !== uuid) }
: point
),
}));
setSimulationPaths(updatedPaths);
};
const handleTriggerSelect = (uuid: string, triggerType: string) => {
if (!selectedActionSphere) return;
const updatedPaths = simulationPaths.map((path) => ({
...path,
points: path.points.map((point) =>
point.uuid === selectedActionSphere.point.uuid
? {
...point,
triggers: point.triggers.map((trigger) =>
trigger.uuid === uuid ? { ...trigger, type: triggerType } : trigger
),
}
: point
),
}));
setSimulationPaths(updatedPaths);
};
const handleResetPath = () => {
if (!selectedPath) return;
};
const handleActionToggle = (uuid: string) => {
if (!selectedActionSphere) return;
const updatedPaths = simulationPaths.map((path) => ({
...path,
points: path.points.map((point) =>
point.uuid === selectedActionSphere.point.uuid
? {
...point,
actions: point.actions.map((action) => ({
...action,
isUsed: action.uuid === uuid ? !action.isUsed : false,
})),
}
: point
),
}));
setSimulationPaths(updatedPaths);
};
const handleTriggerToggle = (uuid: string) => {
if (!selectedActionSphere) return;
const updatedPaths = simulationPaths.map((path) => ({
...path,
points: path.points.map((point) =>
point.uuid === selectedActionSphere.point.uuid
? {
...point,
triggers: point.triggers.map((trigger) => ({
...trigger,
isUsed: trigger.uuid === uuid ? !trigger.isUsed : false,
})),
}
: point
),
}));
setSimulationPaths(updatedPaths);
};
const selectedPoint = useMemo(() => {
if (!selectedActionSphere) return null;
return simulationPaths.flatMap((path) => path.points).find((point) => point.uuid === selectedActionSphere.point.uuid);
}, [selectedActionSphere, simulationPaths]);
return (
<>
{activeModule === "simulation" && (
<div style={{ zIndex: 10, position: "relative", width: '260px' }}>
{!ToggleView && (
<>
<button
onClick={() => setStartSimulation(!startSimulation)}
style={{
marginTop: "10px",
background: startSimulation ? '#ff320e' : '',
padding: "10px",
borderRadius: "5px"
}}
>
{startSimulation ? 'Stop Simulation' : 'Start Simulation'}
</button>
{selectedPath && (
<div style={{ marginTop: "10px" }}>
<label>Path Speed:</label>
<input
style={{ width: '50px' }}
type="number"
value={selectedPath.path.speed}
min="0.1"
step="0.1"
onChange={(e) => handleSpeedChange(parseFloat(e.target.value))}
/>
</div>
)}
{selectedActionSphere && (
<div style={{ marginTop: "10px" }}>
<button onClick={handleAddAction}>Add Action</button>
<button onClick={handleAddTrigger}>Add Trigger</button>
{selectedPoint?.actions.map((action) => (
<div key={action.uuid} style={{ marginTop: "10px" }}>
<select value={action.type} onChange={(e) => handleActionSelect(action.uuid, e.target.value)}>
<option value="Inherit">Inherit</option>
<option value="Spawn">Spawn Point</option>
<option value="Swap">Swap Material</option>
<option value="Despawn">Despawn Point</option>
<option value="Delay">Delay</option>
</select>
<button onClick={() => handleDeleteAction(action.uuid)}>Delete Action</button>
<label>
<input
type="checkbox"
checked={action.isUsed}
onChange={() => handleActionToggle(action.uuid)}
/>
</label>
{(action.type === 'Spawn' || action.type === 'Swap') && (
<div style={{ marginTop: "10px" }}>
<select value={action.material} onChange={(e) => handleMaterialSelect(action.uuid, e.target.value)}>
<option value="Inherit">Inherit</option>
<option value="Crate">Crate</option>
<option value="Box">Box</option>
</select>
</div>
)}
{action.type === 'Delay' && (
<div style={{ marginTop: "10px" }}>
<label>Delay Time:</label>
<input
style={{ width: '50px' }}
type="text"
value={isNaN(Number(action.delay)) || action.delay === "Inherit" ? "Inherit" : action.delay}
min="1"
onChange={(e) => handleDelayChange(action.uuid, parseInt(e.target.value) || 'Inherit')}
/>
</div>
)}
{action.type === 'Spawn' && (
<div style={{ marginTop: "10px" }}>
<label>Spawn Interval:</label>
<input
style={{ width: '50px' }}
type="text"
value={isNaN(Number(action.spawnInterval)) || action.spawnInterval === "Inherit" ? "Inherit" : action.spawnInterval}
min="1"
onChange={(e) => handleSpawnIntervalChange(action.uuid, parseInt(e.target.value) || 'Inherit')}
/>
</div>
)}
<hr style={{ margin: "10px 0", borderColor: "#ccc" }} />
</div>
))}
<hr style={{ margin: "10px 0", border: "1px solid black" }} />
{selectedPoint?.triggers.map((trigger) => (
<div key={trigger.uuid} style={{ marginTop: "10px" }}>
<select value={trigger.type} onChange={(e) => handleTriggerSelect(trigger.uuid, e.target.value)}>
<option value="">Select Trigger Type</option>
<option value="On-Hit">On Hit</option>
<option value="Buffer">Buffer</option>
</select>
<button onClick={() => handleDeleteTrigger(trigger.uuid)}>Delete Trigger</button>
<label>
<input
type="checkbox"
checked={trigger.isUsed}
onChange={() => handleTriggerToggle(trigger.uuid)}
/>
</label>
<hr style={{ margin: "10px 0", borderColor: "#ccc" }} />
</div>
))}
</div>
)}
{selectedPath && (
<div style={{ marginTop: "10px" }}>
<button
onClick={handleResetPath}
style={{ padding: "10px", borderRadius: "5px", background: "#ff0000", color: "#fff" }}
>
Reset Path
</button>
</div>
)}
</>
)}
</div>
)}
</>
);
}
export default SimulationUI;

View File

@ -8,6 +8,7 @@ import Tools from "../components/ui/Tools";
import Scene from "../modules/scene/scene";
import { useSocketStore, useFloorItems, useOrganization, useUserName, useWallItems, useZones } from "../store/store";
import { useNavigate } from "react-router-dom";
import SimulationUI from "../modules/simulation/simulationUI";
const Project: React.FC = () => {
let navigate = useNavigate();
@ -45,6 +46,7 @@ const Project: React.FC = () => {
{activeModule === "visualization" && <RealTimeVisulization />}
<Tools />
<Scene />
<SimulationUI />
</div>
);
};

View File

@ -2,6 +2,9 @@ import React, { useState, FormEvent } from "react";
import { useNavigate } from "react-router-dom";
import { LogoIconLarge } from "../components/icons/Logo";
import { EyeIcon } from "../components/icons/ExportCommonIcons";
import { useOrganization, useUserName } from "../store/store";
import { signInApi } from "../services/factoryBuilder/signInSignUp/signInApi";
import { signUpApi } from "../services/factoryBuilder/signInSignUp/signUpApi";
// import LoadingPage from "../components/templates/LoadingPage";
const UserAuth: React.FC = () => {
@ -9,34 +12,50 @@ const UserAuth: React.FC = () => {
const [password, setPassword] = useState("");
const [showPassword, setShowPassword] = useState(false);
const [error, setError] = useState("");
const [isSignIn, setIsSignIn] = useState(true); // Toggle between login and register
const [userName, setUserName] = useState(""); // Username for registration
const [isSignIn, setIsSignIn] = useState(true);
const { userName, setUserName } = useUserName();
const { organization, setOrganization } = useOrganization();
const navigate = useNavigate();
const handleLogin = (e: FormEvent) => {
const handleLogin = async (e: FormEvent<HTMLFormElement>) => {
e.preventDefault();
// Dummy validation for "account not found"
if (email !== "user@example.com") {
setError("Account not found");
} else {
const organization = (email.split("@")[1]).split(".")[0];
try {
const res = await signInApi(email, password, organization);
if (res.message === "login successfull") {
setError("");
console.log("Login Successful!");
console.log("Email:", email);
console.log("Password:", password);
setOrganization(organization);
setUserName(res.name);
localStorage.setItem("userId", res.userId);
localStorage.setItem("email", res.email);
localStorage.setItem("userName", res.name);
if (res.isShare) {
navigate("/Project");
}
} else if (res.message === "User Not Found!!! Kindly signup...") {
setError("Account not found");
}
} catch (error) { }
};
const handleRegister = (e: FormEvent) => {
const handleRegister = async (e: FormEvent) => {
e.preventDefault();
// Dummy validation for registration
if (email && password && userName) {
setError("");
console.log("Registration Successful!");
console.log("Username:", userName);
console.log("Email:", email);
console.log("Password:", password);
try {
const organization = (email.split("@")[1]).split(".")[0];
const res = await signUpApi(userName, email, password, organization);
if (res.message === "New User created") {
setIsSignIn(true);
}
if (res.message === "User already exists") {
setError("User already exists");
}
} catch (error) { }
} else {
setError("Please fill all the fields!");
}
@ -97,6 +116,7 @@ const UserAuth: React.FC = () => {
)}
<input
type="email"
name="email"
value={email}
placeholder="Email"
onChange={(e) => setEmail(e.target.value)}
@ -104,6 +124,7 @@ const UserAuth: React.FC = () => {
/>
<div className="password-container">
<input
name="password"
type={showPassword ? "text" : "password"}
value={password}
placeholder="Password"

View File

@ -1,6 +1,6 @@
let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}`;
export const signIn = async (email: string, password: Object, organization: Object) => {
export const signInApi = async (email: string, password: Object, organization: Object) => {
try {
const response = await fetch(`${url_Backend_dwinzo}/api/v1/login`, {
method: "POST",

View File

@ -1,6 +1,6 @@
let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}`;
export const signUp = async (userName: string, email: string, password: Object, organization: Object) => {
export const signUpApi = async (userName: string, email: string, password: Object, organization: Object) => {
try {
const response = await fetch(`${url_Backend_dwinzo}/api/v1/signup`, {
method: "POST",
@ -11,7 +11,7 @@ export const signUp = async (userName: string, email: string, password: Object,
});
if (!response.ok) {
throw new Error("Failed to signUp");
throw new Error("Failed to signUpApi");
}
const result = await response.json();

View File

@ -283,9 +283,9 @@ export const useDrawMaterialPath = create<any>((set: any) => ({
setDrawMaterialPath: (x: any) => set({ drawMaterialPath: x }),
}));
export const useSelectedEventSphere = create<any>((set: any) => ({
selectedEventSphere: undefined,
setSelectedEventSphere: (x: any) => set({ selectedEventSphere: x }),
export const useSelectedActionSphere = create<any>((set: any) => ({
selectedActionSphere: undefined,
setSelectedActionSphere: (x: any) => set({ selectedActionSphere: x }),
}));
export const useSelectedPath = create<any>((set: any) => ({
@ -293,11 +293,77 @@ export const useSelectedPath = create<any>((set: any) => ({
setSelectedPath: (x: any) => set({ selectedPath: x }),
}));
export const useSimulationPaths = create<Types.SimulationPathsStore>((set) => ({
interface Path {
modeluuid: string;
modelName: string;
points: {
uuid: string;
position: [number, number, number];
rotation: [number, number, number];
actions: { uuid: string; type: string; material: string; delay: number | string; spawnInterval: number | string; isUsed: boolean }[] | [];
triggers: { uuid: string; type: string; isUsed: boolean }[] | [];
}[];
pathPosition: [number, number, number];
pathRotation: [number, number, number];
speed: number;
}
interface SimulationPathsStore {
simulationPaths: Path[];
setSimulationPaths: (paths: Path[]) => void;
}
export const useSimulationPaths = create<SimulationPathsStore>((set) => ({
simulationPaths: [],
setSimulationPaths: (paths) => set({ simulationPaths: paths }),
}));
// interface Point {
// uuid: string;
// position: [number, number, number];
// rotation: [number, number, number];
// event: {
// uuid: string;
// type: string;
// material: string;
// delay: number | string;
// spawnInterval: number | string;
// isUsed: boolean;
// };
// trigger: {
// uuid: string;
// type: string;
// isUsed: boolean;
// };
// }
// interface Process {
// processId: string;
// processName: string;
// points: Point[];
// pathPosition: [number, number, number];
// pathRotation: [number, number, number];
// speed: number;
// isUsed: boolean;
// }
// interface Path {
// modeluuid: string;
// processes: Process[];
// }
// interface SimulationPathsStore {
// simulationPaths: Path[];
// setSimulationPaths: (paths: Path[]) => void;
// }
// export const useSimulationPaths = create<SimulationPathsStore>((set) => ({
// simulationPaths: [],
// setSimulationPaths: (paths) => set({ simulationPaths: paths }),
// }));
export const useConnections = create<Types.ConnectionStore>((set) => ({
connections: [],

View File

@ -1,4 +1,3 @@
// store/useModuleStore.ts
import { create } from "zustand";
interface ModuleStore {
@ -12,3 +11,16 @@ const useModuleStore = create<ModuleStore>((set) => ({
}));
export default useModuleStore;
// New store for subModule
interface SubModuleStore {
subModule: string;
setSubModule: (subModule: string) => void;
}
const useSubModuleStore = create<SubModuleStore>((set) => ({
subModule: "properties", // Initial subModule state
setSubModule: (subModule) => set({ subModule }), // Update subModule state
}));
export { useSubModuleStore };

View File

@ -270,7 +270,7 @@ export const planeConfig: PlaneConfig = {
width: 300, // Width of the plane
height: 300, // Height of the plane
color: "white" // Color of the plane
color: "#f3f3f3" // Color of the plane
}
export const shadowConfig: ShadowConfig = {

View File

@ -270,26 +270,6 @@ export type setSelectedItemsIndexSetState = (index: number | null) => void;
export type RefCSM = React.MutableRefObject<CSM>;
export type RefCSMHelper = React.MutableRefObject<CSMHelper>;
interface Path {
modeluuid: string;
points: {
uuid: string;
position: [number, number, number];
rotation: [number, number, number];
events: { uuid: string; type: string; material: string; delay: number | string; spawnInterval: number | string; isUsed: boolean }[] | [];
triggers: { uuid: string; type: string; isUsed: boolean }[] | [];
}[];
pathPosition: [number, number, number];
pathRotation: [number, number, number];
speed: number;
}
interface SimulationPathsStore {
simulationPaths: Path[];
setSimulationPaths: (paths: Path[]) => void;
}
interface PathConnection {
fromPathUUID: string;
fromUUID: string;