Spaces:
Runtime error
Runtime error
Commit
·
1be0bd5
1
Parent(s):
9349de1
fix for video segmentation
Browse files- src/app/games/enchanters.ts +2 -0
- src/app/games/flamenco.ts +41 -0
- src/app/games/index.ts +4 -2
- src/app/games/pharaoh.ts +35 -0
- src/app/games/types.ts +1 -1
- src/app/main.tsx +17 -17
- src/app/queries/getActionnables.ts +16 -2
- src/app/queries/getDialogue.ts +1 -0
- src/app/render.ts +2 -2
- src/components/business/cartesian-video.tsx +4 -0
src/app/games/enchanters.ts
CHANGED
@@ -14,6 +14,8 @@ const initialActionnables = [
|
|
14 |
"lake",
|
15 |
"roof",
|
16 |
"boat",
|
|
|
|
|
17 |
]
|
18 |
|
19 |
export const game: Game = {
|
|
|
14 |
"lake",
|
15 |
"roof",
|
16 |
"boat",
|
17 |
+
"mountain",
|
18 |
+
"sky"
|
19 |
]
|
20 |
|
21 |
export const game: Game = {
|
src/app/games/flamenco.ts
ADDED
@@ -0,0 +1,41 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import { macondo } from "@/lib/fonts"
|
2 |
+
import { Game } from "./types"
|
3 |
+
|
4 |
+
const initialSituation = [
|
5 |
+
`beautiful view of an art deco building in new york`,
|
6 |
+
`looking up`,
|
7 |
+
`entrance desk`,
|
8 |
+
`pigeon character`,
|
9 |
+
`day of the dead makeup`,
|
10 |
+
`artdeco bridge`,
|
11 |
+
].join(", ")
|
12 |
+
|
13 |
+
const initialActionnables = [
|
14 |
+
"pigeon",
|
15 |
+
"face",
|
16 |
+
"person",
|
17 |
+
"building",
|
18 |
+
"light",
|
19 |
+
"decoration",
|
20 |
+
"box",
|
21 |
+
"desk",
|
22 |
+
"gate",
|
23 |
+
"door"
|
24 |
+
]
|
25 |
+
|
26 |
+
export const game: Game = {
|
27 |
+
title: "Sad Flamenco",
|
28 |
+
type: "flamenco",
|
29 |
+
engine: "spherical_image",
|
30 |
+
className: macondo.className,
|
31 |
+
initialSituation,
|
32 |
+
initialActionnables,
|
33 |
+
getScenePrompt: (situation?: string) => [
|
34 |
+
`photo of an artdeco scene`,
|
35 |
+
`grimfandango screenshot`,
|
36 |
+
`unreal engine`,
|
37 |
+
`1920 mexico`,
|
38 |
+
situation || initialSituation,
|
39 |
+
]
|
40 |
+
}
|
41 |
+
|
src/app/games/index.ts
CHANGED
@@ -6,9 +6,11 @@ import { game as dungeon } from "./dungeon"
|
|
6 |
import { game as doom } from "./doom"
|
7 |
import { game as vernian } from "./vernian"
|
8 |
import { game as enchanters } from "./enchanters"
|
|
|
|
|
9 |
|
10 |
-
export const games = { pirates, city, dungeon, doom, vernian, enchanters}
|
11 |
|
12 |
-
export const defaultGame: GameType = "
|
13 |
|
14 |
export const getGame = (type?: GameType) => games[type || defaultGame] || games[defaultGame]
|
|
|
6 |
import { game as doom } from "./doom"
|
7 |
import { game as vernian } from "./vernian"
|
8 |
import { game as enchanters } from "./enchanters"
|
9 |
+
import { game as flamenco } from "./flamenco"
|
10 |
+
import { game as pharaoh } from "./pharaoh"
|
11 |
|
12 |
+
export const games = { pirates, city, dungeon, doom, vernian, enchanters, flamenco, pharaoh}
|
13 |
|
14 |
+
export const defaultGame: GameType = "flamenco"
|
15 |
|
16 |
export const getGame = (type?: GameType) => games[type || defaultGame] || games[defaultGame]
|
src/app/games/pharaoh.ts
ADDED
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import { macondo } from "@/lib/fonts"
|
2 |
+
import { Game } from "./types"
|
3 |
+
|
4 |
+
const initialSituation = [
|
5 |
+
`looking at a beautiful pyramid, ancient egypt, during golden hour, surrounded by sand dunes, near the Nile`,
|
6 |
+
].join(", ")
|
7 |
+
|
8 |
+
const initialActionnables = [
|
9 |
+
"pyramid",
|
10 |
+
"person",
|
11 |
+
"rocks",
|
12 |
+
"dune",
|
13 |
+
"sceptre",
|
14 |
+
"tree",
|
15 |
+
"river",
|
16 |
+
"boat",
|
17 |
+
"crocodile"
|
18 |
+
]
|
19 |
+
|
20 |
+
export const game: Game = {
|
21 |
+
title: "Pharaoh",
|
22 |
+
type: "pharaoh",
|
23 |
+
engine: "spherical_image",
|
24 |
+
className: macondo.className,
|
25 |
+
initialSituation,
|
26 |
+
initialActionnables,
|
27 |
+
getScenePrompt: (situation?: string) => [
|
28 |
+
`Screenshot from a videogame`,
|
29 |
+
`unreal engine`,
|
30 |
+
`ancient egypt`,
|
31 |
+
`first person`,
|
32 |
+
situation || initialSituation,
|
33 |
+
]
|
34 |
+
}
|
35 |
+
|
src/app/games/types.ts
CHANGED
@@ -1,6 +1,6 @@
|
|
1 |
import { EngineType } from "../engines"
|
2 |
|
3 |
-
export type GameType = "pirates" | "city" | "dungeon" | "doom" | "vernian" | "enchanters"
|
4 |
|
5 |
export interface Scene {
|
6 |
actionnables: string[]
|
|
|
1 |
import { EngineType } from "../engines"
|
2 |
|
3 |
+
export type GameType = "pirates" | "city" | "dungeon" | "doom" | "vernian" | "enchanters" | "pharaoh" | "flamenco"
|
4 |
|
5 |
export interface Scene {
|
6 |
actionnables: string[]
|
src/app/main.tsx
CHANGED
@@ -35,7 +35,7 @@ const getInitialRenderedScene = (): RenderedScene => ({
|
|
35 |
export default function Main() {
|
36 |
const [isPending, startTransition] = useTransition()
|
37 |
const [rendered, setRendered] = useState<RenderedScene>(getInitialRenderedScene())
|
38 |
-
const
|
39 |
const router = useRouter()
|
40 |
const pathname = usePathname()
|
41 |
const searchParams = useSearchParams()
|
@@ -50,7 +50,7 @@ export default function Main() {
|
|
50 |
const debug = (searchParams.get('debug') === "true")
|
51 |
|
52 |
const [situation, setSituation] = useState("")
|
53 |
-
|
54 |
const [dialogue, setDialogue] = useState("")
|
55 |
const [hoveredActionnable, setHoveredActionnable] = useState("")
|
56 |
|
@@ -59,14 +59,13 @@ export default function Main() {
|
|
59 |
|
60 |
const loopRef = useRef<any>(null)
|
61 |
|
62 |
-
|
63 |
const loadNextScene = async (nextSituation?: string, nextActionnables?: string[]) => {
|
64 |
|
65 |
await startTransition(async () => {
|
66 |
console.log("Rendering a scene for " + game.type)
|
67 |
|
68 |
// console.log(`rendering scene..`)
|
69 |
-
|
70 |
engine,
|
71 |
|
72 |
// SCENE PROMPT
|
@@ -79,7 +78,7 @@ export default function Main() {
|
|
79 |
).slice(0, 10) // too many can slow us down it seems
|
80 |
})
|
81 |
|
82 |
-
console.log("got the first version of our scene!",
|
83 |
|
84 |
// detect if type game type changed while we were busy
|
85 |
if (game?.type !== gameRef?.current) {
|
@@ -87,16 +86,17 @@ export default function Main() {
|
|
87 |
return
|
88 |
}
|
89 |
|
90 |
-
|
91 |
-
|
92 |
-
setRendered(renderedRef.current)
|
93 |
})
|
94 |
}
|
95 |
|
96 |
const checkRenderedLoop = async () => {
|
97 |
// console.log("checkRenderedLoop! rendered:", renderedRef.current)
|
98 |
clearTimeout(loopRef.current)
|
99 |
-
|
|
|
|
|
100 |
// console.log("let's try again in a moments")
|
101 |
loopRef.current = setTimeout(() => checkRenderedLoop(), 200)
|
102 |
return
|
@@ -106,13 +106,13 @@ export default function Main() {
|
|
106 |
await startTransition(async () => {
|
107 |
// console.log(`getting latest updated scene..`)
|
108 |
try {
|
109 |
-
if (!
|
110 |
throw new Error(`missing renderId`)
|
111 |
}
|
112 |
|
113 |
|
114 |
// console.log(`calling getRender(${renderedRef.current.renderId})`)
|
115 |
-
const newRendered = await getRender(
|
116 |
// console.log(`got latest updated scene:`, renderedRef.current)
|
117 |
|
118 |
// detect if type game type changed while we were busy
|
@@ -122,13 +122,13 @@ export default function Main() {
|
|
122 |
}
|
123 |
|
124 |
|
125 |
-
const before = JSON.stringify(
|
126 |
const after = JSON.stringify(newRendered)
|
127 |
|
128 |
if (after !== before) {
|
129 |
console.log("updating scene..")
|
130 |
-
|
131 |
-
setRendered(
|
132 |
|
133 |
if (newRendered.status === "completed") {
|
134 |
setBusy(busyRef.current = false)
|
@@ -283,7 +283,7 @@ export default function Main() {
|
|
283 |
</div>
|
284 |
|
285 |
<div className={[
|
286 |
-
"flex flex-col w-full pt-4 space-y-3
|
287 |
getGame(gameRef.current).className // apply the game theme
|
288 |
].join(" ")}>
|
289 |
<div className="flex flex-row">
|
@@ -299,7 +299,7 @@ export default function Main() {
|
|
299 |
{i < (clickables.length - 1) ? <div>,</div> : null}
|
300 |
</div>)}
|
301 |
</div>
|
302 |
-
<div className="text-xl p-
|
303 |
You are looking at: <span className="font-bold">{hoveredActionnable || "nothing"}</span>
|
304 |
</div>
|
305 |
<Renderer
|
@@ -311,7 +311,7 @@ export default function Main() {
|
|
311 |
engine={engine}
|
312 |
debug={debug}
|
313 |
/>
|
314 |
-
<div className="text-xl rounded-xl backdrop-blur-sm bg-white/30">{dialogue}</div>
|
315 |
</div>
|
316 |
</div>
|
317 |
)
|
|
|
35 |
export default function Main() {
|
36 |
const [isPending, startTransition] = useTransition()
|
37 |
const [rendered, setRendered] = useState<RenderedScene>(getInitialRenderedScene())
|
38 |
+
const historyRef = useRef<RenderedScene[]>([])
|
39 |
const router = useRouter()
|
40 |
const pathname = usePathname()
|
41 |
const searchParams = useSearchParams()
|
|
|
50 |
const debug = (searchParams.get('debug') === "true")
|
51 |
|
52 |
const [situation, setSituation] = useState("")
|
53 |
+
|
54 |
const [dialogue, setDialogue] = useState("")
|
55 |
const [hoveredActionnable, setHoveredActionnable] = useState("")
|
56 |
|
|
|
59 |
|
60 |
const loopRef = useRef<any>(null)
|
61 |
|
|
|
62 |
const loadNextScene = async (nextSituation?: string, nextActionnables?: string[]) => {
|
63 |
|
64 |
await startTransition(async () => {
|
65 |
console.log("Rendering a scene for " + game.type)
|
66 |
|
67 |
// console.log(`rendering scene..`)
|
68 |
+
const newRendered = await newRender({
|
69 |
engine,
|
70 |
|
71 |
// SCENE PROMPT
|
|
|
78 |
).slice(0, 10) // too many can slow us down it seems
|
79 |
})
|
80 |
|
81 |
+
console.log("got the first version of our scene!", newRendered)
|
82 |
|
83 |
// detect if type game type changed while we were busy
|
84 |
if (game?.type !== gameRef?.current) {
|
|
|
86 |
return
|
87 |
}
|
88 |
|
89 |
+
historyRef.current.unshift(newRendered)
|
90 |
+
setRendered(newRendered)
|
|
|
91 |
})
|
92 |
}
|
93 |
|
94 |
const checkRenderedLoop = async () => {
|
95 |
// console.log("checkRenderedLoop! rendered:", renderedRef.current)
|
96 |
clearTimeout(loopRef.current)
|
97 |
+
|
98 |
+
if (!historyRef.current[0]?.renderId || historyRef.current[0]?.status !== "pending") {
|
99 |
+
|
100 |
// console.log("let's try again in a moments")
|
101 |
loopRef.current = setTimeout(() => checkRenderedLoop(), 200)
|
102 |
return
|
|
|
106 |
await startTransition(async () => {
|
107 |
// console.log(`getting latest updated scene..`)
|
108 |
try {
|
109 |
+
if (!historyRef.current[0]?.renderId) {
|
110 |
throw new Error(`missing renderId`)
|
111 |
}
|
112 |
|
113 |
|
114 |
// console.log(`calling getRender(${renderedRef.current.renderId})`)
|
115 |
+
const newRendered = await getRender(historyRef.current[0]?.renderId)
|
116 |
// console.log(`got latest updated scene:`, renderedRef.current)
|
117 |
|
118 |
// detect if type game type changed while we were busy
|
|
|
122 |
}
|
123 |
|
124 |
|
125 |
+
const before = JSON.stringify(historyRef.current[0])
|
126 |
const after = JSON.stringify(newRendered)
|
127 |
|
128 |
if (after !== before) {
|
129 |
console.log("updating scene..")
|
130 |
+
historyRef.current[0] = newRendered
|
131 |
+
setRendered(historyRef.current[0])
|
132 |
|
133 |
if (newRendered.status === "completed") {
|
134 |
setBusy(busyRef.current = false)
|
|
|
283 |
</div>
|
284 |
|
285 |
<div className={[
|
286 |
+
"flex flex-col w-full pt-4 space-y-3 text-gray-50 dark:text-gray-50",
|
287 |
getGame(gameRef.current).className // apply the game theme
|
288 |
].join(" ")}>
|
289 |
<div className="flex flex-row">
|
|
|
299 |
{i < (clickables.length - 1) ? <div>,</div> : null}
|
300 |
</div>)}
|
301 |
</div>
|
302 |
+
<div className="text-xl p-4 rounded-xl backdrop-blur-sm bg-white/30">
|
303 |
You are looking at: <span className="font-bold">{hoveredActionnable || "nothing"}</span>
|
304 |
</div>
|
305 |
<Renderer
|
|
|
311 |
engine={engine}
|
312 |
debug={debug}
|
313 |
/>
|
314 |
+
<div className="text-xl rounded-xl backdrop-blur-sm bg-white/30 p-4">{dialogue}</div>
|
315 |
</div>
|
316 |
</div>
|
317 |
)
|
src/app/queries/getActionnables.ts
CHANGED
@@ -77,8 +77,22 @@ export const getActionnables = async ({
|
|
77 |
throw new Error("no actionnables")
|
78 |
}
|
79 |
} catch (err) {
|
80 |
-
console.log("failed to repair and recover a valid JSON!")
|
81 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
82 |
}
|
83 |
}
|
84 |
|
|
|
77 |
throw new Error("no actionnables")
|
78 |
}
|
79 |
} catch (err) {
|
80 |
+
console.log("failed to repair and recover a valid JSON! Using a generic fallback..")
|
81 |
+
|
82 |
+
return [
|
83 |
+
"door",
|
84 |
+
"rock",
|
85 |
+
"window",
|
86 |
+
"table",
|
87 |
+
"ground",
|
88 |
+
"sky",
|
89 |
+
"box",
|
90 |
+
"tree",
|
91 |
+
"wall",
|
92 |
+
"floor"
|
93 |
+
]
|
94 |
+
|
95 |
+
// throw new Error("failed to parse the actionnables")
|
96 |
}
|
97 |
}
|
98 |
|
src/app/queries/getDialogue.ts
CHANGED
@@ -41,6 +41,7 @@ Here is the original scene in which the user was located at first, which will in
|
|
41 |
basePrompt,
|
42 |
`You must imagine a funny response to speak in reaction to what the player did, like in some old point and click video games.`,
|
43 |
`Please limit yourself to only a 1 or 2 sentences, please.`,
|
|
|
44 |
].filter(item => item).join("\n")
|
45 |
},
|
46 |
{
|
|
|
41 |
basePrompt,
|
42 |
`You must imagine a funny response to speak in reaction to what the player did, like in some old point and click video games.`,
|
43 |
`Please limit yourself to only a 1 or 2 sentences, please.`,
|
44 |
+
`Also please don't say things like "Well, well, well", it is annoying.`
|
45 |
].filter(item => item).join("\n")
|
46 |
},
|
47 |
{
|
src/app/render.ts
CHANGED
@@ -54,7 +54,7 @@ export async function newRender({
|
|
54 |
prompt,
|
55 |
// nbFrames: 8 and nbSteps: 15 --> ~10 sec generation
|
56 |
nbFrames, // when nbFrames is 1, we will only generate static images
|
57 |
-
nbSteps: isForVideo ?
|
58 |
actionnables,
|
59 |
segmentation: "firstframe", // one day we will remove this param, to make it automatic
|
60 |
width: isForVideo ? 576 : 1024,
|
@@ -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 ?
|
76 |
actionnables,
|
77 |
segmentation: "firstframe", // one day we will remove this param, to make it automatic
|
78 |
width: isForVideo ? 576 : 1024,
|
|
|
54 |
prompt,
|
55 |
// nbFrames: 8 and nbSteps: 15 --> ~10 sec generation
|
56 |
nbFrames, // when nbFrames is 1, we will only generate static images
|
57 |
+
nbSteps: isForVideo ? 25 : 35, // 20 = fast, 30 = better, 50 = best
|
58 |
actionnables,
|
59 |
segmentation: "firstframe", // one day we will remove this param, to make it automatic
|
60 |
width: isForVideo ? 576 : 1024,
|
|
|
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,
|
src/components/business/cartesian-video.tsx
CHANGED
@@ -44,11 +44,15 @@ export const CartesianVideo = forwardRef(({
|
|
44 |
muted
|
45 |
autoPlay
|
46 |
loop
|
|
|
|
|
47 |
className="absolute"
|
48 |
/>
|
49 |
{debug && <img
|
50 |
src={rendered.maskUrl || undefined}
|
51 |
className="absolute opacity-50"
|
|
|
|
|
52 |
/>}
|
53 |
</div>
|
54 |
)
|
|
|
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 |
)
|