File size: 5,657 Bytes
2a5255e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0

import os

from kimodo.assets import DEMO_EXAMPLES_ROOT
from kimodo.model.registry import (
    AVAILABLE_MODELS,
    DEFAULT_MODEL,
    FRIENDLY_NAMES,
    get_datasets,
    get_model_info,
    get_models_for_dataset_skeleton,
    get_short_key_from_display_name,
    get_skeleton_display_name,
    get_skeleton_display_names_for_dataset,
    get_skeleton_key_from_display_name,
    get_skeletons_for_dataset,
    get_versions_for_dataset_skeleton,
    resolve_to_short_key,
)

SERVER_NAME = os.environ.get("SERVER_NAME", "0.0.0.0")
SERVER_PORT = int(os.environ.get("SERVER_PORT") or os.environ.get("PORT", "7860"))


def _env_bool(name: str, default: bool = False) -> bool:
    raw = os.environ.get(name)
    if raw is None:
        return default
    return str(raw).strip().lower() in ("1", "true", "yes", "on")


HF_MODE = _env_bool("HF_MODE", False)

# HF mode: user queue and session limit (override via env in Spaces)
MAX_ACTIVE_USERS = int(os.environ.get("MAX_ACTIVE_USERS", "5"))
MAX_SESSION_MINUTES = float(os.environ.get("MAX_SESSION_MINUTES", "5.0"))

DEFAULT_PLAYBACK_SPEED = 1.0
# default start duration is 6.0 sec, but model can handle up to 10 sec
DEFAULT_CUR_DURATION = 6.0
DEFAULT_PROMPT = "A person walks forward."
MIN_DURATION = 2.0
MAX_DURATION = 10.0

SHOW_TRANSITION_PARAMS = False
INIT_POSTPROCESSING = True
NB_TRANSITION_FRAMES = 5

LIGHT_THEME = dict(
    floor=(220, 220, 220),
    grid=(180, 180, 180),
)

# Dark theme: slightly lighter grid and floor for better visibility and less flat black
DARK_THEME = dict(
    floor=(48, 48, 52),
    grid=(105, 105, 110),
)

EXAMPLES_ROOT_DIR = str(DEMO_EXAMPLES_ROOT)

# Model list and paths from kimodo registry (all models: Kimodo + TMR)
MODEL_NAMES = tuple(AVAILABLE_MODELS)
MODEL_EXAMPLES_DIRS = {name: os.path.join(EXAMPLES_ROOT_DIR, name) for name in MODEL_NAMES}
# Display labels for backward compatibility (short_key -> display name)
MODEL_LABELS = {name: FRIENDLY_NAMES.get(name, f"Model ({name})") for name in MODEL_NAMES}
MODEL_LABEL_TO_NAME = {label: name for name, label in MODEL_LABELS.items()}

# -----------------------------------------------------------------------------
# Demo UI copy
# -----------------------------------------------------------------------------

DEMO_UI_QUICK_START_CORE_MD = """
### Camera
- **Left-drag**: rotate
- **Right-drag**: pan
- **Scroll**: zoom

### Playback
- **Space** to play/pause
- **←/→** to step frames, or click the frame number.
- **Scroll up/down** in the timeline: move left/right
- **Shift + scroll** in the timeline: zoom in/out

### Prompts
- **Double-click** a text prompt to edit it.
- **Click and drag** the right edge of a prompt box to extend/shorten it.
- **Click empty space** to add a prompt.
- **Right-click** a prompt to delete it.

### Generate
- Go to the **Generate** tab to modify options
- It is also possible to **load** examples
- Click **Generate** to generate a motion

### Constraints
- This is **optional**: should be use after a first generation
- **Click** in the timeline tracks (Full-Body / 2D root etc) to add a constraint.
- **Right-click** on a constraint to delete it.
- To **edit** a constraint:
    - Move playback to the target frame
    - Click **Enter Editing Mode** in the Constraints tab.
"""

DEMO_UI_QUICK_START_MODAL_MD = (
    DEMO_UI_QUICK_START_CORE_MD
    + """

See the **Instructions** tab for the full user manual.
"""
)

DEMO_UI_INSTRUCTIONS_TAB_MD = (
    """
## How to Use This Demo

"""
    + DEMO_UI_QUICK_START_CORE_MD
    + """

---

### Generating Motion (step-by-step)

1. **Edit the text prompts** in the timeline (e.g., "A person walks forward.")
2. **Modify the duration** by moving the right edge of each prompts (2–10 seconds)
3. **Add constraints** (optional) to control the motion:
   - Click **Enter Editing Mode** to adjust the character pose
   - Use the timeline to place keyframes or intervals in constraint tracks (see below)
4. **Click Generate** to create the motion
5. If generating multiple samples, **click on a mesh** to select which one to keep

### Timeline Editing

**Adding Constraints:**
1. Click anywhere on the timeline to add a keyframe at that frame. The keyframe is created based on the current character motion.
2. Ctrl/Cmd+click+drag to add an interval constraint, or expand a keyframe into an interval
3. Enter editing mode with the **Enter Editing Mode** button to adjust character pose before/after adding constraints.

**Constraint Types:**
- **Full-Body**: constrains the entire character pose
- **2D Root**: constrains the character's path on the ground plane
  - Enable **Densify** to create a continuous path
- **End-Effectors**: constrains hands and feet positions
  - Use separate tracks for Left/Right Hand/Foot


**Moving & Deleting:**
- **Drag keyframes/intervals** to move them to different frames
- **Right-click** a keyframe or interval to delete it
- Use **Clear All Constraints** to remove everything

**Tips:**
- The posing skeleton becomes visible in editing mode for precise positioning
- Use **Snap to constraint** to align the current frame to a constraint

### Saving & Loading

You can save the current constraints or current motion to load in later from the Load/Save menu.
Saving an **Example** will save the full constraints, motion, and generation metadata.

### Visualization Options

Switch to the **Visualize** tab to:
- Toggle mesh and skeleton visibility
- Adjust mesh opacity
- Show/hide foot contact indicators
- Switch between light and dark modes
"""
)