Skip to content

Commit

Permalink
added z rotation controls + annotation fix
Browse files Browse the repository at this point in the history
  • Loading branch information
sahirgomez1 committed Jun 26, 2021
1 parent d96b24d commit 0ffc976
Show file tree
Hide file tree
Showing 7 changed files with 122 additions and 45 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ to install all dependencies. Then run.
```
npm start
```
Add your 3D objects to the public folder, use `.gltf` files. We suggest and [OBJ coverter](https://github.com/CesiumGS/obj2gltf), then optimize
your glTF assets with `gltf-pipeline`, [more info](https://www.npmjs.com/package/gltf-pipeline)
Add your 3D objects to the public folder, use `.gltf` files. We suggest an [OBJ coverter](https://github.com/CesiumGS/obj2gltf), then optimize
your glTF assets with `gltf-pipeline`, [more info](https://www.npmjs.com/package/gltf-pipeline).

### `npm start`

Expand Down
23 changes: 21 additions & 2 deletions src/ObjectControls.js
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,12 @@
enabled: true,
from: Math.PI ,
to: Math.PI
}
},
z: {
enabled: true,
from: Math.PI,
to: Math.PI
},
};

let
Expand Down Expand Up @@ -187,7 +192,6 @@
x: e.offsetX - previousMousePosition.x,
y: e.offsetY - previousMousePosition.y
};

previousMousePosition = { x: e.offsetX, y: e.offsetY };

if (horizontalRotationEnabled && deltaMove.x !== 0)
Expand All @@ -211,6 +215,21 @@
mesh.rotation.x += Math.sign(deltaMove.y) * rotationSpeed;
flag = mouseFlags.MOUSEMOVE;
}
}
// To rotate over Z
if (isDragging && e.ctrlKey) {
const deltaMove = {
x: e.offsetX - previousMousePosition.x,
y: e.offsetY - previousMousePosition.y
};
previousMousePosition = { x: e.offsetX, y: e.offsetY };

if (horizontalRotationEnabled && deltaMove.x !== 0 ){
if (!isWithinMaxAngle(Math.sign(deltaMove.x) * rotationSpeed, 'z'))
return;
mesh.rotation.z += Math.sign(deltaMove.x) * rotationSpeed;
flag = mouseFlags.MOUSEMOVE;
}
}
}

Expand Down
32 changes: 30 additions & 2 deletions src/components/AnnotationView.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import ReactPlayer from 'react-player';
import EnvironmentContainer from './EnvironmentContainer';
import FormattedTime from '../components/videoPlayer/FormattedTime';
import { useVideoStore } from '../stores/VideoStore';
import { useAnnotationStore } from '../stores/AnnotationStore';
import { useObjectStore } from '../stores/ObjectStore'

const Slider = ({ onMouseUp, onMouseDown, onChange, played }) => (
<div>
Expand Down Expand Up @@ -34,6 +36,7 @@ const AnnotationView = ({camPosition, objScale}) => {
loop,
seeking,
setVideoDimensions,
onSeekTime,
handleProgress,
handleVideoPlayPause,
handleVideoRewind,
Expand All @@ -44,16 +47,40 @@ const AnnotationView = ({camPosition, objScale}) => {
handleSeekChange,
handleVideoSpeedChange } = useVideoStore();

const annotationStore = useAnnotationStore();
const objectStore = useObjectStore();

const findAnnotation = t => {
//if (!editMode) return
let currentAnnotations = annotationStore.outputAnnotation.annotations
//if (!currentAnnotations) return
let annotation = currentAnnotations.find(x => x.time === t)
//console.log(currentAnnotations)
if (annotation !== undefined) {
objectStore.handleRotation(annotation.rotation)
objectStore.handleTranslation(annotation.position)
}
return
}

const handleSeekMouseUp = e => {
handleSeekingtoFalse()
player.current.seekTo(parseFloat(e.target.value))
findAnnotation(parseFloat(e.target.value))
}

const handleRewind = () => {
handleVideoRewind()
player.current.seekTo(0);
}

const onVideoReady = (e) => {
const videoWidth = player.current.getInternalPlayer().videoWidth;
const videoHeight = player.current.getInternalPlayer().videoHeight;
setVideoDimensions(videoWidth, videoHeight)
annotationStore.setVideoMetadata(e)
}

const onProgress = state => {
if (!seeking) handleProgress(state.played)
}
Expand All @@ -79,10 +106,11 @@ const AnnotationView = ({camPosition, objScale}) => {
controls={false}
loop={loop}
playbackRate={playbackRate}
onReady={(e) => setVideoDimensions(e)}
progressInterval={1000 / 30}
onReady={(e) => onVideoReady(e)}
onStart={() => console.log('onStart')}
onBuffer={() => console.log('onBuffer')}
onSeek={e => console.log('onSeek', e)}
onSeek={e => onSeekTime(e)}
onEnded={handleEnded}
onError={e => console.log('onError', e)}
onProgress={onProgress}
Expand Down
44 changes: 28 additions & 16 deletions src/components/EnvironmentContainer.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,48 +22,60 @@ const Banana = ({camPosition, ...props}) => {
const [ hovered, setHover ] = useState(false)

const { camera, gl: { domElement }} = useThree();
const state = useThree();
camera.position.set( camPosition.xCamPos, camPosition.yCamPos, camPosition.zCamPos)
const position = Object.values(objPosition)
const rotation = Object.values(objRotation)

const handleShiftKey = useCallback((e) => {
if (!e.shiftKey) {
const handleKeys = useCallback((e) => {
if (!e.shiftKey || !e.ctrKey) {
handleRotation(object.current.rotation)
} return
}, [handleRotation]);

useEffect(() => {
window.addEventListener('keyup', handleShiftKey);
window.addEventListener('keyup', handleKeys);
return () => {
window.removeEventListener('keyup', handleShiftKey);
window.removeEventListener('keyup', handleKeys);
};
}, [handleShiftKey]);
}, [handleKeys]);

useFrame((state) => {
//state.camera.fov = THREE.MathUtils.lerp(state.camera.fov, 7, step)
//state.camera.position.lerp(vec.set( position.xCamPos, position.yCamPos, 10), step)
state.clock.autoStart = false
state.camera.fov = camPosition.fov
state.camera.lookAt(0,0,0)
state.camera.updateProjectionMatrix()
object.current.updateMatrixWorld();
})

const annotateFrame = () => {
//console.log(object.current)
let video_metadata = {
url: videoState.url,
videoHeight: videoState.videoHeight,
videoWidth: videoState.videoWidth
}
state.clock.start()
//console.log(state.clock.oldTime)
//rotateXYZ()
let dataAnnotation = {
id: videoState.played,
id:(videoState.played * videoState.duration),
time: (videoState.played * videoState.duration),
position: object.current.position,
rotation: object.current.rotation,
scale: object.current.scale
position: {x: object.current.position.x,y: object.current.position.y,z: object.current.position.z},
rotation: {_x: object.current.rotation._x, _y: object.current.rotation._y, _z: object.current.rotation._z},
scale: object.current.scale.x
}
addAnnotation(video_metadata, dataAnnotation)
addAnnotation(dataAnnotation)
}

const rotateXYZ = () => {
object.current.rotation.set(0,0,0)
object.current.position.set(0,0,0)
}

/*useFrame(({ clock }) => {
clock.autoStart = false
if (clock.elapsedTime < 3) {
object.current.rotation.x += Math.PI/2
//object.current.position.set(0,0,0)
}
})*/

return (
<>
Expand Down
58 changes: 37 additions & 21 deletions src/stores/AnnotationStore.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,42 @@
import create from 'zustand';
import create from "zustand";

const addRecord = (list, annotation) => {
let ann_found = list.some(o => o.id === annotation.id);
if (!ann_found) list.push(annotation);
list.map(o => (o.id === annotation.id) ? annotation : o)
return list;
}

const useAnnotationStore = create(set => ({
outputAnnotation : { url: "", videoWidth: 0, videoHeight: 0, annotations:[] },
addAnnotation : (video_metadata, annotation) =>
set(state => ({
outputAnnotation: {
...state.outputAnnotation,
url: video_metadata.url,
videoWidth: video_metadata.videoWidth,
videoHeight: video_metadata.videoHeight,
annotations: addRecord(state.outputAnnotation.annotations, annotation)
}
})),

}))
let ann_found = list.some((o) => o.id === annotation.id); // Check if annotation already exists
if (!ann_found) {
list.push(annotation)
return list;
} else {
const modifiedList = list.map((o) => (o.id === annotation.id ? annotation : o));
return modifiedList;
}
};

const useAnnotationStore = create((set, get) => ({
outputAnnotation: { url: "", videoWidth: 0, videoHeight: 0, annotations: [] },
setVideoMetadata: (e) =>
set((state) => ({
outputAnnotation: {
...state.outputAnnotation,
url: e.props.url,
videoHeight: e.getInternalPlayer().videoHeight,
videoWidth: e.getInternalPlayer().videoWidth
},
})),
addAnnotation: (annotation) =>
set(
(state) => (
{
outputAnnotation: {
...state.outputAnnotation,
annotations: addRecord(state.outputAnnotation.annotations, annotation),
},
}
)
),
getCurrentAnnotations: () => {
const currentAnnotations = get().outputAnnotation.annotations;
return currentAnnotations;
},
}));

export { useAnnotationStore };
1 change: 0 additions & 1 deletion src/stores/ObjectStore.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ const useObjectStore = create((set) => ({
objectSelected: { name: "Banana", gltfFile: "/banana.gltf" },
objPosition: { x: 0, y: 0.2, z: 0 },
objRotation: { _x: Math.PI / 2, _y: 0, _z: 0 },

handleSelectObject: (e) =>
set((state) => ({
objectSelected: state.defaultObjects.find((i) => i.name === e),
Expand Down
5 changes: 4 additions & 1 deletion src/stores/VideoStore.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const useVideoStore = create(set => ({
duration: 0,
id :'react-player',
played: 0,
seekedTime: 0,
playing: false,
controls: false ,
muted: true,
Expand All @@ -15,7 +16,9 @@ const useVideoStore = create(set => ({
height: 'auto',

setVideoOnScene : (e) => set ( state => ({ url: e.target.value })),
setVideoDimensions : (e) => set (state => ({ videoHeight: e.wrapper.clientHeight, videoWidth: e.wrapper.clientWidth})),
setVideoDimensions : (videoWidth, videoHeight) => set (state => ({ videoHeight: videoHeight, videoWidth: videoWidth})),
setVideoClientDimensions : (e) => set (state => ({ videoClientHeight: e.wrapper.clientHeight, videoClientWidth: e.wrapper.clientWidth})),
onSeekTime : (e) => set (state => ({seekedTime : e})),
handleToggleLoop : () => set ( state => ({ loop: !state.loop})),
handleVideoPlayPause : () => set (state => ({ playing : !state.playing })),
handleVideoRewind : () => set (state => ({ playing: false, played: 0})),
Expand Down

0 comments on commit 0ffc976

Please sign in to comment.