jbilcke-hf HF staff commited on
Commit
4251a28
·
1 Parent(s): 1be0bd5

adjustment

Browse files
src/app/render.ts CHANGED
@@ -72,7 +72,7 @@ export async function newRender({
72
  prompt,
73
  // nbFrames: 8 and nbSteps: 15 --> ~10 sec generation
74
  nbFrames, // when nbFrames is 1, we will only generate static images
75
- nbSteps: isForVideo ? 25 : 35, // 20 = fast, 30 = better, 50 = best
76
  actionnables,
77
  segmentation: "firstframe", // one day we will remove this param, to make it automatic
78
  width: isForVideo ? 576 : 1024,
@@ -121,7 +121,7 @@ export async function getRender(renderId: string) {
121
  }
122
 
123
  try {
124
- console.log(`calling GET ${apiUrl}/render with renderId: ${renderId}`)
125
  const res = await fetch(`${apiUrl}/render/${renderId}`, {
126
  method: "GET",
127
  headers: {
 
72
  prompt,
73
  // nbFrames: 8 and nbSteps: 15 --> ~10 sec generation
74
  nbFrames, // when nbFrames is 1, we will only generate static images
75
+ nbSteps: isForVideo ? 30 : 35, // 20 = fast, 30 = better, 50 = best
76
  actionnables,
77
  segmentation: "firstframe", // one day we will remove this param, to make it automatic
78
  width: isForVideo ? 576 : 1024,
 
121
  }
122
 
123
  try {
124
+ // console.log(`calling GET ${apiUrl}/render with renderId: ${renderId}`)
125
  const res = await fetch(`${apiUrl}/render/${renderId}`, {
126
  method: "GET",
127
  headers: {
src/components/business/cartesian-image.tsx CHANGED
@@ -1,9 +1,9 @@
1
- import { ForwardedRef, forwardRef } from "react"
2
-
3
  import { SceneEventHandler } from "./types"
4
  import { RenderedScene } from "@/app/types"
 
5
 
6
- export const CartesianImage = forwardRef(({
7
  rendered,
8
  onEvent,
9
  className,
@@ -13,23 +13,36 @@ export const CartesianImage = forwardRef(({
13
  onEvent: SceneEventHandler
14
  className?: string
15
  debug?: boolean
16
- }, ref: ForwardedRef<HTMLDivElement>) => {
17
 
18
- const handleEvent = (event: React.MouseEvent<HTMLDivElement, MouseEvent>, isClick: boolean) => {
19
 
20
- const element = ((ref as any)?.current) as HTMLDivElement
 
21
 
22
- if (!element) {
23
  console.log("element isn't ready")
24
  return
25
  }
26
 
27
- const boundingRect = element.getBoundingClientRect()
28
- const x = (event.clientX - boundingRect.left) * 1.03
29
- const y = (event.clientY - boundingRect.top) //* 1.03
 
 
 
 
 
 
 
 
 
 
 
 
30
 
31
  const eventType = isClick ? "click" : "hover"
32
- onEvent(eventType, x, y)
33
  }
34
 
35
  if (!rendered.assetUrl) {
@@ -38,20 +51,18 @@ export const CartesianImage = forwardRef(({
38
  return (
39
  <div
40
  className={className}
41
- onMouseUp={(event) => handleEvent(event, true)}
42
- onMouseMove={(event) => handleEvent(event, false)}
43
  >
44
  <img
45
  src={rendered.assetUrl || undefined}
46
- ref={ref as any}
47
  className="absolute"
 
 
48
  />
49
  {debug && <img
50
  src={rendered.maskUrl || undefined}
51
- className="absolute opacity-50"
52
  />}
53
  </div>
54
  )
55
- })
56
-
57
- CartesianImage.displayName = "CartesianImage"
 
1
+ import { useRef } from "react"
 
2
  import { SceneEventHandler } from "./types"
3
  import { RenderedScene } from "@/app/types"
4
+ import { useImageDimension } from "@/lib/useImageDimension"
5
 
6
+ export function CartesianImage({
7
  rendered,
8
  onEvent,
9
  className,
 
13
  onEvent: SceneEventHandler
14
  className?: string
15
  debug?: boolean
16
+ }) {
17
 
18
+ const maskDimension = useImageDimension(rendered.maskUrl)
19
 
20
+ const ref = useRef<HTMLImageElement>(null)
21
+ const handleEvent = async (event: React.MouseEvent<HTMLImageElement, MouseEvent>, isClick: boolean) => {
22
 
23
+ if (!ref.current) {
24
  console.log("element isn't ready")
25
  return
26
  }
27
 
28
+ const boundingRect = ref.current.getBoundingClientRect()
29
+ // const x = (event.clientX - boundingRect.left) * 1.03
30
+ // const y = (event.clientY - boundingRect.top) //* 1.03
31
+
32
+ // those X and Y will be based on the current size of the container, which might be variable
33
+ const containerX = event.clientX - boundingRect.left
34
+ const containerY = event.clientY - boundingRect.top
35
+
36
+ // then we convert them to relative coordinates
37
+ const relativeX = containerX / boundingRect.width
38
+ const relativey = containerY / boundingRect.height
39
+
40
+ // finally, we convert back to coordinates within the input image
41
+ const imageX = relativeX * maskDimension.width
42
+ const imageY = relativey * maskDimension.height
43
 
44
  const eventType = isClick ? "click" : "hover"
45
+ onEvent(eventType, imageX, imageY)
46
  }
47
 
48
  if (!rendered.assetUrl) {
 
51
  return (
52
  <div
53
  className={className}
 
 
54
  >
55
  <img
56
  src={rendered.assetUrl || undefined}
57
+ ref={ref}
58
  className="absolute"
59
+ onMouseUp={(event) => handleEvent(event, true)}
60
+ onMouseMove={(event) => handleEvent(event, false)}
61
  />
62
  {debug && <img
63
  src={rendered.maskUrl || undefined}
64
+ className="absolute opacity-50 pointer-events-none"
65
  />}
66
  </div>
67
  )
68
+ }
 
 
src/components/business/cartesian-video.tsx CHANGED
@@ -1,9 +1,9 @@
1
- import { ForwardedRef, forwardRef } from "react"
2
-
3
  import { SceneEventHandler } from "./types"
4
  import { RenderedScene } from "@/app/types"
 
5
 
6
- export const CartesianVideo = forwardRef(({
7
  rendered,
8
  onEvent,
9
  className,
@@ -13,49 +13,58 @@ export const CartesianVideo = forwardRef(({
13
  onEvent: SceneEventHandler
14
  className?: string
15
  debug?: boolean
16
- }, ref: ForwardedRef<HTMLDivElement>) => {
17
-
18
- const handleEvent = (event: React.MouseEvent<HTMLDivElement, MouseEvent>, isClick: boolean) => {
19
 
20
- const element = ((ref as any)?.current) as HTMLDivElement
 
21
 
22
- if (!element) {
23
  console.log("element isn't ready")
24
  return
25
  }
26
 
27
- const boundingRect = element.getBoundingClientRect()
28
- const x = event.clientX - boundingRect.left
29
- const y = event.clientY - boundingRect.top
 
 
 
 
 
 
 
 
 
 
 
 
 
30
 
31
  const eventType = isClick ? "click" : "hover"
32
- onEvent(eventType, x, y)
33
  }
34
 
35
  return (
36
- <div
37
- className={className}
38
- ref={ref}
39
- onMouseUp={(event) => handleEvent(event, true)}
40
- onMouseMove={(event) => handleEvent(event, false)}
41
- >
42
- <video
43
- src={rendered.assetUrl || undefined}
44
- muted
45
- autoPlay
46
- loop
47
- width="1024px"
48
- height="512px"
49
- className="absolute"
50
- />
51
- {debug && <img
52
- src={rendered.maskUrl || undefined}
53
- className="absolute opacity-50"
54
- width="1024px"
55
- height="512px"
56
- />}
57
- </div>
58
  )
59
- })
60
-
61
- CartesianVideo.displayName = "CartesianVideo"
 
1
+ import { useRef } from "react"
 
2
  import { SceneEventHandler } from "./types"
3
  import { RenderedScene } from "@/app/types"
4
+ import { useImageDimension } from "@/lib/useImageDimension"
5
 
6
+ export function CartesianVideo({
7
  rendered,
8
  onEvent,
9
  className,
 
13
  onEvent: SceneEventHandler
14
  className?: string
15
  debug?: boolean
16
+ }) {
17
+ const maskDimension = useImageDimension(rendered.maskUrl)
 
18
 
19
+ const ref = useRef<HTMLVideoElement>(null)
20
+ const handleEvent = (event: React.MouseEvent<HTMLVideoElement, MouseEvent>, isClick: boolean) => {
21
 
22
+ if (!ref.current) {
23
  console.log("element isn't ready")
24
  return
25
  }
26
 
27
+ const boundingRect = ref.current.getBoundingClientRect()
28
+ // const x = (event.clientX - boundingRect.left) * 1.03
29
+ // const y = (event.clientY - boundingRect.top) //* 1.03
30
+
31
+ // those X and Y will be based on the current size of the container, which might be variable
32
+ const containerX = event.clientX - boundingRect.left
33
+ const containerY = event.clientY - boundingRect.top
34
+
35
+ // then we convert them to relative coordinates
36
+ const relativeX = containerX / boundingRect.width
37
+ const relativey = containerY / boundingRect.height
38
+
39
+ // finally, we convert back to coordinates within the input image
40
+ // TODO: go read the video size
41
+ const contentX = relativeX * maskDimension.width
42
+ const contentY = relativey * maskDimension.height
43
 
44
  const eventType = isClick ? "click" : "hover"
45
+ onEvent(eventType, contentX, contentY)
46
  }
47
 
48
  return (
49
+ <div className={className}>
50
+ <video
51
+ src={rendered.assetUrl || undefined}
52
+ ref={ref}
53
+ onMouseUp={(event) => handleEvent(event, true)}
54
+ onMouseMove={(event) => handleEvent(event, false)}
55
+ className="absolute"
56
+ muted
57
+ autoPlay
58
+ loop
59
+ width="1024px"
60
+ height="512px"
61
+ />
62
+ {debug && <img
63
+ src={rendered.maskUrl || undefined}
64
+ className="absolute opacity-50 pointer-events-none"
65
+ width="1024px"
66
+ height="512px"
67
+ />}
68
+ </div>
 
 
69
  )
70
+ }
 
 
src/components/business/renderer.tsx CHANGED
@@ -27,7 +27,6 @@ export const Renderer = ({
27
  debug: boolean
28
  }) => {
29
  const timeoutRef = useRef<any>()
30
- const viewRef = useRef<HTMLDivElement>()
31
  const canvasRef = useRef<HTMLCanvasElement | null>(null)
32
  const contextRef = useRef<CanvasRenderingContext2D | null>(null)
33
  const [actionnable, setActionnable] = useState<string>("")
@@ -192,20 +191,17 @@ export const Renderer = ({
192
  {engine.type === "cartesian_video"
193
  ? <CartesianVideo
194
  rendered={rendered}
195
- ref={viewRef as any}
196
  onEvent={handleMouseEvent}
197
  debug={debug}
198
  />
199
  : engine.type === "spherical_image"
200
  ? <SphericalImage
201
  rendered={rendered}
202
- ref={viewRef as any}
203
  onEvent={handleMouseEvent}
204
  debug={debug}
205
  />
206
  : <CartesianImage
207
  rendered={rendered}
208
- ref={viewRef as any}
209
  onEvent={handleMouseEvent}
210
  debug={debug}
211
  />
 
27
  debug: boolean
28
  }) => {
29
  const timeoutRef = useRef<any>()
 
30
  const canvasRef = useRef<HTMLCanvasElement | null>(null)
31
  const contextRef = useRef<CanvasRenderingContext2D | null>(null)
32
  const [actionnable, setActionnable] = useState<string>("")
 
191
  {engine.type === "cartesian_video"
192
  ? <CartesianVideo
193
  rendered={rendered}
 
194
  onEvent={handleMouseEvent}
195
  debug={debug}
196
  />
197
  : engine.type === "spherical_image"
198
  ? <SphericalImage
199
  rendered={rendered}
 
200
  onEvent={handleMouseEvent}
201
  debug={debug}
202
  />
203
  : <CartesianImage
204
  rendered={rendered}
 
205
  onEvent={handleMouseEvent}
206
  debug={debug}
207
  />
src/components/business/spherical-image.tsx CHANGED
@@ -1,10 +1,9 @@
1
- import { ForwardedRef, forwardRef } from "react"
2
  import { ReactPhotoSphereViewer } from "react-photo-sphere-viewer"
3
 
4
  import { SceneEventHandler } from "./types"
5
  import { RenderedScene } from "@/app/types"
6
 
7
- export const SphericalImage = forwardRef(({
8
  rendered,
9
  onEvent,
10
  className,
@@ -14,7 +13,7 @@ export const SphericalImage = forwardRef(({
14
  onEvent: SceneEventHandler
15
  className?: string
16
  debug?: boolean
17
- }, ref: ForwardedRef<HTMLImageElement>) => {
18
 
19
  if (!rendered.assetUrl) {
20
  return null
@@ -32,6 +31,21 @@ export const SphericalImage = forwardRef(({
32
 
33
  defaultZoomLvl={1}
34
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
35
  onClick={(data, instance) => {
36
  console.log("on click:")
37
  const position = data.target.getPosition()
@@ -59,6 +73,4 @@ export const SphericalImage = forwardRef(({
59
 
60
  />
61
  )
62
- })
63
-
64
- SphericalImage.displayName = "SphericalImage"
 
 
1
  import { ReactPhotoSphereViewer } from "react-photo-sphere-viewer"
2
 
3
  import { SceneEventHandler } from "./types"
4
  import { RenderedScene } from "@/app/types"
5
 
6
+ export function SphericalImage({
7
  rendered,
8
  onEvent,
9
  className,
 
13
  onEvent: SceneEventHandler
14
  className?: string
15
  debug?: boolean
16
+ }) {
17
 
18
  if (!rendered.assetUrl) {
19
  return null
 
31
 
32
  defaultZoomLvl={1}
33
 
34
+ overlay={rendered.maskUrl || undefined}
35
+ overlayOpacity={debug ? 0.5 : 0}
36
+
37
+ panoData={{
38
+ fullWidth: 1300,
39
+ fullHeight: 700,
40
+ croppedWidth: 1024,
41
+ croppedHeight: 512,
42
+ croppedX: 0,
43
+ croppedY: 120,
44
+ // poseHeading: 0, // 0 to 360
45
+ posePitch: 0, // -90 to 90
46
+ // poseRoll: 0, // -180 to 180
47
+ }}
48
+
49
  onClick={(data, instance) => {
50
  console.log("on click:")
51
  const position = data.target.getPosition()
 
73
 
74
  />
75
  )
76
+ }
 
 
src/lib/getImageDimension.ts ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ export interface ImageDimension {
2
+ width: number
3
+ height: number
4
+ }
5
+
6
+ export async function getImageDimension(src: string): Promise<ImageDimension> {
7
+ if (!src) {
8
+ return { width: 0, height: 0 }
9
+ }
10
+ const img = new Image()
11
+ img.src = src
12
+ await img.decode()
13
+ const width = img.width
14
+ const height = img.height
15
+ return { width, height }
16
+ }
src/lib/useImageDimension.ts ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { useEffect, useState } from "react"
2
+
3
+ import { ImageDimension, getImageDimension } from "./getImageDimension"
4
+
5
+ export function useImageDimension(src: string) {
6
+ const [dimension, setDimension] = useState<ImageDimension>({
7
+ width: 0,
8
+ height: 0,
9
+ })
10
+
11
+ useEffect(() => {
12
+ const compute = async () => {
13
+ const newDimension = await getImageDimension(src)
14
+ setDimension(newDimension)
15
+ }
16
+ compute()
17
+ }, [src])
18
+
19
+ return dimension
20
+ }