Nothing
scene3d <- function(minimal = TRUE) {
saveSubscene <- currentSubscene3d()
on.exit(useSubscene3d(saveSubscene))
defaultmaterial <- material3d()
matdiff <- function(mat) {
for (m in names(mat)) {
if (identical(mat[[m]], defaultmaterial[[m]]))
mat[[m]] <- NULL
}
mat
}
getObject <- function(id, type) {
result <- list(id=id, type=type)
if (!(type %in% c("light", "clipplanes"))) {
mat <- rgl.getmaterial(id=id)
lit <- mat$lit
result$material <- matdiff(mat)
} else
lit <- FALSE
attribs <- c("vertices", "colors", "texcoords", "dim",
"texts", "cex", "adj", "radii", "ids",
"usermatrix", "types", "offsets", "centers",
"family", "font", "pos", "axes", "indices", "normals", "shapenum")
for (a in attribs)
if (rgl.attrib.count(id, a))
result[[a]] <- rgl.attrib(id, a)
flags <- rgl.attrib(id, "flags")
if (length(flags)) {
if ("ignoreExtent" %in% rownames(flags))
result$ignoreExtent <- flags["ignoreExtent", 1]
if ("fixedSize" %in% rownames(flags))
result$fixedSize <- flags["fixedSize", 1]
if ("rotating" %in% rownames(flags))
result$rotating <- flags["rotating", 1]
if ("fastTransparency" %in% rownames(flags))
result$fastTransparency <- flags["fastTransparency", 1]
if ("flipped" %in% rownames(flags))
result$flipped <- flags["flipped", 1]
}
if (!is.null(result$ids)) {
objlist <- vector("list", nrow(result$ids))
for (i in seq_len(nrow(result$ids)))
objlist[[i]] <- getObject(result$ids[i,1], result$types[i,1])
result$objects <- objlist
}
if (type == "background") {
flags <- rgl.attrib(id, "flags")
result$sphere <- flags["sphere", 1]
result$fogtype <- if (flags["linear_fog", 1]) "linear"
else if (flags["exp_fog", 1]) "exp"
else if (flags["exp2_fog", 1]) "exp2"
else "none"
result$fogscale <- as.numeric(rgl.attrib(id, "fogscale"))
} else if (type == "bboxdeco") {
flags <- rgl.attrib(id, "flags")
result$draw_front <- flags["draw_front", 1]
} else if (type == "light") {
flags <- rgl.attrib(id, "flags")
result$viewpoint <- flags["viewpoint", 1]
result$finite <- flags["finite", 1]
}
class(result) <- c(paste0("rgl", type), "rglobject")
result
}
getSubscene <- function(id) {
useSubscene3d(id)
result <- list(id = id, type = "subscene", par3d = par3d())
result$embeddings <- subsceneInfo()$embeddings
objs <- ids3d(c("background", "bboxdeco", "shapes", "lights"))
result$objects <- objs$id
if (nrow(obj <- ids3d("subscene", subscene = id))) {
subscenes <- vector("list", nrow(obj))
ids <- obj$id
for (i in seq_len(nrow(obj)))
subscenes[[i]] <- getSubscene(ids[i])
result$subscenes <- subscenes
}
class(result) <- c("rglsubscene", "rglobject")
result
}
result <- list()
result$material <- defaultmaterial
result$rootSubscene <- getSubscene(rootSubscene())
objs <- ids3d(c("shapes", "lights", "background", "bboxdeco"), subscene=0)
objlist <- vector("list", nrow(objs))
ids <- objs$id
types <- as.character(objs$type)
for (i in seq_len(nrow(objs))) {
objlist[[i]] <- getObject(ids[i], types[i])
names(objlist)[i] <- as.character(ids[i])
}
result$objects <- objlist
# If there are user callbacks for the mouse, they'll
# be recorded in rgl.callback.env
devname <- paste0("dev", cur3d())
callbacks <- rgl.callback.env[[devname]]
if (!is.null(callbacks)) {
for (name in names(callbacks)) {
subscene <- sub("^sub", "", name)
sub <- findSubscene(result$rootSubscene, subscene)
if (!is.null(sub)) {
sub$callbacks <- callbacks[[name]]
result$rootSubscene <- replaceSubscene(result$rootSubscene, subscene, sub)
}
bboxid <- sub("^bbox", "", name)
bbox <- result$objects[[bboxid]]
if (!is.null(bbox)) {
bbox$callbacks <- callbacks[[name]]
result$objects[[bboxid]] <- bbox
}
}
result$javascript <- callbacks$javascript
}
class(result) <- "rglscene"
result
}
print.rglscene <- function(x, ...) {
cat(gettext("RGL scene containing:\n"))
if (!is.null(x$par3d))
cat(gettext(" par3d:\tscene information\n"))
if (!is.null(x$material))
cat(gettext(" material:\tdefault material properties\n"))
if (!is.null(x$objects)) {
cat(gettextf(" objects:\tlist of %d object(s):\n", length(x$objects)))
cat(" \t", sapply(x$objects, function(obj) obj$type), "\n")
}
if (!is.null(x$root))
cat(gettext(" root:\ta root subscene\n"))
invisible(x)
}
summary.rglscene <- function(object, ...) {
result <- list()
nobjs <- length(object$objects)
if (nobjs) result$objects <- data.frame(type=sapply(object$objects, function(obj) obj$type))
if (!is.null(object$rootSubscene))
result$subscenes <- summary(object$rootSubscene)
result
}
summary.rglsubscene <- function(object, ...) {
result <- data.frame(id = object$id, parent = NA, objects = 0)
result$objects <- list(object$objects)
if (length(object$subscenes)) {
children <- do.call(rbind, lapply(object$subscenes, summary))
children[is.na(children$parent),"parent"] <- object$id
result <- rbind(result, children)
}
result
}
print.rglobject <- function(x, ...) {
cat(gettextf("RGL object of type %s containing components\n", x$type))
cat(" ")
cat(names(x), sep=", ")
cat("\n")
}
print.rglsubscene <- function(x, ...) {
cat(gettext("RGL subscene containing components\n"))
cat(" ")
cat(names(x), sep=", ")
cat("\n")
}
plot3d.rglscene <- function(x, add=FALSE, open3dParams = getr3dDefaults(), ...) {
root <- x$rootSubscene
if (is.null(root)) root <- x # Should work with pre-subscene objects
if (!add) {
args <- list(...)
params <- open3dParams
params[names(args)] <- args
if (!is.null(x$material)) {
if (is.null(params$material)) params$material <- list()
params$material[names(x$material)] <- x$material
}
if (!is.null(root$bg)) {
if (is.null(params$bg)) params$bg <- list()
params$bg[names(params$material)] <- params$material
params$bg[names(x$bg$material)] <- x$bg$material
x$bg$material <- x$bg$id <- x$bg$type <- NULL
params$bg[names(x$bg)] <- x$bg
}
if (!is.null(root$par3d)) {
ind <- !(names(root$par3d) %in% rgl.par3d.readonly)
params[names(root$par3d)[ind]] <- root$par3d[ind]
}
open3d(params = params)
# Some older scenes might not have a light in them, so only clear if one is there
for (i in seq_along(x$objects)) {
obj <- x$objects[[i]]
if (obj$type == "light") {
clear3d("lights")
break
}
}
}
save <- par3d(skipRedraw = TRUE)
on.exit(par3d(save))
if (is.null(x$rootSubscene)) {
results <- NULL
for (i in seq_along(x$objects)) {
obj <- x$objects[[i]]
results <- c(results, plot3d(obj))
}
if (!is.null(obj <- x$bbox))
plot3d(obj)
} else
results <- plot3d(root, x$objects, root = TRUE, ...)
highlevel(results)
}
plot3d.rglsubscene <- function(x, objects, root = TRUE, ...) {
if (root) {
if (!is.null(x$embeddings)) {
info <- subsceneInfo(embeddings = x$embeddings)
subscene <- info$id
} else
subscene <- currentSubscene3d()
if (!is.null(x$par3d$viewport))
par3d(viewport = x$par3d$viewport)
} else
subscene <- newSubscene3d(viewport = x$embeddings["viewport"],
projection = x$embeddings["projection"],
model = x$embeddings["model"],
newviewport = x$par3d$viewport,
copyLights = FALSE)
if (!is.null(scale <- x$par3d$scale))
par3d(scale = scale)
if (!is.null(userMatrix <- x$par3d$userMatrix))
par3d(userMatrix = userMatrix)
listeners <- list(x$par3d$listeners) # list contains old ids
names(listeners) <- subscene # names are new ids
results <- subscene
names(results) <- paste0("subscene", as.character(x$id))
objs <- x$objects
for (id in as.character(objs)) {
obj <- objects[[id]]
if (is.null(obj$newid))
results <- c(results, objects[[id]]$newid <- plot3d(obj, ...))
else
addToSubscene3d(obj$newid)
}
for (i in seq_along(x$subscenes)) {
useSubscene3d(subscene)
res <- plot3d(x$subscenes[[i]], objects, root=FALSE, ...)
results <- c(results, res$results)
listeners <- c(listeners, res$listeners)
objects <- res$objects
}
if (root) {
# Translate all the listener values
dotranslations <- function(id) {
info <- subsceneInfo(id = id)
oldlisteners <- listeners[[as.character(id)]]
par3d(listeners = results[paste0("subscene", oldlisteners)], subscene = id)
for (child in info$children)
dotranslations(child)
}
dotranslations(subscene)
useSubscene3d(subscene)
return(results)
} else
return(list(results=results, objects=objects, listeners=listeners))
}
plot3d.rglobject <- function(x, ...) {
type <- x$type
fn <- switch(type,
points = points3d,
lines = segments3d,
linestrip = lines3d,
triangles = triangles3d,
quads = quads3d,
text = texts3d,
spheres = spheres3d,
abclines = abclines3d,
planes = planes3d,
surface = surface3d,
sprites = sprites3d,
light = light3d,
clipplanes = clipplanes3d,
NULL)
if (is.null(fn)) {
warning(gettextf("Object type '%s' not handled.", type),
domain = NA)
return()
}
if (!is.null(x$ignoreExtent)) {
save <- par3d(ignoreExtent = x$ignoreExtent)
on.exit(par3d(save))
}
args <- list()
args$x <- x$vertices
args$normals <- x$normals
args$texcoords <- x$texcoords
args$texts <- x$texts
args$cex <- x$cex
args$adj <- x$adj
args$radius <- x$radii
args$d <- x$offsets
args$indices <- x$indices
switch(type,
abclines = {
odd <- seq_len(nrow(args$x)) %% 2 == 1
ends <- args$x[odd,,drop=FALSE]
args$a <- args$x[!odd,,drop=FALSE] - ends
args$x <- ends
},
planes =,
clipplanes = {
args$a <- args$normals
args$x <- NULL
args$normals <- NULL
},
surface = {
dim <- x$dim
args$y <- matrix(args$x[,2], dim[1], dim[2])
args$z <- matrix(args$x[,3], dim[1], dim[2])
args$x <- matrix(args$x[,1], dim[1], dim[2])
if (!is.null(args$normals)) {
args$normal_x <- matrix(args$normals[,1], dim[1], dim[2])
args$normal_y <- matrix(args$normals[,2], dim[1], dim[2])
args$normal_z <- matrix(args$normals[,3], dim[1], dim[2])
args$normals <- NULL
}
if (!is.null(args$texcoords)) {
args$texture_s <- matrix(args$texcoords[,1], dim[1], dim[2])
args$texture_t <- matrix(args$texcoords[,2], dim[1], dim[2])
args$texcoords <- NULL
}
},
sprites = {
save2 <- par3d(skipRedraw = TRUE)
on.exit(par3d(save2), add=TRUE)
if (!is.null(x$objects)) {
ids <- numeric(length(x$objects))
for (i in seq_along(ids))
ids[i] <- plot3d(x$objects[[i]])
args$shapes <- ids
}
args$userMatrix <- x$usermatrix
})
mat <- x$material
if (is.null(mat)) mat <- list()
if (!is.null(col <- x$colors)) {
mat$color <- rgb(col[,1], col[,2], col[,3])
mat$alpha <- col[,4]
}
if (type == "light") {
if (!x$finite) {
args$x <- NULL
vx <- x$vertices[1]
vy <- x$vertices[2]
vz <- x$vertices[3]
args$phi <- atan2(vy, sqrt(vx^2 + vz^2))*180/pi
args$theta <- atan2(vx, vz)*180/pi
}
args$viewpoint.rel <- x$viewpoint
args$ambient <- mat$color[1]
args$diffuse <- mat$color[2]
args$specular <- mat$color[3]
} else
args <- c(args, mat)
do.call(fn, args)
}
plot3d.rglbboxdeco <- function(x, ...) {
args <- list()
v <- x$vertices
t <- x$texts
m <- x$axes$mode
if (m[1] == "none")
args$xat <- numeric()
else if (m[1] != "pretty") {
ind <- is.na(v[,2]) & is.na(v[,3])
if (any(ind)) {
args$xat <- v[ind,1]
if (!is.null(t))
args$xlab <- t[ind]
else
args$xlab <- signif(args$xat, 4)
}
}
if (m[2] == "none")
args$yat <- numeric()
else if (m[2] != "pretty") {
ind <- is.na(v[,1]) & is.na(v[,3])
if (any(ind)) {
args$yat <- v[ind,2]
if (!is.null(t))
args$ylab <- t[ind]
else
args$ylab <- signif(args$yat, 4)
}
}
if (m[3] == "none")
args$zat <- numeric()
else if (m[3] != "pretty") {
ind <- is.na(v[,1]) & is.na(v[,2])
if (any(ind)) {
args$zat <- v[ind,3]
if (!is.null(t))
args$zlab <- t[ind]
else
args$zlab <- signif(args$zat, 4)
}
}
args$draw_front <- x$draw_front
args <- c(args, x$material)
do.call("bbox3d", args)
}
plot3d.rglbackground <- function(x, ...) {
mat <- x$material
if (is.null(mat)) mat <- list()
if (!is.null(col <- x$colors)) {
mat$color <- rgb(col[,1], col[,2], col[,3])
mat$alpha <- col[,4]
}
args <- c(list(sphere = x$sphere, fogtype = x$fogtype), mat)
do.call("bg3d", args)
}
plot3d.rglWebGL <- function(x, ...) {
plot3d(attr(x, "origScene"), ...)
}
compare_proxy.rglscene <- function(x, path = "x") {
list(object = old_compare_proxy.rglscene(x),
path = paste0("compare_proxy(", path, ")"))
}
old_compare_proxy.rglscene <- function(x) {
doSubscene <- function(obj) {
if (!is.null(obj$par3d)) {
rect <- obj$par3d$windowRect
if (!is.null(rect)) {
rect <- rect - rect[1:2]
obj$par3d$windowRect <- rect
}
}
ids <<- c(ids, obj$id)
if (is.list(obj$subscenes))
obj$subscenes <- lapply(obj$subscenes, doSubscene)
}
ids <- c(x$rootSubscene$id,
sapply(x$objects, function(obj) obj$id))
x$rootSubscene <- doSubscene(x$rootSubscene)
ids <- unique(ids)
newids <- ids - min(ids) + 1
names(newids) <- ids
newid <- function(id) {
result <- if (is.null(id)) NULL
else unname(newids[as.character(id)])
if (any(is.na(result)))
stop("id gives NA")
result
}
newidc <- function(id) as.character(newid(id))
fixvec <- function(vec) {
if (is.list(vec))
lapply(vec, fixobj)
else
newid(vec)
}
fixobj <- function(obj) {
obj$id <- newid(obj$id)
obj$objects <- fixvec(obj$objects)
obj$ids <- fixvec(obj$ids)
if (!is.null(obj$par3d)) {
obj$par3d$listeners <- newid(obj$par3d$listeners)
obj$par3d$fontname <- NULL
obj$par3d$maxClipPlanes <- NULL
obj$par3d$glVersion <- NULL
}
if (!is.null(obj$material)) {
obj$material$texture <- NULL
}
obj$subscenes <- fixvec(obj$subscenes)
obj
}
x$rootSubscene <- fixobj(x$rootSubscene)
x$objects <- lapply(x$objects, fixobj)
names(x$objects) <- newidc(names(x$objects))
class(x) <- NULL
x
}
# Compare old and new scenes
all.equal.rglscene <- function(target, current, ...) {
if (inherits(current, "rglscene")) {
target <- compare_proxy.rglscene(target)
current <- compare_proxy.rglscene(current)
result <- all.equal(target,
current, ...)
if (!isTRUE(result) && isNamespaceLoaded("waldo"))
result <- waldo::compare(target, current)
result
} else
"'current' is not an rglscene object"
}
as.rglscene <- function(x, ...) {
UseMethod("as.rglscene")
}
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.