Favor the non-parented case for SetWorld...() and for updating the world transform.

Explain in documentation that the Scene transform is ignored.
This commit is contained in:
Lasse Öörni 2013-09-04 08:26:47 +00:00
Родитель 580dd746cf
Коммит 05ba4bf719
2 изменённых файлов: 13 добавлений и 19 удалений

Просмотреть файл

@ -271,7 +271,7 @@ When created, both nodes and components get scene-global integer IDs. They can b
There is no inbuilt concept of an entity or a game object; rather it is up to the programmer to decide the node hierarchy, and in which nodes to place any scripted logic. Typically, free-moving objects in the 3D world would be created as children of the root node. Nodes can be created either with or without a name, see \ref Node::CreateChild "CreateChild()". Uniqueness of node names is not enforced.
Whenever there is some hierarchical composition, it is recommended (and in fact necessary, because components do not have their own 3D transforms) to create a child node. For example if a character was holding an object in his hand, the object should have its own node, which would be parented to the character's hand bone (also a Node.) The exception is the physics CollisionShape, which can be offsetted and rotated individually in relation to the node. See \ref Physics "Physics" for more details.
Whenever there is some hierarchical composition, it is recommended (and in fact necessary, because components do not have their own 3D transforms) to create a child node. For example if a character was holding an object in his hand, the object should have its own node, which would be parented to the character's hand bone (also a Node.) The exception is the physics CollisionShape, which can be offsetted and rotated individually in relation to the node. See \ref Physics "Physics" for more details. Note that Scene's own transform is purposefully ignored as an optimization when calculating world derived transforms of child nodes, so changing it has no effect and it should be left as it is (position at origin, no rotation, no scaling.)
%Scene nodes can be freely reparented. In contrast components are always created to the node they belong to, and can not be moved between nodes. Both child nodes and components are stored using SharedPtr containers; this means that detaching a child node from its parent or removing a component will also destroy it, if no other references to it exist. Both Node & Component provide the \ref Node::Remove "Remove()" function to accomplish this without having to go through the parent. Note that no operations on the node or component in question are safe after calling that function.

Просмотреть файл

@ -308,34 +308,28 @@ void Node::SetTransform(const Vector3& position, const Quaternion& rotation, con
void Node::SetWorldPosition(const Vector3& position)
{
SetPosition((parent_ != scene_ && parent_) ? parent_->GetWorldTransform().Inverse() * position : position);
SetPosition((parent_ == scene_ || !parent_) ? position : parent_->GetWorldTransform().Inverse() * position);
}
void Node::SetWorldRotation(const Quaternion& rotation)
{
SetRotation((parent_ != scene_ && parent_) ? parent_->GetWorldRotation().Inverse() * rotation : rotation);
SetRotation((parent_ == scene_ || !parent_) ? rotation : parent_->GetWorldRotation().Inverse() * rotation);
}
void Node::SetWorldDirection(const Vector3& direction)
{
Vector3 localDirection = (parent_ != scene_ && parent_) ? parent_->GetWorldRotation().Inverse() * direction : direction;
Vector3 localDirection = (parent_ == scene_ || !parent_) ? direction : parent_->GetWorldRotation().Inverse() * direction;
SetRotation(Quaternion(Vector3::FORWARD, localDirection));
}
void Node::SetWorldScale(float scale)
{
if (parent_ != scene_ && parent_)
{
Vector3 parentWorldScale = parent_->GetWorldScale();
SetScale(Vector3(scale / parentWorldScale.x_, scale / parentWorldScale.y_, scale / parentWorldScale.z_));
}
else
SetScale(scale);
SetWorldScale(Vector3(scale, scale, scale));
}
void Node::SetWorldScale(const Vector3& scale)
{
SetScale((parent_ != scene_ && parent_) ? scale / parent_->GetWorldScale() : scale);
SetScale((parent_ == scene_ || !parent_) ? scale : scale / parent_->GetWorldScale());
}
void Node::SetWorldTransform(const Vector3& position, const Quaternion& rotation)
@ -407,7 +401,7 @@ void Node::LookAt(const Vector3& target, const Vector3& upAxis)
Vector3 targetY = targetZ.CrossProduct(targetX).Normalized();
Quaternion rotation(targetX, targetY, targetZ);
SetRotation((parent_ != scene_ && parent_) ? parent_->GetWorldRotation().Inverse() * rotation : rotation);
SetRotation((parent_ == scene_ || !parent_) ? rotation : parent_->GetWorldRotation().Inverse() * rotation);
}
void Node::Scale(float scale)
@ -1346,16 +1340,16 @@ void Node::UpdateWorldTransform() const
Matrix3x4 transform = GetTransform();
// Assume the root node (scene) has identity transform
if (parent_ != scene_ && parent_)
{
worldTransform_ = parent_->GetWorldTransform() * transform;
worldRotation_ = parent_->GetWorldRotation() * rotation_;
}
else
if (parent_ == scene_ || !parent_)
{
worldTransform_ = transform;
worldRotation_ = rotation_;
}
else
{
worldTransform_ = parent_->GetWorldTransform() * transform;
worldRotation_ = parent_->GetWorldRotation() * rotation_;
}
dirty_ = false;
}