使用R:如何在单个rgl画布中为多个3D对象制作动画?

时间:2017-10-28 10:53:04

标签: r animation 3d mesh rgl

我有数据,参与者每只手都有位置数据:

左: 右:

位置数据

pos.x
pos.y
pos.z

在某个时间t

最初的问题是关于导入OBJ以使用RGL:https://stackoverflow.com/posts/46626767/revisions

我认为那部分了。我编写了一些函数来改进开源OBJ文件的{​​{1}}网格框架。

我在线放置了所需的功能:https://gist.github.com/MonteShaffer/d142210cddf346c86aeab1ea2d1d7e9d

应该在手表上捕获位置数据,因此我希望能够显示两个或更多3D数据对象,并根据位置/时间数据独立制作动画。

也就是说,在手表区域适当移动的情况下,将手像刚性物体一样对待。

我将hand.OBJ文件放在网上:https://gist.github.com/MonteShaffer/6c0057b1431364caf120220db77dde4b

我知道基本的图形,更新,旋转:

rgl

我的目标是在同一个rgl画布上绘制多个对象。

例如,

library(rgl)

mymesh = buildBasicMeshFromOBJ(parseFileOBJ("hand.OBJ"));

open3d()
shade3d(mymesh, col = "pink")
par3d(userMatrix = rotate3d(par3d("userMatrix"), 0.1, 1,0,0))
play3d(spin3d(axis = c(1, 0, 0)))

并根据每个元素的位置/时间数据,使每个元素作为动画随时间移动。现在头部保持不动,但每只手都根据刚性的想法移动,位置代表手腕。

在动画进行过程中,鼠标拖动仍然可以发生(在手和头部周围改变3D视图),这将是一个额外的好处。

1 个答案:

答案 0 :(得分:0)

您可以使用rotate3d之类的功能在场景中移动对象。尽管它的名字,它允许相当普遍的运动:请参阅帮助页面。

因此,不要使用par3d移动东西,而是移动对象本身。

rgl没有提供修改场景中已有对象的方法(虽然rgl对象的WebGL显示确实...),所以基本思路如下:

  • 绘制对象,并保存ID(例如ids <- shade3d(mymesh)
  • 然后,循环:
    • 关闭更新(使用par3d(skipRedraw=TRUE)
    • 删除对象(例如rgl.pop(id=ids)
    • 移动并重新绘制对象
    • 启用更新。

play3d功能提供了一个自动化框架,但您不需要使用它。例如,这将绘制两个二十面体并随机旋转它们:

orig1 <- icosahedron3d()
id1 <- shade3d(orig1, col = "green")
orig2 <- translate3d(orig1, 4, 0, 0)
id2 <- shade3d(orig2, col = "blue")

repeat {
  orig1 <- rotate3d(orig1, 0.01, rnorm(1, 1), rnorm(1), rnorm(1))
  orig2 <- rotate3d(orig2, 0.05, rnorm(1, -1), rnorm(1), rnorm(1))
  par3d(skipRedraw = TRUE)
  rgl.pop(id = c(id1, id2))
  id1 <- shade3d(orig1, col = "green")
  id2 <- shade3d(orig2, col = "blue")
  par3d(skipRedraw = FALSE)
}

另一种方法是设置两个单独的子场景。然后每个 可以通过自己的par3d()设置进​​行控制。例如,

icos <- icosahedron3d()
ids <- mfrow3d(1,2)
shade3d(icos, col = "red")
next3d()
shade3d(icos, col = "green")

现在每个icosahedra都可以用鼠标独立操作。如果您想使用par3d执行此操作,请使用par3d(..., subscene = ids[1])之类的内容影响左侧窗格,par3d(..., subscene = ids[2])使用右侧窗格。