过去一周,我一直在努力实现类似游戏Antichamber(更准确地说是下面显示的这个技巧):
这是我希望实现的视频(尽管它是使用虚幻引擎4完成的;我没有使用它):https://www.youtube.com/watch?v = Off3JcoWrMZs
我查找了最好的方法,我发现了模板缓冲区.在这篇文章和这个代码("drawPortals()"函数)之间,我在网上找到了我几乎实现它.
它可以很好地与一个门户到另一个房间(不是一个可交叉的门户,这意味着你无法穿过它并被传送到另一个房间).在我的例子中,我正在绘制一个门户到一个简单的方形房间,里面有一个球体; 在门户网站后面还有另一个球体,我用来检查深度缓冲区是否正常工作并将其绘制在门户网站后面:
当我添加另一个接近此门户的门户时,会出现问题.在这种情况下,我设法正确显示另一个门户(灯光关闭,但右侧的球体颜色不同,表明它是另一个球体):
但是如果我转动相机以便第一个门户必须被绘制在第二个门户上,那么第一个门户的深度就会出错,而第二个门户将被绘制在第一个门户上,如下所示:
虽然应该是这样的:
所以,这就是问题所在.我可能在深度缓冲区做错了,但我找不到什么.
我的渲染部分的代码就是这样的:
glClear(GL_DEPTH_BUFFER_BIT);
glEnable(GL_STENCIL_TEST);
// First portal
glPushMatrix();
// Disable writing to the color and depht buffer; disable depth testing
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
glDepthMask(GL_FALSE);
glDisable(GL_DEPTH_TEST);
// Make sure that the stencil always fails
glStencilFunc(GL_NEVER, 1, 0xFF);
// On fail, put 1 on the buffer
glStencilOp(GL_REPLACE, GL_KEEP, GL_KEEP);
// Enable writing to the stencil buffer
glStencilMask(0xFF);
// Clean the …Run Code Online (Sandbox Code Playgroud) 这个问题的标题可能有点含糊,但我不知道如何用一句话来表达。
基本上我遇到了这种情况:场景中有一个透视相机和一个网格。网格不以轴的原点为中心。
相机直接指向这个对象的中心,它的位置(我的意思是 Three.js 相机对象的“位置”属性)是相对于对象中心的位置,而不是原点;所以它在另一个坐标系中工作。
我的问题是:如何获得相机的位置,而不是相对于对象中心,而是相对于“全局”坐标系的原点?
澄清一下,情况是这样的。在此图像中,您可以看到位置远离坐标系原点的手部网格。相机直接指向手的中心(所以从相机的角度来看的原点是手的中心),如果我打印它的位置,它会给我这些值:x:-53.46980763626004;y:-2.7201492246619283;z:-9.814480359970839 而实际上我想要相对于坐标系原点的位置(因此在这种情况下,值会不同;例如,y 值将为正)。
更新: 我尝试了@leota 的建议,所以我以这种方式使用了 localToWorld 方法:
var camera = scene.getCamera();
var viewPos = camera.position;
var newView = new THREE.Vector3();
newView.copy(viewPos);
camera.localToWorld(newView);
Run Code Online (Sandbox Code Playgroud)
我用这个网格做了一个实验。正如你所看到的,这个网格也没有以原点为中心(你可以看到左下角的轴)。如果我打印相机位置的正常值(因此,相对于网格的中心),它会给我以下结果:x: 0; y:0;z: 15
如果现在我在上面的代码之后打印结果值,结果是:x: 0; y:0;z: 30
这是错误的,因为您可以看到图像中的相机位置的 x 和 y 值明显不同于 0(而 z = 30 可能是真的,据我所知)。
例如,如果我旋转相机,使其非常靠近原点,就像这样(在图像中相机就在原点后面,因此它在世界坐标中的位置应该为 x、y、z 的负值),坐标关于物体的中心是:
x:-4.674180744175711;y:-4.8370441591630255;z:-4.877951155147168
而在上面的代码之后,它们变成了:
x:3.6176076166961373;y:-4.98753160894295;z:-4.365141278155379
y 和 z 值甚至可能一目了然,但 x 的正值告诉我这是完全错误的,我不知道为什么。
我将继续寻找解决方案,但这可能是朝着正确方向迈出的一步。不过,任何更多的建议表示赞赏!
更新 2:
找到了解决办法。@leota 说的是正确的,这确实是您获得相机绝对坐标的方式。不过,就我而言,我终于发现项目代码中隐藏了一行代码,该代码根据某些规则(与项目相关)缩放所有内容。因此,我的解决方案是按原样获取相机位置,然后根据该规则将其缩小。
由于@leota 的答案确实是原始问题的解决方案,因此我接受它作为正确的答案
我想从给定大小的无序元素列表中构建B +树N.
我知道这样做的最佳界限是?(N / B * logM / B(N / B))块传输,这也是排序的最佳选择; 所以我不能简单地选择一个项目并单独在树中插入,因为它会给我O(N logB(N))块传输.
所以我认为构建树的最佳方法是首先对元素进行排序,因为无论如何都要对树进行排序.从那以后,我很茫然.
我想过这样的事情:
B-1父母中有路由键时,表示它已满.所以新的路由密钥将改为"祖父"(因此树增长一级),所有新的叶子将有一个新的父级N/B读取块 基本上,问题在于我没有考虑内部节点可以拥有的最小子节点数.因此,例如,一个节点最终只有一个子节点,这显然是错误的.
我到处寻找,但我找不到实际解释如何构建树的算法?(N / B * logM / B(N / B)).我找到的只是在列表中为每个项目简单插入树的算法,而没有利用B因子.
你能帮助我吗,也许能指出我正确的方向?
基本上我的情况是这样的:
我有一个扩展QQuickView的类,它通过设置上下文属性将某些对象从C++暴露给QML.显示的视图是从QML创建的,并且是同一个自定义组件的所有不同的结构; 当某些事件发生时会创建新视图,当发生这种情况时,现有视图应显示最初在C++端分配给它们的对象,而新视图应显示分配给它们的内容.
所以,在C++方面,我有这样的事情:
WindowManager::WindowManager(QQuickView *parent) :
QQuickView(parent)
{
// Setting the source file to use
this->setSource(QUrl("qrc:/qml/main.qml"));
// Exposing the istance of this class to QML for later use
this->rootContext()->setContextProperty("qquickView", this);
// Calling the method that will create dynamically a new view that will be child of main.qml; the parameter is not important, just a random number to start with
this->prepareNewView(3)
this->showFullScreen();
}
WindowManager::prepareNewView(int stuffId)
{
MyDatabase db;
// Getting something to show in QML from somewhere based on the …Run Code Online (Sandbox Code Playgroud) 我刚刚开始使用Android Studio,我想向我的项目添加一个开源库。我在Internet上浏览了很多东西,但是找不到找到使我的项目编译并使该库的类可见的方法。
这是我要包含的库:https : //github.com/TangoAgency/material-intro-screen?utm_source=android-arsenal.com&utm_medium=referral&utm_campaign=4368
在自述文件中,它首先说是添加gradle依赖项:
dependencies {
compile 'agency.tango.android:material-intro-screen:{latest_release}'
}
Run Code Online (Sandbox Code Playgroud)
但是在我看来,在那之前还有更多事情要做……只是我不知道该做什么。