我现在有点困在我的基本体素物理学。这非常非常不稳定,我很确定我的数学在某个地方被破坏了,但让我们看看你有什么要说的:
// SOMEWHERE AT CLASS LEVEL (so not being reinstantiated every frame, but persisted instead!)
glm::vec3 oldPos;
// ACTUAL IMPL
glm::vec3 distanceToGravityCenter =
this->entity->getPosition() -
((this->entity->getPosition() - gravityCenter) * 0.005d); // TODO multiply by time
if (!entity->grounded) {
glm::vec3 entityPosition = entity->getPosition();
if (getBlock(floorf(entityPosition.x), floorf(entityPosition.y), floorf(entityPosition.z))) {
glm::vec3 dir = entityPosition - oldPos; // Actually no need to normalize as we check for lesser, bigger or equal to 0
std::cout << "falling dir: " << glm::to_string(dir) << std::endl;
// Calculate offset (where to put after hit)
int x = dir.x;
int y = dir.y;
int z = dir.z;
if (dir.x >= 0) {
x = -1;
} else if (dir.x < 0) {
x = 1;
}
if (dir.y >= 0) {
y = -1;
} else if (dir.y < 0) {
y = 1;
}
if (dir.z >= 0) {
z = -1;
} else if (dir.z < 0) {
z = 1;
}
glm::vec3 newPos = oldPos + glm::vec3(x, y, z);
this->entity->setPosition(newPos);
entity->grounded = true; // If some update happens, grounded needs to be changed
} else {
oldPos = entity->getPosition();
this->entity->setPosition(distanceToGravityCenter);
}
}
基本思想是确定实体将从哪个方向击中表面,然后将一个“单位”放回到该方向。但显然我做错了,因为它总会将实体移回到它产生的位置,有效地将它保持在产生点。
这也可能更容易,我正在思考它。
答案 0 :(得分:1)
考虑一个坐标的if
- 语句:
if (dir.x >= 0) {
x = -1;
}
if (dir.x < 0) {
x = 1;
}
假设dir.x < 0
。然后,您将跳过第一个if
,输入第二个,x
将设置为1。
如果dir.x >= 0
,您将输入第一个if
,x
将设置为-1
。现在x < 0
为真,因此您也会输入第二个if
,x
再次设置为1。
您可能希望将x
设置为1或-1
,具体取决于dir.x
。您只应在未输入第一个if
时执行第二个else if
,因此您需要if (dir.x >= 0) {
x = -1;
} else if (dir.x < 0) {
x = 1;
}
:
x = (dir.x >= 0) ? -1 : 1;
如果您愿意,可以将其浓缩为
class Reaction(models.Model):
first_object = models.ForeignKey(Object, related_name='first_object')
second_object = models.ForeignKey(Object, related_name='second_object')
result_object = models.ForeignKey(Object, related_name='result_object')
class Meta:
unique_together = (('first_object', 'second_object',),)
答案 1 :(得分:1)
正如@CompuChip已经指出的那样,您的ifs
可以进一步简化。
但更重要的是一个逻辑问题可以解释&#34;波动&#34;你描述(可悲的是你没有提供任何镜头,所以这是我最好的猜测)
根据您发布的代码:
首先检查实体是否已接地。如果是这样,你继续检查是否有碰撞,最后,如果没有,你设置位置。
你必须反过来。
基本上是这样的:
glm::vec3 distanceToGravityCenter =
this->entity->getPosition() -
((this->entity->getPosition() - gravityCenter) * 0.005d); // TODO multiply by time
oldPos = entity->getPosition(); // 1.
if (!entity->grounded) { // 2.
this->fallingStar->setPosition(distanceToGravityPoint); // 3
glm::vec3 entityPosition = entity->getPosition();
if (getBlock(floorf(entityPosition.x), floorf(entityPosition.y), floorf(entityPosition.z))) { // 4, 5
this->entity->setPosition(oldPos);
entity->grounded = true; // If some update happens, grounded needs to be changed
}
}
这应该让你开始:)
我想详细说明一下:
如果先检查碰撞然后再设置位置,则会创建一个&#34;无限循环&#34;当你碰撞时第一次碰撞/撞击,然后如果发生碰撞(有),你就会回到原来的位置。基本上只是数学上的不准确会让你移动,因为每次检查都会让你回到原来的位置。