我将bullet移植到kotlin并编写了运行HelloWorld示例所需的所有内容。
我现在处于调试阶段,我遇到了对象引用问题。
一开始,我第一次输入collideTTpersistentStack
:
fun collideTTpersistentStack(root0: DbvtNode?, root1: DbvtNode?, collider: DbvtTreeCollider) {
if (root0 != null && root1 != null) {
var depth = 1
var treshold = DOUBLE_STACKSIZE - 4
val element = StkNN(root0, root1)
if (stkStack.isNotEmpty()) stkStack[0] = element
else stkStack += element
stkStack resize DOUBLE_STACKSIZE
do {
val p = stkStack[--depth]
if (depth > treshold) {
stkStack resize (stkStack.size * 2)
treshold = stkStack.size - 4
}
val pa = p.a!!
val pb = p.b!!
if (pa === pb) {
if (pa.isInternal) {
stkStack[depth++] = StkNN(pa.childs[0], pa.childs[0])
stkStack[depth++] = StkNN(pa.childs[1], pa.childs[1])
stkStack[depth++] = StkNN(pa.childs[0], pa.childs[1])
}
} else if (pa.volume intersect pb.volume)
if (pa.isInternal)
if (pb.isInternal) {
stkStack[depth++] = StkNN(pa.childs[0], pb.childs[0])
stkStack[depth++] = StkNN(pa.childs[1], pb.childs[0])
stkStack[depth++] = StkNN(pa.childs[0], pb.childs[1])
stkStack[depth++] = StkNN(pa.childs[1], pb.childs[1])
} else {
stkStack[depth++] = StkNN(pa.childs[0], pb)
stkStack[depth++] = StkNN(pa.childs[1], pb)
}
else
if (pb.isInternal) {
stkStack[depth++] = StkNN(pa, pb.childs[0])
stkStack[depth++] = StkNN(pa, pb.childs[1])
} else
collider.process(pa, pb)
} while (depth != 0)
}
}
但由于root0
是null
,我立即退出。下次我输入函数时,root0
和root1
都是有效对象,其引用如下:
root0 = Dbvt@708
root1 = Dbvt@656
然后我创建了第一个要添加到stkStack
的元素,它仍然是空的,定义为:
val stkStack = ArrayList<StkNN>()
element
是如此定义的StkNN
类:
class StkNN(var a: DbvtNode? = null, var b: DbvtNode? = null)
插入后,我得到:
这是有道理的。
stkStack resize DOUBLE_STACKSIZE
只需创建一些虚拟StkNN实例
然后我输入do
并抓住stkStack
上的第一个元素,它基本上就是我们刚插入的元素:
p = {Dbvt$StkNN@731}
a = {DbvtNode@708}
b = {DbvtNode@656}
然后我们跳过下一个if
,我将变量p.a
和p.b
保存为对可空性的不可变检查
val pa = p.a!!
val pb = p.b!!
pa
和pb
在引用方面都是一致的:
pa = @708
pb = @656
现在我们直接降落here:
} else {
stkStack[depth++] = StkNN(pa.childs[0], pb)
stkStack[depth++] = StkNN(pa.childs[1], pb)
}
depth
现在是0
而stkStack
包含一个元素,即我们在开头插入的元素,因此它应该用新实例替换它
嗯,pa
孩子是以下
pa = {DbvtNode@708}
childs = {DbvtNode[2]@748}
0 = {DbvtNode@759}
1 = {DbvtNode@656}
但在跳过作业后,stkStack
将包含以下内容:
stkStack = {ArrayList@709} size = 128
0 = {Dbvt$StkNN@772}
a = {DbvtNode@708} // this is wrong, it should be @759
b = {DbvtNode@656}
1 = {Dbvt$StkNN@781}
a = {DbvtNode@656} // right
b = {DbvtNode@656} // right
C ++代码使用指针,我仔细检查执行,它的stkStack[0].a
指针实际上是应该的,也就是说,它对应于p.a->childs[0]
指针
发生了什么事?
编辑:如果我在添加实例之前创建虚拟对象:
val test = StkNN(pa.childs[0], pb)
stkStack[depth++] = StkNN(pa.childs[0], pb)
stkStack[depth++] = StkNN(pa.childs[1], pb)
它确实有正确的引用,test.a
实际上是pa.childs[0]
。如果我直接指定test
:
val test = StkNN(pa.childs[0], pb)
stkStack[depth++] = test
stkStack[depth++] = StkNN(pa.childs[1], pb)
stkStack[0]
不 test
..!
查看set(index: Int, element: Dbvt.stkNN)
中的文档,它说:
使用指定的元素
替换此列表中指定位置的元素
但这不是发生的事情