防止自动更新modelMatrix并在rgl中修改剔除平面
我试图使用par3d()在rgl中设置自定义userMatrix,但由于只读modelMatrix的重新计算,结果视图会出现不必要的副作用。(,第节:渲染) 此外,当靠近/远离视点时,近消隐平面和远消隐平面(我似乎也无法修改)过早地剪切对象 我的目标是以交互方式导航(Z轴向上)具有回归平面和曲面的点云,比以场景为中心的旋转和缩放更自由(我已经看到了使用rgl.setMouseCallbacks的平移示例) 重新绘制整个场景以移动它实际上不是一个选项,但对某些场景对象应用自定义变换可能是另一种方法,但更像是一种变通方法防止自动更新modelMatrix并在rgl中修改剔除平面,r,rgl,R,Rgl,我试图使用par3d()在rgl中设置自定义userMatrix,但由于只读modelMatrix的重新计算,结果视图会出现不必要的副作用。(,第节:渲染) 此外,当靠近/远离视点时,近消隐平面和远消隐平面(我似乎也无法修改)过早地剪切对象 我的目标是以交互方式导航(Z轴向上)具有回归平面和曲面的点云,比以场景为中心的旋转和缩放更自由(我已经看到了使用rgl.setMouseCallbacks的平移示例) 重新绘制整个场景以移动它实际上不是一个选项,但对某些场景对象应用自定义变换可能是另一种方法
提前感谢您的反馈 你的问题太模糊了。什么是“不必要的副作用”?但我会尝试: 在最简单的情况下,模型矩阵M被设置为U V,其中V由系统设置(如par3d中所述),U完全在您的控制之下。因此,如果您想要完全控制M,首先将U设置为标识并读取M以获得V,然后实现新的M',将U设置为M'V^-1
剪裁平面是投影矩阵的一个特征。你没有太多的控制权 因此,此示例代码在rgl中生成一个FPV或第三人称视图,包括一个hack(微调-550常量),以使视图更接近枢轴点(如果可以完全控制所有矩阵,则不需要这样做)。 远近剪裁/剔除仍然存在,但可以接受
library("rgl")
library("Morpho")
rglInit <- function()
{
rgl.open()
rgl.viewpoint(fov=110, type="userviewpoint")
defaultUserMatrix <<- par3d()$userMatrix
}
lookAt3d <-function(eye, center, up)
{
cat("*** lookat\n")
cat("eye\n")
print(eye)
cat("center\n")
print(center)
cat("up\n")
print(up)
fwd = center - eye
fwd = fwd / sqrt(sum(fwd^2))
upn = up / sqrt(sum(up^2))
side = crossProduct(fwd, up)
upnt = crossProduct(side, fwd)
M = rbind(c(side, 0), c(upnt, 0), c(-fwd, 0), c(0,0,0,1))
M = M %*% t(translationMatrix(-550 * fwd[1] - eye[1],
-550 * fwd[2] - eye[2],
-550 * fwd[3] - eye[3])) # -550 hack seems to put the view closer to the pivot point
cat("result\n")
print(M)
return (M)
}
yawPitchDirection3d <- function(yawAngle, pitchAngle)
{
c(
cos(pitchAngle) * cos(yawAngle),
cos(pitchAngle) * sin(yawAngle),
sin(pitchAngle))
}
lookAtYawPitch3d <- function(eye, yawAngle, pitchAngle)
{
fwd = yawPitchDirection3d(yawAngle, pitchAngle)
lookAt3d(eye, eye + fwd, c(0,0,1))
}
addTestScene <- function()
{
data(volcano)
z <- 2 * volcano # Exaggerate the relief
x <- 10 * (1:nrow(z)) # 10 meter spacing (S to N)
y <- 10 * (1:ncol(z)) # 10 meter spacing (E to W)
zlim <- range(z)
zlen <- zlim[2] - zlim[1] + 1
colorlut <- terrain.colors(zlen) # height color lookup table
col <- colorlut[ z-zlim[1]+1 ] # assign colors to heights for each point
rgl.surface(x, y, z, coords = c(1,3,2), color=col, back="lines")
axis3d('x', pos=c( NA, 0, 0 ), col = "red")
axis3d('y', pos=c( 0, NA, 0 ), col = "green")
axis3d('z', pos=c( 0, 0, NA ), col = "blue")
}
view = list()
resetView <- function()
{
view$yaw <<- 0.6
view$pitch <<- -1
view$eye <<- c(-360, -250,115)
setView()
}
setView <- function(yawDiff = 0.0, pitchDiff = 0.0, fwdDiff = 0.0, sideDiff = 0.0,
newView = NULL, delta = T)
{
view$yaw <<- view$yaw + yawDiff
view$pitch <<- view$pitch + pitchDiff
if (view$pitch > 0.99 * pi / 2)
{
view$pitch <<- 0.99 * pi / 2
}
if (view$pitch < -0.99 * pi / 2)
{
view$pitch <<- -0.99 * pi / 2
}
cat("*** Setview\n")
cat("Yaw\n")
print(view$yaw)
cat("Pitch\n")
print(view$pitch)
cat("Eye\n")
print(view$eye)
fwd = yawPitchDirection3d(view$yaw, view$pitch)
up = c(0,0,1)
upn = up / sqrt(sum(up^2))
side = crossProduct(fwd, up)
view$eye <<- view$eye + sideDiff * side + fwdDiff * fwd
userView = lookAtYawPitch3d(eye = view$eye,
yawAngle = view$yaw,
pitchAngle = view$pitch)
par3d(userMatrix = userView)
}
setMouseCallbacks <- function()
{
clickPrev <- list()
rgl.setMouseCallbacks(1,
begin = function(x, y)
{
clickPrev$x1 <<- x
clickPrev$y1 <<- y
},
update = function(x, y)
{
setView(yawDiff = -0.05 * (x - clickPrev$x1) / pi,
pitchDiff = -0.05 * (y - clickPrev$y1) / pi)
clickPrev$x1 <<- x
clickPrev$y1 <<- y
cat("*** Drag MB1\n")
cat("userMatrix\n")
print(par3d()$userMatrix)
cat("modelMatrix\n")
print(par3d()$modelMatrix)
cat("projMatrix\n")
print(par3d()$projMatrix)
}
)
rgl.setMouseCallbacks(2,
begin = function(x, y)
{
clickPrev$x2 <<- x
clickPrev$y2 <<- y
},
update = function(x, y)
{
setView(fwdDiff = -0.5 * (y - clickPrev$y2),
sideDiff = -0.5 * (x - clickPrev$x2))
clickPrev$x2 <<- x
clickPrev$y2 <<- y
cat("*** Drag MB2\n")
cat("userMatrix\n")
print(par3d()$userMatrix)
cat("modelMatrix\n")
print(par3d()$modelMatrix)
cat("projMatrix\n")
print(par3d()$projMatrix)
}
)
}
rglInit()
resetView()
addTestScene()
setMouseCallbacks()
库(“rgl”)
图书馆(“Morpho”)
你把这个贴到了rgl论坛上,得到了答案。是的,对不起。我的帖子一整天都没有得到管理员的验证,我注意到那里没有很多活动。我猜是不同的时区,不够耐心:/链接中所述的操作会导致场景被转换为零,并根据缩放重新计算透视图。我确实试图“欺骗”它,但它没有用,因为模型转换会立即重新计算。据我记忆所及,近平面和远平面肯定是OpenGL中的一个设置,可能不是由rgl公开的。不过,谢谢你的意见。如果我可以禁用模型矩阵的更新,那就好了。你一直在毫无根据地提出这个主张。禁用模型矩阵更新不会解决您看到的问题。如果您不同意,请尝试:rgl
是开源的,您可以更改任何您喜欢的内容。我不会说我的主张没有依据,但从所述信息来看可能不清楚。虽然很难找到时间,但我还是设法获得了一些第一/第三人称视图,并进行了一些调试打印,因此不会进一步调查。它包括一个修改,以抵消模型视图变换的影响,该变换似乎将最终生成的视图放置在对象/场景的后面,以确保无论缩放和fov等如何,它都能很好地适合视口。我认为这与我从文档中可以解释的有点一致。下面是示例代码。