我无法弄清楚如何将 setUserCallbacks() 设置的回调函数应用于使用 newSubscene3d() 生成的场景,第一个场景除外。
在下面的示例中,添加的场景覆盖了原始场景的左下角,但我不知道如何接收这部分的事件。
如果所需的输出不是 HTML,可以使用多种方法。例如,可以创建一个覆盖整个视口的场景作为最顶层的场景来代表其他场景接收和处理事件。
% R -e rmarkdown::render"('index.Rmd',output_file='index.html')"
---
title: "WebGL callback for a subscene created with newSubscene3d()"
output: html_document
vignette: >
%\VignetteIndexEntry{Callback implementation}
%\VignetteEngine{knitr::rmarkdown}
%\VignetteEncoding{UTF-8}
---
```{r setup, include=FALSE}
library(knitr)
library(rgl)
options(rgl.useNULL = TRUE)
setupKnitr(autoprint = FALSE)
opts_chunk$set(echo=FALSE, error=FALSE, warning=FALSE, message=FALSE)
knit_hooks$set(webgl = hook_webgl)
setupKnitr(autoprint = FALSE)
```
```{r}
sys.source("ex.R", envir = knit_global())
func1()
scene <- setUserCallbacks("left",
begin = "alert('AAA')",
update = "alert('BBB')",
end = "alert('CCC')",
scene = scene3d(minimal = FALSE),
subscene = scene3d(minimal = FALSE)$rootSubscene$id,
applyToScene = TRUE,
applyToDev = FALSE)
rglwidget(scene)
```
## This is ex.R.
library(rgl)
func1 <- function() {
func1.dev.id <- open3d()
func1.scene.1 <- subsceneInfo()$id
par3d(windowRect = c(0, 0, 500, 500))
view3d(theta=0, phi=0, zoom=1, fov=0)
spheres3d(0,0,0, r=10, color = "green", alpha=0.5) #
spheres3d(500,500,0, r=10, color = "green", alpha=0.5) #
start <- list()
begin <- function(x, y) {
set3d(func1.dev.id, silent = TRUE)
start$x <<- x
start$y <<- y
start$umat <<- par3d(subscene = func1.scene.1, "userMatrix")
start$umat <<- par3d(subscene = func1.scene.2, "userMatrix")
}
update <- function(x, y) {
viewport <- par3d("viewport")
x <- (x - start$x) / viewport[["width"]] / 1 # 1 is enpirically determined
y <- (y - start$y) / viewport[["height"]] / 1
umat <- start$umat
umat <- umat %*% rotationMatrix(x, 0, 1, 0) # disp. y
umat <- umat %*% rotationMatrix(y, 1, 0, 0) # disp. x
par3d(subscene = func1.scene.1, userMatrix=umat)
par3d(subscene = func1.scene.2, userMatrix=umat)
}
func1.scene.2 <- newSubscene3d(newviewport = c(0, 0, 200, 200))
useSubscene3d(func1.scene.2)
spheres3d(0,200,0, r=10, color = "red", alpha=0.5) #
spheres3d(200,0,0, r=10, color = "red", alpha=0.5) #
rgl.setMouseCallbacks(1, begin, update)
}
当您编写
subscene = scene3d(minimal = FALSE)$rootSubscene$id
时,您要求在根子场景上设置回调。如果它不是根子场景,您应该使用您想要的子场景的 id。
此外,表达式
scene3d(minimal = FALSE)$rootSubscene$id
比它需要的更复杂。 rglwidget()
显示中使用的 id 与 R 会话中的 id 相同。因此,如果您想对您创建的子场景进行回调
func1.scene.2 <- newSubscene3d(newviewport = c(0, 0, 200, 200))
那么您应该保存值
func1.scene.2
,并在调用 subscene
时使用该值作为 setUserCallbacks
参数。最简单的方法是从 func1
返回它,然后在文档中使用此代码:
sys.source("ex.R", envir = knit_global())
subsceneid <- func1()
scene <- setUserCallbacks("left",
begin = "alert('AAA')",
update = "alert('BBB')",
end = "alert('CCC')",
scene = scene3d(minimal = FALSE),
subscene = subsceneid,
applyToScene = TRUE,
applyToDev = FALSE)
rglwidget(scene)