diff --git a/Source/Editor/SceneGraph/GUI/ActorTreeNode.cs b/Source/Editor/SceneGraph/GUI/ActorTreeNode.cs index 95f767d80..29032010e 100644 --- a/Source/Editor/SceneGraph/GUI/ActorTreeNode.cs +++ b/Source/Editor/SceneGraph/GUI/ActorTreeNode.cs @@ -658,7 +658,7 @@ namespace FlaxEditor.SceneGraph.GUI } } actor.Name = item.ShortName; - if (_dragAssets.Objects[i] is not PrefabItem p) + if (_dragAssets.Objects[i] is not PrefabItem) actor.Transform = Transform.Identity; var previousTrans = actor.Transform; ActorNode.Root.Spawn(actor, spawnParent); diff --git a/Source/Engine/Graphics/RenderView.h b/Source/Engine/Graphics/RenderView.h index e72ebaa45..778c8f2e5 100644 --- a/Source/Engine/Graphics/RenderView.h +++ b/Source/Engine/Graphics/RenderView.h @@ -335,4 +335,12 @@ public: // Calculates the world matrix for the given transformation instance rendering. void GetWorldMatrix(const Transform& transform, Matrix& world) const; + + // Applies the render origin to the transformation instance matrix. + FORCE_INLINE void GetWorldMatrix(Matrix& world) const + { + world.M41 -= Origin.X; + world.M42 -= Origin.Y; + world.M43 -= Origin.Z; + } }; diff --git a/Source/Engine/Level/Actor.cpp b/Source/Engine/Level/Actor.cpp index 60646cdbf..6ae69d471 100644 --- a/Source/Engine/Level/Actor.cpp +++ b/Source/Engine/Level/Actor.cpp @@ -657,7 +657,7 @@ void Actor::SetScale(const Float3& value) if (!Float3::NearEqual(_transform.Scale, value)) { if (_parent) - Float3::Divide(value, _parent->GetScale(), _localTransform.Scale); + Float3::Divide(value, _parent->_transform.Scale, _localTransform.Scale); else _localTransform.Scale = value; OnTransformChanged(); @@ -753,10 +753,25 @@ void Actor::AddMovement(const Vector3& translation, const Quaternion& rotation) void Actor::GetWorldToLocalMatrix(Matrix& worldToLocal) const { - _transform.GetWorld(worldToLocal); + GetLocalToWorldMatrix(worldToLocal); worldToLocal.Invert(); } +void Actor::GetLocalToWorldMatrix(Matrix& localToWorld) const +{ +#if 0 + _transform.GetWorld(localToWorld); +#else + _localTransform.GetWorld(localToWorld); + if (_parent) + { + Matrix parentToWorld; + _parent->GetLocalToWorldMatrix(parentToWorld); + localToWorld = localToWorld * parentToWorld; + } +#endif +} + void Actor::LinkPrefab(const Guid& prefabId, const Guid& prefabObjectId) { ASSERT(prefabId.IsValid()); diff --git a/Source/Engine/Level/Actor.h b/Source/Engine/Level/Actor.h index ddf6f0587..bb3570eee 100644 --- a/Source/Engine/Level/Actor.h +++ b/Source/Engine/Level/Actor.h @@ -638,10 +638,7 @@ public: /// Gets the matrix that transforms a point from the local space of the actor to world space. /// /// The world to local matrix. - API_FUNCTION() FORCE_INLINE void GetLocalToWorldMatrix(API_PARAM(Out) Matrix& localToWorld) const - { - _transform.GetWorld(localToWorld); - } + API_FUNCTION() void GetLocalToWorldMatrix(API_PARAM(Out) Matrix& localToWorld) const; public: /// diff --git a/Source/Engine/Level/Actors/AnimatedModel.cpp b/Source/Engine/Level/Actors/AnimatedModel.cpp index 319def475..027995e19 100644 --- a/Source/Engine/Level/Actors/AnimatedModel.cpp +++ b/Source/Engine/Level/Actors/AnimatedModel.cpp @@ -127,7 +127,7 @@ void AnimatedModel::GetCurrentPose(Array& nodesTransformation, bool worl if (worldSpace) { Matrix world; - _transform.GetWorld(world); + GetLocalToWorldMatrix(world); for (auto& m : nodesTransformation) m = m * world; } @@ -142,7 +142,7 @@ void AnimatedModel::SetCurrentPose(const Array& nodesTransformation, boo if (worldSpace) { Matrix world; - _transform.GetWorld(world); + GetLocalToWorldMatrix(world); Matrix invWorld; Matrix::Invert(world, invWorld); for (auto& m : GraphInstance.NodesPose) @@ -162,7 +162,7 @@ void AnimatedModel::GetNodeTransformation(int32 nodeIndex, Matrix& nodeTransform if (worldSpace) { Matrix world; - _transform.GetWorld(world); + GetLocalToWorldMatrix(world); nodeTransformation = nodeTransformation * world; } } @@ -181,7 +181,7 @@ void AnimatedModel::SetNodeTransformation(int32 nodeIndex, const Matrix& nodeTra if (worldSpace) { Matrix world; - _transform.GetWorld(world); + GetLocalToWorldMatrix(world); Matrix invWorld; Matrix::Invert(world, invWorld); GraphInstance.NodesPose[nodeIndex] = GraphInstance.NodesPose[nodeIndex] * invWorld; @@ -731,7 +731,9 @@ void AnimatedModel::UpdateBounds() } else if (model && model->IsLoaded() && model->LODs.Count() != 0) { - const BoundingBox modelBox = model->GetBox(_transform.GetWorld()); + Matrix world; + GetLocalToWorldMatrix(world); + const BoundingBox modelBox = model->GetBox(world); BoundingBox box = modelBox; if (GraphInstance.NodesPose.Count() != 0) { @@ -911,8 +913,8 @@ void AnimatedModel::Draw(RenderContext& renderContext) if (renderContext.View.Pass == DrawPass::GlobalSurfaceAtlas) return; // No supported Matrix world; - const Float3 translation = _transform.Translation - renderContext.View.Origin; - Matrix::Transformation(_transform.Scale, _transform.Orientation, translation, world); + GetLocalToWorldMatrix(world); + renderContext.View.GetWorldMatrix(world); GEOMETRY_DRAW_STATE_EVENT_BEGIN(_drawState, world); _lastMinDstSqr = Math::Min(_lastMinDstSqr, Vector3::DistanceSquared(_transform.Translation, renderContext.View.WorldPosition)); diff --git a/Source/Engine/Level/Actors/Camera.cpp b/Source/Engine/Level/Actors/Camera.cpp index c3559c87f..6f3052598 100644 --- a/Source/Engine/Level/Actors/Camera.cpp +++ b/Source/Engine/Level/Actors/Camera.cpp @@ -378,7 +378,7 @@ void Camera::UpdateCache() // Update editor preview model cache Matrix rot, tmp, world; - _transform.GetWorld(tmp); + GetLocalToWorldMatrix(tmp); Matrix::RotationY(PI * -0.5f, rot); Matrix::Multiply(rot, tmp, world); diff --git a/Source/Engine/Level/Actors/Spline.cpp b/Source/Engine/Level/Actors/Spline.cpp index dfe7c2be8..a54384dd9 100644 --- a/Source/Engine/Level/Actors/Spline.cpp +++ b/Source/Engine/Level/Actors/Spline.cpp @@ -467,7 +467,7 @@ void Spline::UpdateSpline() for (int32 i = 1; i < count; i++) _localBounds.Merge(keyframes[i].Value.Translation); Matrix world; - _transform.GetWorld(world); + GetLocalToWorldMatrix(world); BoundingBox::Transform(_localBounds, world, _box); SplineUpdated(); @@ -542,7 +542,7 @@ void Spline::OnTransformChanged() Actor::OnTransformChanged(); Matrix world; - _transform.GetWorld(world); + GetLocalToWorldMatrix(world); BoundingBox::Transform(_localBounds, world, _box); BoundingSphere::FromBox(_box, _sphere); } @@ -560,7 +560,7 @@ void Spline::Initialize() for (int32 i = 1; i < count; i++) _localBounds.Merge(keyframes[i].Value.Translation); Matrix world; - _transform.GetWorld(world); + GetLocalToWorldMatrix(world); BoundingBox::Transform(_localBounds, world, _box); } diff --git a/Source/Engine/Level/Actors/StaticModel.cpp b/Source/Engine/Level/Actors/StaticModel.cpp index d5c7e0e3e..58a471e04 100644 --- a/Source/Engine/Level/Actors/StaticModel.cpp +++ b/Source/Engine/Level/Actors/StaticModel.cpp @@ -335,8 +335,8 @@ void StaticModel::Draw(RenderContext& renderContext) return; } Matrix world; - const Float3 translation = _transform.Translation - renderContext.View.Origin; - Matrix::Transformation(_transform.Scale, _transform.Orientation, translation, world); + GetLocalToWorldMatrix(world); + renderContext.View.GetWorldMatrix(world); GEOMETRY_DRAW_STATE_EVENT_BEGIN(_drawState, world); if (_vertexColorsDirty) FlushVertexColors(); @@ -369,8 +369,8 @@ void StaticModel::Draw(RenderContextBatch& renderContextBatch) return; const RenderContext& renderContext = renderContextBatch.GetMainContext(); Matrix world; - const Float3 translation = _transform.Translation - renderContext.View.Origin; - Matrix::Transformation(_transform.Scale, _transform.Orientation, translation, world); + GetLocalToWorldMatrix(world); + renderContext.View.GetWorldMatrix(world); GEOMETRY_DRAW_STATE_EVENT_BEGIN(_drawState, world); if (_vertexColorsDirty) FlushVertexColors(); diff --git a/Source/Engine/Particles/Graph/GPU/GPUParticles.cpp b/Source/Engine/Particles/Graph/GPU/GPUParticles.cpp index 57ffa251a..94cc5ef08 100644 --- a/Source/Engine/Particles/Graph/GPU/GPUParticles.cpp +++ b/Source/Engine/Particles/Graph/GPU/GPUParticles.cpp @@ -233,11 +233,9 @@ void GPUParticles::Execute(GPUContext* context, ParticleEmitter* emitter, Partic else { Matrix worldMatrix; - const Transform transform = effect->GetTransform(); + effect->GetLocalToWorldMatrix(worldMatrix); if (viewTask) - viewTask->View.GetWorldMatrix(transform, worldMatrix); - else - transform.GetWorld(worldMatrix); + viewTask->View.GetWorldMatrix(worldMatrix); Matrix::Transpose(worldMatrix, cbData->WorldMatrix); worldMatrix.Invert(); Matrix::Transpose(worldMatrix, cbData->InvWorldMatrix); diff --git a/Source/Engine/Physics/Actors/Cloth.cpp b/Source/Engine/Physics/Actors/Cloth.cpp index a35acb066..2c6199490 100644 --- a/Source/Engine/Physics/Actors/Cloth.cpp +++ b/Source/Engine/Physics/Actors/Cloth.cpp @@ -847,7 +847,8 @@ void Cloth::OnPostUpdate() if (_meshDeformation) { // Mark mesh as dirty - const Matrix invWorld = Matrix::Invert(_transform.GetWorld()); + Matrix invWorld; + GetWorldToLocalMatrix(invWorld); BoundingBox localBounds; BoundingBox::Transform(_box, invWorld, localBounds); _meshDeformation->Dirty(_mesh.LODIndex, _mesh.MeshIndex, MeshBufferType::Vertex0, localBounds); diff --git a/Source/Engine/ShadowsOfMordor/Builder.Entries.cpp b/Source/Engine/ShadowsOfMordor/Builder.Entries.cpp index 67af59585..7ab93cfc8 100644 --- a/Source/Engine/ShadowsOfMordor/Builder.Entries.cpp +++ b/Source/Engine/ShadowsOfMordor/Builder.Entries.cpp @@ -64,7 +64,7 @@ bool cacheStaticGeometryTree(Actor* actor, ShadowsOfMordor::Builder::SceneBuildC if (useLightmap && anyValid && entry.Scale > ZeroTolerance) { Matrix worldMatrix; - staticModel->GetTransform().GetWorld(worldMatrix); + staticModel->GetLocalToWorldMatrix(worldMatrix); entry.Box = model->GetBox(worldMatrix); results.Add(entry); } diff --git a/Source/Engine/ShadowsOfMordor/Builder.Jobs.cpp b/Source/Engine/ShadowsOfMordor/Builder.Jobs.cpp index 8aed89eb3..02cedf1ad 100644 --- a/Source/Engine/ShadowsOfMordor/Builder.Jobs.cpp +++ b/Source/Engine/ShadowsOfMordor/Builder.Jobs.cpp @@ -125,7 +125,7 @@ void ShadowsOfMordor::Builder::onJobRender(GPUContext* context) auto& lod = staticModel->Model->LODs[0]; Matrix worldMatrix; - staticModel->GetTransform().GetWorld(worldMatrix); + staticModel->GetLocalToWorldMatrix(worldMatrix); Matrix::Transpose(worldMatrix, shaderData.WorldMatrix); shaderData.LightmapArea = staticModel->Lightmap.UVsArea; diff --git a/Source/Engine/UI/SpriteRender.cpp b/Source/Engine/UI/SpriteRender.cpp index 25446c9c5..a2ad0021c 100644 --- a/Source/Engine/UI/SpriteRender.cpp +++ b/Source/Engine/UI/SpriteRender.cpp @@ -213,7 +213,7 @@ void SpriteRender::OnTransformChanged() const BoundingSphere localSphere(Vector3::Zero, _size.Length()); Matrix world; - _transform.GetWorld(world); + GetLocalToWorldMatrix(world); BoundingSphere::Transform(localSphere, world, _sphere); BoundingBox::FromSphere(_sphere, _box); if (_sceneRenderingKey != -1)