// Copyright (C) 2023 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only

#include "qphysxstaticbody_p.h"

#include "PxPhysics.h"
#include "PxRigidActor.h"
#include "PxRigidStatic.h"

#include "qphysicsutils_p.h"
#include "qphysicsworld_p.h"
#include "qstaticrigidbody_p.h"
#include "qstaticphysxobjects_p.h"

QT_BEGIN_NAMESPACE

static inline bool fuzzyEquals(const physx::PxTransform &a, const physx::PxTransform &b)
{
    return qFuzzyCompare(a.p.x, b.p.x) && qFuzzyCompare(a.p.y, b.p.y) && qFuzzyCompare(a.p.z, b.p.z)
            && qFuzzyCompare(a.q.x, b.q.x) && qFuzzyCompare(a.q.y, b.q.y)
            && qFuzzyCompare(a.q.z, b.q.z) && qFuzzyCompare(a.q.w, b.q.w);
}

QPhysXStaticBody::QPhysXStaticBody(QStaticRigidBody *frontEnd) : QPhysXRigidBody(frontEnd) { }

DebugDrawBodyType QPhysXStaticBody::getDebugDrawBodyType()
{
    return DebugDrawBodyType::Static;
}

void QPhysXStaticBody::sync(float deltaTime, QHash<QQuick3DNode *, QMatrix4x4> &transformCache)
{
    auto *staticBody = static_cast<QStaticRigidBody *>(frontendNode);
    const physx::PxTransform poseNew = QPhysicsUtils::toPhysXTransform(staticBody->scenePosition(),
                                                                       staticBody->sceneRotation());
    const physx::PxTransform poseOld = actor->getGlobalPose();

    // For performance we only update static objects if they have been moved
    if (!fuzzyEquals(poseNew, poseOld))
        actor->setGlobalPose(poseNew);
    QPhysXActorBody::sync(deltaTime, transformCache);
}

void QPhysXStaticBody::createActor(QPhysXWorld * /*physX*/)
{
    auto &s_physx = StaticPhysXObjects::getReference();
    const physx::PxTransform trf = QPhysicsUtils::toPhysXTransform(frontendNode->scenePosition(),
                                                                   frontendNode->sceneRotation());
    actor = s_physx.physics->createRigidStatic(trf);
}

QT_END_NAMESPACE
