Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/83.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
防止自动更新modelMatrix并在rgl中修改剔除平面_R_Rgl - Fatal编程技术网

防止自动更新modelMatrix并在rgl中修改剔除平面

防止自动更新modelMatrix并在rgl中修改剔除平面,r,rgl,R,Rgl,我试图使用par3d()在rgl中设置自定义userMatrix,但由于只读modelMatrix的重新计算,结果视图会出现不必要的副作用。(,第节:渲染) 此外,当靠近/远离视点时,近消隐平面和远消隐平面(我似乎也无法修改)过早地剪切对象 我的目标是以交互方式导航(Z轴向上)具有回归平面和曲面的点云,比以场景为中心的旋转和缩放更自由(我已经看到了使用rgl.setMouseCallbacks的平移示例) 重新绘制整个场景以移动它实际上不是一个选项,但对某些场景对象应用自定义变换可能是另一种方法

我试图使用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等如何,它都能很好地适合视口。我认为这与我从文档中可以解释的有点一致。下面是示例代码。