Use a temp variable when calculating a merged world bounding box, as OnWorldBoundingBoxUpdate() may be called re-entrantly from multiple worker threads.
This commit is contained in:
parent
41f627b230
commit
9443cce235
@ -310,13 +310,12 @@ const PODVector<unsigned char>& BillboardSet::GetNetBillboardsAttr() const
|
||||
|
||||
void BillboardSet::OnWorldBoundingBoxUpdate()
|
||||
{
|
||||
worldBoundingBox_.defined_ = false;
|
||||
|
||||
unsigned enabledBillboards = 0;
|
||||
const Matrix3x4& worldTransform = node_->GetWorldTransform();
|
||||
Matrix3x4 billboardTransform = relative_ ? worldTransform : Matrix3x4::IDENTITY;
|
||||
Vector3 billboardScale = scaled_ ? worldTransform.Scale() : Vector3::ONE;
|
||||
|
||||
BoundingBox worldBox;
|
||||
|
||||
for (unsigned i = 0; i < billboards_.Size(); ++i)
|
||||
{
|
||||
if (!billboards_[i].enabled_)
|
||||
@ -325,14 +324,16 @@ void BillboardSet::OnWorldBoundingBoxUpdate()
|
||||
float size = INV_SQRT_TWO * (billboards_[i].size_.x_ * billboardScale.x_ + billboards_[i].size_.y_ * billboardScale.y_);
|
||||
Vector3 center = billboardTransform * billboards_[i].position_;
|
||||
Vector3 edge = Vector3::ONE * size;
|
||||
worldBoundingBox_.Merge(BoundingBox(center - edge, center + edge));
|
||||
worldBox.Merge(BoundingBox(center - edge, center + edge));
|
||||
|
||||
++enabledBillboards;
|
||||
}
|
||||
|
||||
// If no billboards enabled, the bounding box is just the node's world position
|
||||
if (!enabledBillboards)
|
||||
worldBoundingBox_.Merge(node_->GetWorldPosition());
|
||||
worldBox.Merge(node_->GetWorldPosition());
|
||||
|
||||
worldBoundingBox_ = worldBox;
|
||||
}
|
||||
|
||||
void BillboardSet::UpdateBufferSize()
|
||||
|
@ -661,7 +661,7 @@ void DecalSet::OnWorldBoundingBoxUpdate()
|
||||
else
|
||||
{
|
||||
// When using skinning, update world bounding box based on the bones
|
||||
worldBoundingBox_.defined_ = false;
|
||||
BoundingBox worldBox;
|
||||
|
||||
for (Vector<Bone>::ConstIterator i = bones_.Begin(); i != bones_.End(); ++i)
|
||||
{
|
||||
@ -672,10 +672,12 @@ void DecalSet::OnWorldBoundingBoxUpdate()
|
||||
// Use hitbox if available. If not, use only half of the sphere radius
|
||||
/// \todo The sphere radius should be multiplied with bone scale
|
||||
if (i->collisionMask_ & BONECOLLISION_BOX)
|
||||
worldBoundingBox_.Merge(i->boundingBox_.Transformed(boneNode->GetWorldTransform()));
|
||||
worldBox.Merge(i->boundingBox_.Transformed(boneNode->GetWorldTransform()));
|
||||
else if (i->collisionMask_ & BONECOLLISION_SPHERE)
|
||||
worldBoundingBox_.Merge(Sphere(boneNode->GetWorldPosition(), i->radius_ * 0.5f));
|
||||
worldBox.Merge(Sphere(boneNode->GetWorldPosition(), i->radius_ * 0.5f));
|
||||
}
|
||||
|
||||
worldBoundingBox_ = worldBox;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -351,9 +351,10 @@ void StaticModelGroup::OnNodeSetEnabled(Node* node)
|
||||
void StaticModelGroup::OnWorldBoundingBoxUpdate()
|
||||
{
|
||||
// Update transforms and bounding box at the same time to have to go through the objects only once
|
||||
worldBoundingBox_.defined_ = false;
|
||||
unsigned index = 0;
|
||||
|
||||
BoundingBox worldBox;
|
||||
|
||||
for (unsigned i = 0; i < instanceNodes_.Size(); ++i)
|
||||
{
|
||||
Node* node = instanceNodes_[i];
|
||||
@ -362,9 +363,11 @@ void StaticModelGroup::OnWorldBoundingBoxUpdate()
|
||||
|
||||
const Matrix3x4& worldTransform = node->GetWorldTransform();
|
||||
worldTransforms_[index++] = worldTransform;
|
||||
worldBoundingBox_.Merge(boundingBox_.Transformed(worldTransform));
|
||||
worldBox.Merge(boundingBox_.Transformed(worldTransform));
|
||||
}
|
||||
|
||||
worldBoundingBox_ = worldBox;
|
||||
|
||||
// Store the amount of valid instances we found instead of resizing worldTransforms_. This is because this function may be
|
||||
// called from multiple worker threads simultaneously
|
||||
numWorldTransforms_ = index;
|
||||
|
Loading…
Reference in New Issue
Block a user