Skip to content

Commit

Permalink
Minor bug fixes (serialization, search params), playback improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
brentyi committed Jul 17, 2024
1 parent e89eaa8 commit f82f7a2
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 34 deletions.
12 changes: 7 additions & 5 deletions src/viser/client/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -132,10 +132,9 @@ function ViewerRoot() {
servers.length >= 1 ? servers[0] : getDefaultServerFromUrl();

// Playback mode for embedding viser.
const playbackPath = new URLSearchParams(window.location.search).get(
"playbackPath",
);
console.log(playbackPath);
const searchParams = new URLSearchParams(window.location.search);
const playbackPath = searchParams.get("playbackPath");
const darkMode = searchParams.get("darkMode") !== null;

// Values that can be globally accessed by components in a viewer.
const viewer: ViewerContextContents = {
Expand Down Expand Up @@ -179,6 +178,9 @@ function ViewerRoot() {
skinnedMeshState: React.useRef({}),
};

// Set dark default if specified in URL.
if (darkMode) viewer.useGui.getState().theme.dark_mode = darkMode;

return (
<ViewerContext.Provider value={viewer}>
<ViewerContents>
Expand Down Expand Up @@ -441,7 +443,7 @@ function ViewerCanvas({ children }: { children: React.ReactNode }) {
<SceneContextSetter />
<SynchronizedCameraControls />
<SceneNodeThreeObject name="" parent={null} />
<Environment path="/hdri/" files="potsdamer_platz_1k.hdr" />
<Environment path="hdri/" files="potsdamer_platz_1k.hdr" />
<directionalLight color={0xffffff} intensity={1.0} position={[0, 1, 0]} />
<directionalLight
color={0xffffff}
Expand Down
2 changes: 1 addition & 1 deletion src/viser/client/src/FilePlayback.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ export function PlaybackFromFile({ fileUrl }: { fileUrl: string }) {
<Progress
value={(status.downloaded / status.total) * 100.0}
radius={0}
transitionDuration={100}
transitionDuration={0}
/>
</div>
);
Expand Down
37 changes: 19 additions & 18 deletions src/viser/client/src/SearchParamsUtils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,30 +5,31 @@
export const searchParamKey = "websocket";

export function syncSearchParamServer(server: string) {
setServerParams([server]);
}

function setServerParams(serverParams: string[]) {
const searchParams = new URLSearchParams(window.location.search);
// No need to update the URL bar if the websocket port matches the HTTP port.
// So if we navigate to http://localhost:8081, this should by default connect to ws://localhost:8081.
if (
serverParams.length === 1 &&
(window.location.host.includes(
serverParams[0].replace("ws://", "").replace("/", ""),
const isDefaultServer =
window.location.host.includes(
server.replace("ws://", "").replace("/", ""),
) ||
window.location.host.includes(
serverParams[0].replace("wss://", "").replace("/", ""),
))
)
serverParams = [];

window.location.host.includes(
server.replace("wss://", "").replace("/", ""),
);
if (isDefaultServer && searchParams.has(searchParamKey)) {
searchParams.delete(searchParamKey);
} else if (!isDefaultServer) {
searchParams.set(searchParamKey, server);
}
window.history.replaceState(
null,
"Viser",
// We could use URLSearchParams() to build this string, but that would escape
// it. We're going to just not escape the string. :)
serverParams.length === 0
// We could use URLSearchParams.toString() to build this string, but that
// would escape it. We're going to just not escape the string. :)
searchParams.size === 0
? window.location.href.split("?")[0]
: `?${serverParams.map((s) => `${searchParamKey}=${s}`).join("&")}`,
: "?" +
Array.from(searchParams.entries())
.map(([k, v]) => `${k}=${v}`)
.join("&"),
);
}
26 changes: 16 additions & 10 deletions src/viser/infra/_messages.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,33 +44,36 @@ def _prepare_for_deserialization(value: Any, annotation: Type) -> Any:
return value


def _prepare_for_serialization(value: Any, annotation: Type) -> Any:
def _prepare_for_serialization(value: Any, annotation: object) -> Any:
"""Prepare any special types for serialization."""
if annotation is Any:
annotation = type(value)

# Coerce some scalar types: if we've annotated as float / int but we get an
# onp.float32 / onp.int64, for example, we should cast automatically.
if annotation is float:
if annotation is float or isinstance(value, onp.floating):
return float(value)
if annotation is int:
if annotation is int or isinstance(value, onp.integer):
return int(value)

# Recursively handle tuples.
if get_origin(annotation) is tuple:
if isinstance(value, tuple):
if isinstance(value, onp.ndarray):
assert False, (
"Expected a tuple, but got an array... missing a cast somewhere?"
f" {value}"
)

out = []
args = get_args(annotation)
if len(args) >= 2 and args[1] == ...:
args = (args[0],) * len(value)
elif len(value) != len(args):
warnings.warn(f"[viser] {value} does not match annotation {annotation}")
return value
if get_origin(annotation) is tuple:
args = get_args(annotation)
if len(args) >= 2 and args[1] == ...:
args = (args[0],) * len(value)
elif len(value) != len(args):
warnings.warn(f"[viser] {value} does not match annotation {annotation}")
return value
else:
args = [Any] * len(value)

for i, v in enumerate(value):
out.append(
Expand All @@ -85,6 +88,9 @@ def _prepare_for_serialization(value: Any, annotation: Type) -> Any:
if isinstance(value, onp.ndarray):
return value.data if value.data.c_contiguous else value.copy().data

if isinstance(value, dict):
return {k: _prepare_for_serialization(v, Any) for k, v in value.items()} # type: ignore

return value


Expand Down

0 comments on commit f82f7a2

Please sign in to comment.