-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
210 additions
and
184 deletions.
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
/* | ||
Auto-generated by: https://github.com/pmndrs/gltfjsx | ||
*/ | ||
|
||
import { useRef, useEffect } from 'react'; | ||
import { useFrame, useThree } from '@react-three/fiber'; | ||
//import { Quaternion, Euler, Vector3 } from 'three'; | ||
import { GridHelper, AxesHelper, BoxHelper } from 'three'; | ||
import { OBJLoader } from 'three/examples/jsm/loaders/OBJLoader'; | ||
import * as THREE from 'three'; | ||
|
||
//props to pass in rotation through euler angles | ||
interface EeveeProps { | ||
objRef: React.MutableRefObject<THREE.Group | undefined>; | ||
onLoad?: () => void; | ||
} | ||
|
||
export function Eevee({ objRef, onLoad }: EeveeProps) { | ||
const { scene } = useThree(); | ||
const boxHelperRef = useRef<BoxHelper>(); | ||
|
||
useFrame(() => { | ||
if (objRef.current) { | ||
// Add a random amount of rotation to the object each frame times delta | ||
// This is so the rotation is smooth and not dependent on the frame rate | ||
//const quaternion = new Quaternion(); | ||
//quaternion.setFromAxisAngle(new Vector3(0, 1, 0), Math.random() * delta); | ||
// meshRef.current.rotation.x += Math.random() * delta; | ||
// meshRef.current.rotation.y += Math.random() * delta; | ||
// meshRef.current.rotation.z += Math.random() * delta; | ||
//meshRef.current.quaternion.multiply(quaternion); | ||
|
||
if (boxHelperRef.current) { | ||
boxHelperRef.current.update(); | ||
} | ||
} | ||
|
||
}); | ||
|
||
// Load the objects into the scene | ||
useEffect(() => { | ||
const loader = new OBJLoader(); | ||
|
||
loader.load('/Eevee.obj', (object) => { | ||
// Add the loaded object to the scene | ||
scene.add(object); | ||
objRef.current = object; | ||
|
||
const boxHelper = boxHelperRef.current = new BoxHelper(object, 0xffff00); | ||
scene.add(boxHelper); | ||
|
||
console.log('Loaded Eevee'); | ||
if (onLoad) onLoad(); | ||
}); | ||
|
||
const gridHelper = new GridHelper(1000, 100); | ||
gridHelper.position.y = -11; | ||
scene.add(gridHelper); | ||
|
||
const axesHelper = new AxesHelper(40); | ||
scene.add(axesHelper); | ||
|
||
// Cleanup on component unmount | ||
return () => { | ||
if (boxHelperRef.current) { | ||
scene.remove(boxHelperRef.current); | ||
} | ||
scene.remove(gridHelper); | ||
scene.remove(axesHelper); | ||
}; | ||
}, [scene]); | ||
|
||
return ( | ||
<group> | ||
</group> | ||
); | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
import { Suspense, useEffect, useState } from 'react'; | ||
import { Canvas } from '@react-three/fiber'; | ||
import { OrbitControls, Stage } from '@react-three/drei'; | ||
import { Eevee } from './Eevee.js'; | ||
import { useRef } from 'react'; | ||
import { replayData, fetchData } from '@lib/modelUtils.js'; | ||
import './modelViewer.css'; | ||
import { quatReplayData } from 'types/ModelTypes.js'; | ||
|
||
const ModelViewer = () => { | ||
const objRef = useRef<THREE.Group>(); | ||
const [data, setData] = useState<quatReplayData>([]); | ||
const [objectLoaded, setObjectLoaded] = useState(false); | ||
|
||
useEffect(() => { | ||
fetchData().then(fetchedData => setData(fetchedData)); | ||
}, []); | ||
|
||
useEffect(() => { | ||
if (!objRef.current || !objectLoaded || data.length <= 0) return; | ||
console.log('Data:', data, 'objRef:', objRef.current); | ||
replayData(data, objRef.current); | ||
}, [data, objectLoaded]); | ||
|
||
return ( | ||
<div className="modelContainer"> | ||
<Canvas shadows dpr={[1, 2]} camera={{ fov: 40, position: [40, 0, 0] }}> | ||
<Suspense fallback={null}> | ||
<Stage preset="rembrandt" intensity={1} environment="lobby"> | ||
<directionalLight position={[-5, 10, -35]} intensity={2.0} color="red" /> | ||
<directionalLight position={[5, 10, 5]} intensity={2.0} color="blue"/> | ||
<ambientLight intensity={0.3} /> | ||
<Eevee objRef={objRef} onLoad={() => setObjectLoaded(true)}/> | ||
</Stage> | ||
</Suspense> | ||
<OrbitControls/> {/* autoRotate */} | ||
</Canvas> | ||
</div> | ||
|
||
); | ||
}; | ||
|
||
export default ModelViewer; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
import { quatReplayData } from 'types/ModelTypes'; | ||
import { ApiUtil } from './apiUtils'; | ||
import { Quaternion, Euler } from 'three'; | ||
|
||
const extractColumn = (data, columnIndex = 1) => { | ||
return data.map(row => row[columnIndex]); | ||
}; | ||
|
||
const parseCSV = (data: string) => { | ||
return data | ||
.trim() | ||
.split('\n') | ||
.slice(1) | ||
.map(row => row.split(',')); | ||
}; | ||
|
||
const combineData = (timestamps, x, y, z, w) => { | ||
return timestamps.map((timestamp: string, i: number) => ({ | ||
timestamp: Number(timestamp), | ||
x: Number(x[i]), | ||
y: Number(y[i]), | ||
z: Number(z[i]), | ||
w: Number(w[i]) | ||
})); | ||
}; | ||
|
||
export const fetchData = async () => { | ||
let data: quatReplayData = []; | ||
await Promise.all([ | ||
ApiUtil.getFile('data/IMU QUAT W.csv'), | ||
ApiUtil.getFile('data/IMU QUAT X.csv'), | ||
ApiUtil.getFile('data/IMU QUAT Y.csv'), | ||
ApiUtil.getFile('data/IMU QUAT Z.csv') | ||
]).then(([wDataRaw, xDataRaw, yDataRaw, zDataRaw]) => { | ||
const wData = parseCSV(wDataRaw); | ||
const xData = parseCSV(xDataRaw); | ||
const yData = parseCSV(yDataRaw); | ||
const zData = parseCSV(zDataRaw); | ||
|
||
const w = extractColumn(wData); | ||
const x = extractColumn(xData); | ||
const y = extractColumn(yData); | ||
const z = extractColumn(zData); | ||
const timestamps = extractColumn(wData, 0); | ||
|
||
data = combineData(timestamps, x, y, z, w); | ||
}); | ||
return data; | ||
}; | ||
|
||
const updateQuaternion = (quat: Quaternion, objRef: THREE.Group) => { | ||
if (objRef) { | ||
objRef.quaternion.set(quat.x, quat.y, quat.z, quat.w); | ||
//meshRef.current.rotation.set(x, y, z) | ||
} | ||
}; | ||
|
||
const updateEuler = (euler: Euler, objRef: THREE.Group) => { | ||
if (objRef) { | ||
objRef.rotation.set(euler.x, euler.y, euler.z); | ||
} | ||
}; | ||
|
||
export const replayData = (data: quatReplayData, objRef: THREE.Group) => { | ||
for (const { timestamp, x, y, z, w } of data) { | ||
setTimeout(() => { | ||
console.log('Replaying timestamp: ', timestamp); | ||
updateQuaternion(new Quaternion(x, y, z, w), objRef); | ||
}, timestamp); | ||
} | ||
}; | ||
|
||
export const replayDataEuler = (data: {timestamp: number, x: number, y: number, z: number}[], objRef: THREE.Group) => { | ||
for (const { timestamp, x, y, z } of data) { | ||
setTimeout(() => { | ||
console.log('Replaying timestamp: ', timestamp); | ||
updateEuler(new Euler(x, y, z), objRef); | ||
}, timestamp); | ||
} | ||
}; | ||
|
Oops, something went wrong.