Nothing
# This displays an HTML5 input widget to show a subset of objects. It assigns a random id
# and returns that invisibly.
subsetSlider <- function(subsets, labels = names(subsets),
fullset = Reduce(union, subsets),
subscenes = currentSubscene3d(), prefixes = "",
accumulate = FALSE, ...) {
.Deprecated("subsetControl")
propertySlider(subsetSetter(subsets, fullset = fullset,
subscenes = subscenes, prefixes = prefixes,
accumulate = accumulate),
labels = labels, ...)
}
subsetSetter <- function(subsets, subscenes = currentSubscene3d(), prefixes = "",
fullset = Reduce(union, subsets),
accumulate = FALSE) {
.Deprecated("subsetControl")
nsubs <- max(length(subscenes), length(prefixes))
subscenes <- rep(subscenes, length.out = nsubs)
prefixes <- rep(prefixes, length.out = nsubs)
result <- subst(
'function(value) {
var i, ids = [%vals%],
fullset = [%fullset%], entries,
f = function(x) { return fullset.indexOf(x) < 0; };
value = Math.round(value);',
vals = paste(paste0("[", sapply(subsets,
function(i) paste(i, collapse=",")),
"]"), collapse=","),
fullset = paste(fullset, collapse=","))
for (i in seq_len(nsubs))
result <- c(result, subst(
' if (typeof %prefix%rgl.getObj === "undefined") return;
entries = %prefix%rgl.getObj(%subscene%).objects;
entries = entries.filter(f);', prefix = prefixes[i], subscene = subscenes[i]),
if (accumulate)
' for (i=0; i<=value; i++)
entries = entries.concat(ids[i]);'
else
' entries = entries.concat(ids[value]);',
subst('
%prefix%rgl.setSubsceneEntries(entries, %subscene%);',
prefix = prefixes[i], subscene = subscenes[i]))
result <- c(result, '}')
structure(paste(result, collapse = "\n"),
param = seq_along(subsets) - 1,
prefixes = prefixes, class = "propertySetter")
}
toggleButton <- function(subset, subscenes = currentSubscene3d(), prefixes = "",
label = deparse(substitute(subset)),
id = paste0(basename(tempfile("input"))), name = id) {
.Deprecated("toggleWidget")
nsubs <- max(length(subscenes), length(prefixes))
subscenes <- rep(subscenes, length.out = nsubs)
prefixes <- rep(prefixes, length.out = nsubs)
result <- subst(
'<button type="button" id="%id%" name="%name%" onclick = "(function() {
var subset = [%subset%], i;',
name, id, subset = paste(subset, collapse=","))
for (i in seq_len(nsubs))
result <- c(result, subst(
' if (%prefix%rgl.inSubscene(subset[0], %subscene%)) {
for (i=0; i<subset.length; i++)
%prefix%rgl.delFromSubscene(subset[i], %subscene%);
} else {
for (i=0; i<subset.length; i++)
%prefix%rgl.addToSubscene(subset[i], %subscene%);
}', prefix = prefixes[i], subscene = subscenes[i]))
prefixes <- unique(prefixes)
for (i in seq_along(prefixes))
result <- c(result, subst(
' %prefix%rgl.drawScene();', prefix = prefixes[i]))
result <- c(result, subst(
'})()">%label%</button>', label))
cat(result, sep = "\n")
invisible(id)
}
clipplaneSlider <- function(a=NULL, b=NULL, c=NULL, d=NULL,
plane = 1, clipplaneids, prefixes = "",
labels = signif(values[,1],3),
...) {
.Deprecated("clipplaneControl")
values <- cbind(a = a, b = b, c = c, d = d)
col <- which(colnames(values) == letters[1:4]) - 1
propertySlider(values = values, entries = 4*(plane-1) + col,
properties = "vClipplane", objids = clipplaneids,
prefixes = prefixes, labels = labels, ...)
}
propertySlider <- function(setter = propertySetter,
minS = NULL, maxS = NULL, step = 1, init = NULL,
labels,
id = basename(tempfile("input")), name = id,
outputid = paste0(id, "text"),
index = NULL,
...) {
.Deprecated("propertyControl")
displayVals <- function(x) {
base <- signif(mean(x), 2)
base + signif(x - base, 2)
}
if (!is.list(setter)) setters <- list(setter)
else setters <- setter
param <- numeric()
prefixes <- character()
for (i in seq_along(setters)) {
setter <- setters[[i]]
if (is.function(setter))
setters[i] <- setter <- setter(...)
if (!inherits(setter, "propertySetter"))
stop("'setter' must be a propertySetter object")
param <- c(param, attr(setter, "param"))
prefixes <- c(prefixes, attr(setter, "prefixes"))
}
prefix <- prefixes[1]
if (is.null(minS)) minS <- min(param)
if (is.null(maxS)) maxS <- max(param)
if (is.null(init)) init <- minS
sliderVals <- seq(minS, maxS, by = step)
if (missing(labels)) labels <- displayVals(sliderVals)
if (is.null(outputid) || is.null(labels)) outputfield <- setoutput <- ""
else {
outputfield <- subst('<output id="%outputid%" for="%id%">%label%</output>',
outputid, id, label = labels[round(init-minS)/step + 1])
setoutput <- subst('
label = document.getElementById(\'%outputid%\');
if (label !== null) label.value = labels[lvalue];', outputid)
}
# We don't want to respond to a change in the middle of a
# previous response, but we don't want to lose it either.
result <- subst(
'<script>%prefix%rgl.%id% = function(value) {
if (typeof %prefix%rgl.drawScene === "undefined")
return;
var busy = (typeof %prefix%rgl.%id%.busy !== "undefined"),
lvalue, labels;
try {
%prefix%rgl.%id%.busy = value;
if (busy) return;
do {', prefix, id)
for (i in seq_along(setters)) {
setter <- setters[[i]]
if (inherits(setter, "indexedSetter")) {
if (is.null(index)) stop("indexed setter requires an index")
settername <- attr(setter, "name")
}
result <- c(result,
if (!inherits(setter, "indexedSetter")) subst(
' (%setter%)(value);', setter)
else subst(
' %settername%(value, %index%);', settername, index=index-1))
}
for (p in unique(prefixes))
result <- c(result, subst(
' %prefix%rgl.drawScene();', prefix = p))
result <- c(result, subst(
' lvalue = Math.round((value - %minS%)/%step%);
labels = [%labels%]; %setoutput%
} while (%prefix%rgl.%id%.busy !== value);
}
finally {
if (!busy)
%prefix%rgl.%id%.busy = undefined;
}
};
%prefix%rgl.%id%(%init%);</script>
<input type="range" min="%minS%" max="%maxS%" step="%step%" value="%init%" id="%id%" name="%name%"
oninput = "%prefix%rgl.%id%(this.valueAsNumber)">%outputfield%',
prefix, id, setoutput, outputfield,
minS, maxS, step, init, name,
labels = paste0("'", labels, "'", collapse=",")))
cat(result, sep="\n")
invisible(id)
}
propertySetter <- function(values = NULL, entries, properties, objids, prefixes = "",
param = seq_len(NROW(values)), interp = TRUE,
digits = 7) {
.Deprecated("propertyControl")
direct <- is.null(values)
ncol <- length(entries)
if (direct)
interp <- FALSE
else {
values <- matrix(values, NROW(values))
stopifnot(ncol(values) == ncol,
all(diff(param) > 0))
}
prefixes <- rep(prefixes, length.out = ncol)
if (!ncol) return(structure("function(value) {}", param = param,
prefixes = prefixes,
class = "propertySetter"))
properties <- rep(properties, length.out = ncol)
objids <- rep(objids, length.out = ncol)
prefix <- prefixes[1]
property <- properties[1]
objid <- objids[1]
if (interp) values <- rbind(values[1,], values, values[nrow(values),])
get <- if (grepl("^par3d\\.userMatrix", property)) ".getAsArray()" else ""
load <- if (grepl("^par3d\\.userMatrix", property)) ".load(propvals)" else "= propvals"
result <- c(
'function(value) {',
if (!direct) subst(
' var values = [%vals%],',
vals = paste(formatC(as.vector(t(values)), digits = digits, width = 1),
collapse = ",")),
subst(
' propvals = %prefix%rgl.getObj(%objid%).%property%%get%;',
prefix, property, objid, get),
if (interp) subst(
' var svals = [-Infinity, %svals%, Infinity],
v1, v2;
for (var i = 1; i < svals.length; i++)
if (value <= svals[i]) {
var p = (svals[i] - value)/(svals[i] - svals[i-1]);',
svals = paste(formatC(param, digits = digits, width = 1), collapse = ","))
else if (!direct)
' value = Math.round(value);')
for (j in seq_along(entries)) {
newprefix <- prefixes[j]
newprop <- properties[j]
newget <- if (grepl("^par3d\\.userMatrix", newprop)) ".getAsArray()" else ""
newload <- if (grepl("^par3d\\.userMatrix", newprop)) ".load(propvals)" else " = propvals"
newid <- objids[j]
multiplier <- ifelse(ncol>1, paste0(ncol, "*"), "")
offset <- ifelse(j>1, paste0("+", j-1), "")
result <- c(result,
if (newprefix != prefix || newprop != property || newid != objid) subst(
' %prefix%rgl.getObj(%objid%).%property%%load%;
propvals = %newprefix%rgl.getObj(%objid%).%newprop%%newget%;',
prefix, property, objid, load, newget, newprefix, newprop, newid),
if (interp) subst(
' v1 = values[%multiplier%(i-1)%offset%];
v2 = values[%multiplier%i%offset%];
propvals[%entry%] = p*v1 + (1-p)*v2;', entry=entries[j], multiplier, offset)
else if (!direct) subst(
' propvals[%entry%] = values[%multiplier%value%offset%];',
entry = entries[j], multiplier, offset)
else if (ncol == 1) subst(
' propvals[%entry%] = value;',
entry = entries[j], jm1 = j - 1)
else subst(
' propvals[%entry%] = value[%jm1%];',
entry = entries[j], jm1 = j - 1))
prefix <- newprefix
property <- newprop
objid <- newid
get <- newget
load <- newload
}
result <- c(result,
if (interp)
' break;
}',
subst(
' %prefix%rgl.getObj(%objid%).%property%%load%;',
prefix, property, objid, load))
needsBinding <- unique(data.frame(prefixes, objids)[properties == "values",])
if (nrow(needsBinding))
result <- c(result,
' var gl;')
for (i in seq_len(nrow(needsBinding))) {
prefix <- needsBinding[i, 1]
objid <- needsBinding[i, 2]
result <- c(result, subst(
' if (typeof %prefix%rgl.getObj(%objid%).buf !== "undefined") {
gl = %prefix%rgl.gl;
gl.bindBuffer(gl.ARRAY_BUFFER, %prefix%rgl.getObj(%objid%).buf);
gl.bufferData(gl.ARRAY_BUFFER, %prefix%rgl.getObj(%objid%).values, gl.STATIC_DRAW);
}', prefix, objid))
}
result <- c(result, '}')
result <- structure(paste(result, collapse = "\n"),
prefixes = prefixes,
class = "propertySetter")
if (!direct)
attr(result, "param") <- param
result
}
vertexSetter <- function(values = NULL, vertices = 1, attributes, objid, prefix = "",
param = seq_len(NROW(values)), interp = TRUE,
digits = 7) {
.Deprecated("vertexControl")
attribofs <- c(x = 'vofs', y = 'vofs', z = 'vofs',
r = 'cofs', g = 'cofs', b = 'cofs', a = 'cofs',
nx = 'nofs', ny = 'nofs', nz = 'nofs',
radius = 'radofs',
ox = 'oofs', oy = 'oofs', oz = 'oofs',
ts = 'tofs', tt = 'tofs')
attribofsofs <- structure(c(0:2, 0:3, 0:2, 0, 0:2, 0:1),
names = names(attribofs))
direct <- is.null(values)
ncol <- max(if (is.matrix(values)) ncol(values),
length(vertices), length(attributes))
if (direct)
interp <- FALSE
else {
values <- matrix(values, NROW(values))
stopifnot(ncol(values) == ncol,
all(diff(param) > 0))
}
attributes <- match.arg(attributes, names(attribofs), several.ok = TRUE)
stopifnot(length(objid) == 1,
length(prefix) == 1,
all(attributes %in% names(attribofs)),
all(diff(param) > 0))
vertices <- rep(vertices, length.out = ncol)
attributes <- rep(attributes, length.out = ncol)
if (!ncol) return(structure("function(value) {}", param = param,
prefixes = prefix,
class = c("vertexSetter", "propertySetter")))
if (interp) values <- rbind(values[1,], values, values[nrow(values),])
result <- c(
'function(value) {',
if (direct)
' var ofs;'
else subst(
' var ofs, values = [%vals%],',
vals = paste(formatC(as.vector(t(values)), digits = digits, width = 1),
collapse = ",")),
subst(
' propvals = %prefix%rgl.getObj(%objid%).values,
stride = %prefix%rgl.getObj(%objid%).vOffsets.stride;',
prefix, objid),
if (interp) subst(
' var p, v1, v2, svals = [-Infinity, %svals%, Infinity];
for (var i = 1; i < svals.length; i++)
if (value <= svals[i]) {
p = (svals[i] - value)/(svals[i] - svals[i-1]);', svals = paste(formatC(param, digits = digits, width = 1), collapse = ","))
else if (!direct)
' value = Math.round(value);')
for (j in seq_along(vertices)) {
multiplier <- ifelse(ncol>1, paste0(ncol, "*"), "")
offset <- ifelse(j>1, paste0("+", j-1), "")
entry <- ifelse(vertices[j] == 1, 'ofs',
subst('%vertexm1%*stride + ofs',
vertexm1 = vertices[j]-1))
result <- c(result,
subst(
' ofs = %prefix%rgl.getObj(%objid%).vOffsets.%attribofs%;
if (ofs < 0)
alert("Attribute %attribute% not found in object %objid%");',
prefix, objid, attribofs = attribofs[attributes[j]],
attribute = attributes[j]),
if (attribofsofs[attributes[j]] > 0)
subst(
' ofs = ofs + %attribofsofs%;', attribofsofs = attribofsofs[attributes[j]]),
if (interp) subst(
' v1 = values[%multiplier%(i-1)%offset%];
v2 = values[%multiplier%i%offset%];
propvals[%entry%] = p*v1 + (1-p)*v2;',
entry, multiplier, offset)
else if (!direct) subst(
' propvals[%entry%] = values[%multiplier%value%offset%];',
entry, multiplier, offset)
else if (ncol == 1) subst(
' propvals[%entry%] = value;',
entry)
else subst(
' propvals[%entry%] = value[%jm1%];',
entry, jm1 = j - 1))
}
result <- c(result,
if (interp)
' break;
}',
subst(
' %prefix%rgl.getObj(%objid%).values = propvals;
if (typeof %prefix%rgl.getObj(%objid%).buf !== "undefined") {
var gl = %prefix%rgl.gl;
gl.bindBuffer(gl.ARRAY_BUFFER, %prefix%rgl.getObj(%objid%).buf);
gl.bufferData(gl.ARRAY_BUFFER, %prefix%rgl.getObj(%objid%).values, gl.STATIC_DRAW);
}', prefix, objid))
result <- c(result, '}')
structure(paste(result, collapse = "\n"),
param = param, prefixes = prefix,
class = c("vertexSetter", "propertySetter"))
}
par3dinterpSetter <- function(fn, from, to, steps, subscene = NULL,
omitConstant = TRUE, rename = character(), ...) {
.Deprecated("par3dinterpControl")
times <- seq(from, to, length.out = steps+1)
fvals <- lapply(times, fn)
f0 <- fvals[[1]]
entries <- numeric(0)
properties <- character(0)
values <- NULL
props <- c("FOV", "userMatrix", "scale", "zoom")
for(i in seq_along(props)) {
prop <- props[i]
propname <- rename[prop]
if (is.na(propname))
propname <- prop
if (!is.null(value <- f0[[prop]])) {
newvals <- sapply(fvals, function(e) as.numeric(e[[prop]]))
if (is.matrix(newvals)) newvals <- t(newvals)
rows <- NROW(newvals)
cols <- NCOL(newvals)
stopifnot(rows == length(fvals))
entries <- c(entries, seq_len(cols)-1)
properties <- c(properties, rep(propname, cols))
values <- cbind(values, newvals)
}
}
if (omitConstant) keep <- apply(values, 2, var) > 0
else keep <- TRUE
if (is.null(subscene)) subscene <- f0$subscene
propertySetter(values = values[,keep], entries = entries[keep],
properties = paste0("par3d.", properties[keep]),
objids = subscene, param = times, ...)
}
matrixSetter <- function(fns, from, to, steps, subscene = currentSubscene3d(), matrix = "userMatrix",
omitConstant = TRUE, prefix = "", ...) {
.Deprecated("par3dinterpControl")
n <- length(fns)
from <- rep(from, length.out = n)
to <- rep(to, length.out = n)
steps <- rep(steps, length.out = n)
settername <- basename(tempfile("fn", ""))
propname <- paste0("userMatrix", settername) # Needs to match "^userMatrix" regexp
param <- numeric()
result <- subst(
'%prefix%rgl.%settername% = function(value, index) {
var fns = new Array();', prefix, settername)
for (i in seq_len(n)) {
setter <- par3dinterpSetter(fns[[i]], from[i], to[i], steps[i],
omitConstant = TRUE, subscene = i-1, prefixes = prefix,
rename = c(userMatrix = propname), ...)
result <- c(result, subst(
' fns[%i%] = ', i=i-1), setter)
param <- c(param, attr(setter, "param"))
}
result <- c(result,
' fns[index](value);
var newmatrix = new CanvasMatrix4();',
paste0(subst(
' newmatrix.multLeft(%prefix%rgl.%propname%[', prefix, propname), 0:(n-1), ']);'),
subst(
' %prefix%rgl.%matrix%[%subscene%].load(newmatrix);
}
%prefix%rgl.%propname% = new Array();', prefix, subscene, propname, matrix),
paste0(subst(
' %prefix%rgl.%propname%[', prefix, propname), 0:(n-1), '] = new CanvasMatrix4();'))
structure(paste(result, collapse="\n"),
param = sort(unique(param)),
prefixes = prefix,
name = subst('%prefix%rgl.%settername%', prefix, settername),
class = c("matrixSetter", "indexedSetter", "propertySetter"))
}
print.indexedSetter <- function(x, inScript = FALSE, ...) {
if (!inScript) cat("<script>\n")
cat(x)
if (!inScript) cat("\n</script>")
}
ageSetter <- function(births, ages, colors = NULL, alpha = NULL,
radii = NULL, vertices = NULL, normals = NULL,
origins = NULL, texcoords = NULL, objids, prefixes = "",
digits = 7, param = seq(floor(min(births)), ceiling(max(births)))) {
.Deprecated("ageControl")
formatVec <- function(vec) {
vec <- t(vec)
result <- formatC(vec, digits = digits, width = 1)
result[vec == Inf] <- "Infinity"
result[vec == -Inf] <- "-Infinity"
paste(result, collapse = ",")
}
if (!is.null(colors)) colors <- t(col2rgb(colors))/255
lengths <- c(colors = NROW(colors), alpha = length(alpha),
radii = length(radii), vertices = NROW(vertices),
normals = NROW(normals), origins = NROW(origins),
texcoords = NROW(texcoords))
lengths <- lengths[lengths > 0]
attribs <- names(lengths)
n <- unique(lengths)
stopifnot(length(n) == 1, n == length(ages), all(diff(ages) >= 0))
nobjs <- max(length(objids), length(prefixes))
prefixes <- rep(prefixes, length.out = nobjs)
objids <- rep(objids, length.out = nobjs)
result <- subst(
' function(time) {
var ages = [-Infinity, %ages%, Infinity],
births = [%births%],
j = new Array(births.length),
p = new Array(births.length),
i, age, j0, propvals, stride, ofs;',
ages = formatVec(ages), births = formatVec(births))
rows <- c(1,1:n, n)
if ("colors" %in% attribs)
result <- c(result, subst(
' var colors = [%values%];', values = formatVec(colors[rows,])))
if ("alpha" %in% attribs)
result <- c(result, subst(
' var alpha = [%values%];', values = formatVec(alpha[rows])))
if ("radii" %in% attribs)
result <- c(result, subst(
' var radii = [%values%];', values = formatVec(radii[rows])))
if ("vertices" %in% attribs) {
stopifnot(ncol(vertices) == 3)
result <- c(result, subst(
' var vertices = [%values%];', values = formatVec(vertices[rows,])))
}
if ("normals" %in% attribs) {
stopifnot(ncol(normals) == 3)
result <- c(result, subst(
' var normals = [%values%];', values = formatVec(normals[rows,])))
}
if ("origins" %in% attribs) {
stopifnot(ncol(origins) == 2)
result <- c(result, subst(
' var origins = [%values%];', values = formatVec(origins[rows,])))
}
if ("texcoords" %in% attribs) {
stopifnot(ncol(texcoords) == 2)
result <- c(result, subst(
' var texcoords = [%values%];', values = formatVec(texcoords[rows,])))
}
result <- c(result,
' for (i = 0; i < births.length; i++) {
age = time - births[i];
for (j0 = 1; age > ages[j0]; j0++);
if (ages[j0] == Infinity)
p[i] = 1;
else if (ages[j0] > ages[j0-1])
p[i] = (ages[j0] - age)/(ages[j0] - ages[j0-1]);
else
p[i] = 0;
j[i] = j0;
}')
for (j in seq_len(nobjs)) {
prefix <- prefixes[j]
objid <- objids[j]
result <- c(result, subst(
' propvals = %prefix%rgl.getObj(%objid%).values;
stride = %prefix%rgl.getObj(%objid%).vOffsets.stride;',
prefix, objid))
for (a in attribs) {
ofs <- c(colors = "cofs", alpha = "cofs", radii = "radofs",
vertices = "vofs", normals = "nofs", origins = "oofs",
texcoords = "tofs")[a]
result <- c(result, subst(
' ofs = %prefix%rgl.getObj(%objid%).vOffsets.%ofs%;
if (ofs >= 0) {
for (i = 0; i < births.length; i++) {',
prefix, objid, ofs))
dim <- c(colors = 3, alpha = 1, radii = 1,
vertices = 3, normals = 3, origins = 2,
texcoords = 2)[a]
if (dim > 1)
for (d in seq_len(dim) - 1)
result <- c(result, subst(
' propvals[i*stride + ofs + %d1%] = p[i]*%a%[%dim%*(j[i]-1) + %d2%] + (1-p[i])*%a%[%dim%*j[i] + %d2%];',
dim, d1 = if (a == "alpha") 3 else d, d2 = d, a))
else
result <- c(result, subst(
' propvals[i*stride + ofs%alphaofs%] = p[i]*%a%[j[i]-1] + (1-p[i])*%a%[j[i]];',
a, alphaofs = if (a == "alpha") " + 3" else ""))
result <- c(result, subst(
' }
} else
alert("\'%a%\' property not found in object %objid%");', a, objid))
}
result <- c(result, subst(
' %prefix%rgl.getObj(%objid%).values = propvals;
if (typeof %prefix%rgl.getObj(%objid%).buf !== "undefined") {
var gl = %prefix%rgl.gl;
gl.bindBuffer(gl.ARRAY_BUFFER, %prefix%rgl.getObj(%objid%).buf);
gl.bufferData(gl.ARRAY_BUFFER, %prefix%rgl.getObj(%objid%).values, gl.STATIC_DRAW);
}',
prefix, objid))
}
result <- c(result, ' }')
structure(paste(result, collapse = "\n"),
param = param, prefixes = prefixes,
class = c("ageSetter", "propertySetter"))
}
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.