updated new animation

This commit is contained in:
SreeNath14
2025-04-02 11:10:44 +05:30
parent d1e6b010e9
commit 844c8c3366
3 changed files with 514 additions and 181 deletions

View File

@@ -5,11 +5,13 @@ import { useLoader, useFrame } from "@react-three/fiber";
import * as THREE from "three";
import { GLTF } from "three-stdlib";
import boxGltb from "../../../assets/gltf-glb/crate_box.glb";
import camera from "../../../assets/gltf-glb/camera face 2.gltf";
interface PointAction {
uuid: string;
name: string;
type: "Inherit" | "Spawn" | "Despawn" | "Delay" | "Swap";
objectType: string;
material: string;
delay: string | number;
spawnInterval: string | number;
@@ -54,18 +56,8 @@ interface AnimationState {
currentDelayDuration: number;
delayComplete: boolean;
currentPathIndex: number;
spawnPoints: Record<
string,
{
position: THREE.Vector3;
interval: number;
lastSpawnTime: number;
}
>;
}
const MAX_SPAWNED_OBJECTS = 20;
const ProcessAnimator: React.FC<{ processes: ProcessData[] }> = ({
processes,
}) => {
@@ -76,7 +68,7 @@ const ProcessAnimator: React.FC<{ processes: ProcessData[] }> = ({
const groupRef = useRef<THREE.Group>(null);
const meshRef = useRef<THREE.Mesh>(null);
const [visible, setVisible] = useState(false);
const spawnedObjectsRef = useRef<THREE.Object3D[]>([]);
const [currentPathIndex, setCurrentPathIndex] = useState(0);
const materials = useMemo(
() => ({
@@ -125,18 +117,26 @@ const ProcessAnimator: React.FC<{ processes: ProcessData[] }> = ({
currentDelayDuration: 0,
delayComplete: false,
currentPathIndex: 0,
spawnPoints: {},
});
const getPointDataForAnimationIndex = (index: number) => {
if (!processes[0]?.paths) return null;
if (index < 3) {
return processes[0].paths[0]?.points[index];
} else {
const path2Index = index - 3;
return processes[0].paths[1]?.points[path2Index];
let cumulativePoints = 0;
console.log("cumulativePoints: ", cumulativePoints);
for (const path of processes[0].paths) {
const pointCount = path.points?.length || 0;
if (index < cumulativePoints + pointCount) {
const pointIndex = index - cumulativePoints;
return path.points?.[pointIndex] || null;
}
cumulativePoints += pointCount;
}
return null;
};
useEffect(() => {
@@ -152,22 +152,8 @@ const ProcessAnimator: React.FC<{ processes: ProcessData[] }> = ({
currentDelayDuration: 0,
delayComplete: false,
currentPathIndex: 0,
spawnPoints: {},
};
// Clear spawned objects
if (groupRef.current) {
spawnedObjectsRef.current.forEach((obj) => {
if (groupRef.current?.children.includes(obj)) {
groupRef.current.remove(obj);
}
if (obj instanceof THREE.Mesh) {
obj.material.dispose();
}
});
spawnedObjectsRef.current = [];
}
const currentRef = gltf?.scene ? groupRef.current : meshRef.current;
if (currentRef && animationPath.length > 0) {
currentRef.position.copy(animationPath[0]);
@@ -178,15 +164,9 @@ const ProcessAnimator: React.FC<{ processes: ProcessData[] }> = ({
}, [isPlaying, currentProcess, animationPath]);
const handleMaterialSwap = (materialType: string) => {
const newMaterial =
materials[materialType as keyof typeof materials] || materials.Default;
setCurrentMaterial(newMaterial);
spawnedObjectsRef.current.forEach((obj) => {
if (obj instanceof THREE.Mesh) {
obj.material = newMaterial.clone();
}
});
setCurrentMaterial(
materials[materialType as keyof typeof materials] || materials.Default
);
};
const hasNonInheritActions = (actions: PointAction[] = []) => {
@@ -195,8 +175,7 @@ const ProcessAnimator: React.FC<{ processes: ProcessData[] }> = ({
const handlePointActions = (
actions: PointAction[] = [],
currentTime: number,
currentPosition: THREE.Vector3
currentTime: number
) => {
let shouldStopAnimation = false;
@@ -231,18 +210,7 @@ const ProcessAnimator: React.FC<{ processes: ProcessData[] }> = ({
break;
case "Spawn":
const spawnInterval =
typeof action.spawnInterval === "number"
? action.spawnInterval
: parseFloat(action.spawnInterval as string) || 1;
const positionKey = currentPosition.toArray().join(",");
animationStateRef.current.spawnPoints[positionKey] = {
position: currentPosition.clone(),
interval: spawnInterval,
lastSpawnTime: currentTime - spawnInterval, // Force immediate spawn
};
setVisible(true);
break;
case "Swap":
@@ -252,6 +220,7 @@ const ProcessAnimator: React.FC<{ processes: ProcessData[] }> = ({
break;
case "Inherit":
// Handle inherit logic if needed
break;
}
});
@@ -273,24 +242,38 @@ const ProcessAnimator: React.FC<{ processes: ProcessData[] }> = ({
const path = animationPath;
const stateRef = animationStateRef.current;
// Check if we need to switch paths (specific to your structure)
if (stateRef.currentIndex === 3 && stateRef.currentPathIndex === 0) {
setCurrentPathIndex(1);
stateRef.currentPathIndex = 1;
}
// Get the current point data
const currentPointData = getPointDataForAnimationIndex(
stateRef.currentIndex
);
// Execute actions when we first arrive at a point
if (stateRef.progress === 0 && currentPointData?.actions) {
console.log(
`Processing actions at point ${stateRef.currentIndex}`,
currentPointData.actions
);
const shouldStop = handlePointActions(
currentPointData.actions,
currentTime,
currentRef.position
currentTime
);
if (shouldStop) return;
}
// Handle delays
if (stateRef.isDelaying) {
console.log(
`Delaying... ${currentTime - stateRef.delayStartTime}/${
stateRef.currentDelayDuration
}`
);
if (
currentTime - stateRef.delayStartTime >=
stateRef.currentDelayDuration
@@ -298,46 +281,10 @@ const ProcessAnimator: React.FC<{ processes: ProcessData[] }> = ({
stateRef.isDelaying = false;
stateRef.delayComplete = true;
} else {
return;
return; // Keep waiting
}
}
// Handle spawning - this is the key updated part
Object.entries(stateRef.spawnPoints).forEach(([key, spawnPoint]) => {
if (currentTime - spawnPoint.lastSpawnTime >= spawnPoint.interval) {
spawnPoint.lastSpawnTime = currentTime;
if (gltf?.scene && groupRef?.current) {
const newObject = gltf.scene.clone();
newObject.position.copy(spawnPoint.position);
newObject.traverse((child) => {
if (child instanceof THREE.Mesh) {
child.material = currentMaterial.clone();
}
});
groupRef.current.add(newObject);
spawnedObjectsRef.current.push(newObject);
// Clean up old objects if needed
console.log(
"spawnedObjectsRef.current.length: ",
spawnedObjectsRef.current.length
);
if (spawnedObjectsRef.current.length > MAX_SPAWNED_OBJECTS) {
const oldest = spawnedObjectsRef.current.shift();
if (oldest && groupRef.current.children.includes(oldest)) {
groupRef.current.remove(oldest);
if (oldest instanceof THREE.Mesh) {
oldest.material.dispose();
}
}
}
}
}
});
const nextPointIdx = stateRef.currentIndex + 1;
const isLastPoint = nextPointIdx >= path.length;
@@ -374,22 +321,6 @@ const ProcessAnimator: React.FC<{ processes: ProcessData[] }> = ({
}
});
useEffect(() => {
return () => {
if (groupRef.current) {
spawnedObjectsRef.current.forEach((obj) => {
if (groupRef.current?.children.includes(obj)) {
groupRef.current.remove(obj);
}
if (obj instanceof THREE.Mesh) {
obj.material.dispose();
}
});
spawnedObjectsRef.current = [];
}
};
}, []);
if (!processes || processes.length === 0) {
return null;
}