no message
This commit is contained in:
83
cocos/physics/physx/joints/PhysXFixedJoint.cpp
Normal file
83
cocos/physics/physx/joints/PhysXFixedJoint.cpp
Normal file
@@ -0,0 +1,83 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#include "physics/physx/joints/PhysXFixedJoint.h"
|
||||
#include "math/Quaternion.h"
|
||||
#include "physics/physx/PhysXSharedBody.h"
|
||||
#include "physics/physx/PhysXUtils.h"
|
||||
|
||||
namespace cc {
|
||||
namespace physics {
|
||||
|
||||
void PhysXFixedJoint::onComponentSet() {
|
||||
_transA = physx::PxTransform(physx::PxIdentity);
|
||||
_transB = physx::PxTransform(physx::PxIdentity);
|
||||
|
||||
physx::PxRigidActor *actor0 = _mSharedBody->getImpl().rigidActor;
|
||||
physx::PxRigidActor *actor1 = nullptr;
|
||||
|
||||
if (_mConnectedBody) {
|
||||
actor1 = _mConnectedBody->getImpl().rigidActor;
|
||||
}
|
||||
|
||||
_mJoint = PxFixedJointCreate(PxGetPhysics(), actor0, _transA, actor1, _transB);
|
||||
|
||||
updatePose();
|
||||
setEnableDebugVisualization(true);
|
||||
}
|
||||
|
||||
void PhysXFixedJoint::setBreakForce(float force) {
|
||||
_breakForce = force;
|
||||
_mJoint->setBreakForce(_breakForce, _breakTorque);
|
||||
}
|
||||
|
||||
void PhysXFixedJoint::setBreakTorque(float torque) {
|
||||
_breakTorque = torque;
|
||||
_mJoint->setBreakForce(_breakForce, _breakTorque);
|
||||
}
|
||||
|
||||
void PhysXFixedJoint::updateScale0() {
|
||||
updatePose();
|
||||
}
|
||||
|
||||
void PhysXFixedJoint::updateScale1() {
|
||||
updatePose();
|
||||
}
|
||||
|
||||
void PhysXFixedJoint::updatePose() {
|
||||
_transA = physx::PxTransform(physx::PxIdentity);
|
||||
_transB = physx::PxTransform(physx::PxIdentity);
|
||||
|
||||
pxSetVec3Ext(_transA.p, _mSharedBody->getNode()->getWorldPosition());
|
||||
pxSetQuatExt(_transA.q, _mSharedBody->getNode()->getWorldRotation());
|
||||
if (_mConnectedBody) {
|
||||
pxSetVec3Ext(_transB.p, _mConnectedBody->getNode()->getWorldPosition());
|
||||
pxSetQuatExt(_transB.q, _mConnectedBody->getNode()->getWorldRotation());
|
||||
}
|
||||
_mJoint->setLocalPose(physx::PxJointActorIndex::eACTOR0, _transA.getInverse());
|
||||
_mJoint->setLocalPose(physx::PxJointActorIndex::eACTOR1, _transB.getInverse());
|
||||
}
|
||||
|
||||
} // namespace physics
|
||||
} // namespace cc
|
||||
53
cocos/physics/physx/joints/PhysXFixedJoint.h
Normal file
53
cocos/physics/physx/joints/PhysXFixedJoint.h
Normal file
@@ -0,0 +1,53 @@
|
||||
|
||||
/****************************************************************************
|
||||
Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "physics/physx/joints/PhysXJoint.h"
|
||||
|
||||
namespace cc {
|
||||
namespace physics {
|
||||
|
||||
class PhysXFixedJoint final : public PhysXJoint, public IFixedJoint {
|
||||
public:
|
||||
PhysXFixedJoint() {}
|
||||
~PhysXFixedJoint() override = default;
|
||||
|
||||
void setBreakForce(float force) override;
|
||||
void setBreakTorque(float torque) override;
|
||||
void updateScale0() override;
|
||||
void updateScale1() override;
|
||||
|
||||
private:
|
||||
void onComponentSet() override;
|
||||
void updatePose();
|
||||
float _breakForce = 0.0F;
|
||||
float _breakTorque = 0.0F;
|
||||
physx::PxTransform _transA;
|
||||
physx::PxTransform _transB;
|
||||
};
|
||||
|
||||
} // namespace physics
|
||||
} // namespace cc
|
||||
508
cocos/physics/physx/joints/PhysXGenericJoint.cpp
Normal file
508
cocos/physics/physx/joints/PhysXGenericJoint.cpp
Normal file
@@ -0,0 +1,508 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#include "physics/physx/joints/PhysXGenericJoint.h"
|
||||
#include <physics/sdk/Joint.h>
|
||||
#include "math/Mat4.h"
|
||||
#include "math/Quaternion.h"
|
||||
#include "math/Utils.h"
|
||||
#include "math/Vec3.h"
|
||||
#include "physics/physx/PhysXSharedBody.h"
|
||||
#include "physics/physx/PhysXUtils.h"
|
||||
|
||||
namespace cc {
|
||||
namespace physics {
|
||||
|
||||
void PhysXGenericJoint::onComponentSet() {
|
||||
_mJoint = PxD6JointCreate(PxGetPhysics(), &getTempRigidActor(), physx::PxTransform{physx::PxIdentity}, nullptr, physx::PxTransform{physx::PxIdentity});
|
||||
setEnableDebugVisualization(true);
|
||||
}
|
||||
|
||||
inline auto mapAxis(uint32_t index) -> physx::PxD6Axis::Enum {
|
||||
switch (index) {
|
||||
case 0:
|
||||
return physx::PxD6Axis::Enum::eX;
|
||||
case 1:
|
||||
return physx::PxD6Axis::Enum::eY;
|
||||
case 2:
|
||||
return physx::PxD6Axis::Enum::eZ;
|
||||
case 3:
|
||||
return physx::PxD6Axis::Enum::eTWIST;
|
||||
case 4:
|
||||
return physx::PxD6Axis::Enum::eSWING1;
|
||||
case 5:
|
||||
return physx::PxD6Axis::Enum::eSWING2;
|
||||
default:
|
||||
assert(false && "unsupported axis");
|
||||
return physx::PxD6Axis::Enum::eX;
|
||||
}
|
||||
}
|
||||
|
||||
void PhysXGenericJoint::setConstraintMode(uint32_t index, uint32_t mode) {
|
||||
physx::PxD6Axis::Enum axis{mapAxis(index)};
|
||||
physx::PxD6Motion::Enum motion{};
|
||||
switch (mode) {
|
||||
case 0:
|
||||
motion = physx::PxD6Motion::Enum::eFREE;
|
||||
break;
|
||||
case 1:
|
||||
motion = physx::PxD6Motion::Enum::eLIMITED;
|
||||
break;
|
||||
case 2:
|
||||
motion = physx::PxD6Motion::Enum::eLOCKED;
|
||||
break;
|
||||
default:
|
||||
motion = physx::PxD6Motion::Enum::eFREE;
|
||||
break;
|
||||
}
|
||||
switch (index) {
|
||||
case 0:
|
||||
_linearLimit.x = motion;
|
||||
break;
|
||||
case 1:
|
||||
_linearLimit.y = motion;
|
||||
break;
|
||||
case 2:
|
||||
_linearLimit.z = motion;
|
||||
break;
|
||||
case 3:
|
||||
_angularLimit.eTwist = motion;
|
||||
break;
|
||||
case 4:
|
||||
case 5:
|
||||
_angularLimit.eSwing = motion;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
auto* _joint{static_cast<physx::PxD6Joint*>(_mJoint)};
|
||||
_joint->setMotion(axis, motion);
|
||||
}
|
||||
|
||||
void PhysXGenericJoint::setLinearLimit(uint32_t index, float lower, float upper) {
|
||||
assert(index < 3); // linear index should be 1, 2, or 3
|
||||
_linearLimit.lower[index] = lower;
|
||||
_linearLimit.upper[index] = upper;
|
||||
updateLinearLimit();
|
||||
}
|
||||
|
||||
void PhysXGenericJoint::setAngularExtent(float twist, float swing1, float swing2) {
|
||||
_angularLimit.twistExtent = mathutils::toRadian(std::fmax(twist, 1e-9));
|
||||
_angularLimit.swing1Extent = mathutils::toRadian(std::fmax(swing1, 1e-9));
|
||||
_angularLimit.swing2Extent = mathutils::toRadian(std::fmax(swing2, 1e-9));
|
||||
|
||||
updateTwistLimit();
|
||||
updateSwingLimit();
|
||||
}
|
||||
|
||||
void PhysXGenericJoint::setLinearSoftConstraint(bool enable) {
|
||||
_linearLimit.soft = enable;
|
||||
updateLinearLimit();
|
||||
}
|
||||
|
||||
void PhysXGenericJoint::setLinearStiffness(float stiffness) {
|
||||
_linearLimit.stiffness = stiffness;
|
||||
updateLinearLimit();
|
||||
}
|
||||
|
||||
void PhysXGenericJoint::setLinearDamping(float damping) {
|
||||
_linearLimit.damping = damping;
|
||||
updateLinearLimit();
|
||||
}
|
||||
|
||||
void PhysXGenericJoint::setLinearRestitution(float restitution) {
|
||||
_linearLimit.restitution = restitution;
|
||||
updateLinearLimit();
|
||||
}
|
||||
|
||||
void PhysXGenericJoint::setSwingSoftConstraint(bool enable) {
|
||||
_angularLimit.swingSoft = enable;
|
||||
updateSwingLimit();
|
||||
}
|
||||
|
||||
void PhysXGenericJoint::setSwingStiffness(float stiffness) {
|
||||
_angularLimit.swingStiffness = stiffness;
|
||||
updateSwingLimit();
|
||||
}
|
||||
|
||||
void PhysXGenericJoint::setSwingDamping(float damping) {
|
||||
_angularLimit.swingDamping = damping;
|
||||
updateSwingLimit();
|
||||
}
|
||||
|
||||
void PhysXGenericJoint::setSwingRestitution(float restitution) {
|
||||
_angularLimit.swingRestitution = restitution;
|
||||
updateSwingLimit();
|
||||
}
|
||||
|
||||
void PhysXGenericJoint::setTwistSoftConstraint(bool enable) {
|
||||
_angularLimit.twistSoft = enable;
|
||||
updateTwistLimit();
|
||||
}
|
||||
|
||||
void PhysXGenericJoint::setTwistStiffness(float stiffness) {
|
||||
_angularLimit.twistStiffness = stiffness;
|
||||
updateTwistLimit();
|
||||
}
|
||||
|
||||
void PhysXGenericJoint::setTwistDamping(float damping) {
|
||||
_angularLimit.twistDamping = damping;
|
||||
updateTwistLimit();
|
||||
}
|
||||
|
||||
void PhysXGenericJoint::setTwistRestitution(float restitution) {
|
||||
_angularLimit.twistRestitution = restitution;
|
||||
updateTwistLimit();
|
||||
}
|
||||
|
||||
void PhysXGenericJoint::setDriverMode(uint32_t index, uint32_t mode) {
|
||||
switch (index) {
|
||||
case 0:
|
||||
_linearMotor.xDrive = mode;
|
||||
break;
|
||||
case 1:
|
||||
_linearMotor.yDrive = mode;
|
||||
break;
|
||||
case 2:
|
||||
_linearMotor.zDrive = mode;
|
||||
break;
|
||||
case 3:
|
||||
_angularMotor.twistDrive = mode;
|
||||
break;
|
||||
case 4:
|
||||
_angularMotor.swingDrive1 = mode;
|
||||
break;
|
||||
case 5:
|
||||
_angularMotor.swingDrive2 = mode;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
this->updateDrive(index);
|
||||
}
|
||||
|
||||
void PhysXGenericJoint::setLinearMotorTarget(float x, float y, float z) {
|
||||
auto& p = _linearMotor.target;
|
||||
p.x = x;
|
||||
p.y = y;
|
||||
p.z = z;
|
||||
this->updateDrivePosition();
|
||||
}
|
||||
|
||||
void PhysXGenericJoint::setLinearMotorVelocity(float x, float y, float z) {
|
||||
auto& v = _linearMotor.velocity;
|
||||
v.x = x;
|
||||
v.y = y;
|
||||
v.z = z;
|
||||
this->updateDriveVelocity();
|
||||
}
|
||||
|
||||
void PhysXGenericJoint::setLinearMotorForceLimit(float limit) {
|
||||
_linearMotor.forceLimit = limit;
|
||||
updateDrive(0);
|
||||
updateDrive(1);
|
||||
updateDrive(2);
|
||||
}
|
||||
|
||||
void PhysXGenericJoint::setAngularMotorTarget(float x, float y, float z) {
|
||||
auto& p = _angularMotor.target;
|
||||
p.x = x;
|
||||
p.y = y;
|
||||
p.z = z;
|
||||
this->updateDrivePosition();
|
||||
}
|
||||
|
||||
void PhysXGenericJoint::setAngularMotorVelocity(float x, float y, float z) {
|
||||
auto& v = _angularMotor.velocity;
|
||||
v.x = -mathutils::toRadian(x);
|
||||
v.y = -mathutils::toRadian(y);
|
||||
v.z = -mathutils::toRadian(z);
|
||||
this->updateDriveVelocity();
|
||||
}
|
||||
|
||||
void PhysXGenericJoint::setAngularMotorForceLimit(float limit) {
|
||||
_angularMotor.forceLimit = limit;
|
||||
this->updateDrive(3);
|
||||
this->updateDrive(4);
|
||||
this->updateDrive(5);
|
||||
}
|
||||
|
||||
void PhysXGenericJoint::setPivotA(float x, float y, float z) {
|
||||
_mPivotA.x = x;
|
||||
_mPivotA.y = y;
|
||||
_mPivotA.z = z;
|
||||
updatePose();
|
||||
}
|
||||
void PhysXGenericJoint::setPivotB(float x, float y, float z) {
|
||||
_mPivotB.x = x;
|
||||
_mPivotB.y = y;
|
||||
_mPivotB.z = z;
|
||||
updatePose();
|
||||
}
|
||||
void PhysXGenericJoint::setAutoPivotB(bool autoPivot) {
|
||||
_mAutoPivotB = autoPivot;
|
||||
updatePose();
|
||||
}
|
||||
void PhysXGenericJoint::setAxis(float x, float y, float z) {
|
||||
_mAxis.x = x;
|
||||
_mAxis.y = y;
|
||||
_mAxis.z = z;
|
||||
updatePose();
|
||||
}
|
||||
void PhysXGenericJoint::setSecondaryAxis(float x, float y, float z) {
|
||||
_mSecondary.x = x;
|
||||
_mSecondary.y = y;
|
||||
_mSecondary.z = z;
|
||||
updatePose();
|
||||
}
|
||||
|
||||
void PhysXGenericJoint::setBreakForce(float force) {
|
||||
_breakForce = force;
|
||||
physx::PxD6Joint* joint{static_cast<physx::PxD6Joint*>(_mJoint)};
|
||||
joint->getBreakForce(_breakForce, _breakTorque);
|
||||
}
|
||||
void PhysXGenericJoint::setBreakTorque(float torque) {
|
||||
_breakTorque = torque;
|
||||
physx::PxD6Joint* joint{static_cast<physx::PxD6Joint*>(_mJoint)};
|
||||
joint->getBreakForce(_breakForce, _breakTorque);
|
||||
}
|
||||
void PhysXGenericJoint::updateScale0() {
|
||||
this->updatePose();
|
||||
}
|
||||
void PhysXGenericJoint::updateScale1() {
|
||||
this->updatePose();
|
||||
}
|
||||
|
||||
void PhysXGenericJoint::updateLinearLimit() {
|
||||
physx::PxD6Joint* joint{static_cast<physx::PxD6Joint*>(_mJoint)};
|
||||
const auto lower = _linearLimit.lower;
|
||||
const auto upper = _linearLimit.upper;
|
||||
auto limitx = joint->getLinearLimit(physx::PxD6Axis::Enum::eX);
|
||||
auto limity = joint->getLinearLimit(physx::PxD6Axis::Enum::eY);
|
||||
auto limitz = joint->getLinearLimit(physx::PxD6Axis::Enum::eZ);
|
||||
if (_linearLimit.soft) {
|
||||
limitx.stiffness = _linearLimit.stiffness;
|
||||
limitx.damping = _linearLimit.damping;
|
||||
} else {
|
||||
limitx.stiffness = 0.0;
|
||||
limitx.damping = 0.0;
|
||||
}
|
||||
limitx.contactDistance = 0.1;
|
||||
limitx.bounceThreshold = 0.1;
|
||||
limitx.restitution = _linearLimit.restitution;
|
||||
|
||||
limity = limitx;
|
||||
limitz = limitx;
|
||||
if (_linearLimit.x == physx::PxD6Motion::Enum::eLIMITED) {
|
||||
limitx.upper = upper[0];
|
||||
limitx.lower = lower[0];
|
||||
joint->setLinearLimit(physx::PxD6Axis::Enum::eX, limitx);
|
||||
}
|
||||
if (_linearLimit.y == physx::PxD6Motion::Enum::eLIMITED) {
|
||||
limity.upper = upper[1];
|
||||
limity.lower = lower[1];
|
||||
joint->setLinearLimit(physx::PxD6Axis::Enum::eY, limity);
|
||||
}
|
||||
if (_linearLimit.z == physx::PxD6Motion::Enum::eLIMITED) {
|
||||
limitz.upper = upper[2];
|
||||
limitz.lower = lower[2];
|
||||
joint->setLinearLimit(physx::PxD6Axis::Enum::eZ, limitz);
|
||||
}
|
||||
}
|
||||
|
||||
void PhysXGenericJoint::updateSwingLimit() {
|
||||
if (_angularLimit.eSwing != physx::PxD6Motion::Enum::eLIMITED) {
|
||||
return;
|
||||
}
|
||||
|
||||
physx::PxD6Joint* joint{static_cast<physx::PxD6Joint*>(_mJoint)};
|
||||
auto coneLimit = joint->getSwingLimit();
|
||||
if (_angularLimit.swingSoft) {
|
||||
coneLimit.stiffness = _angularLimit.swingStiffness;
|
||||
coneLimit.damping = _angularLimit.swingDamping;
|
||||
} else {
|
||||
coneLimit.stiffness = 0;
|
||||
coneLimit.damping = 0;
|
||||
}
|
||||
coneLimit.bounceThreshold = 0.1;
|
||||
coneLimit.contactDistance = 0.1;
|
||||
coneLimit.restitution = _angularLimit.swingRestitution;
|
||||
coneLimit.yAngle = math::PI;
|
||||
coneLimit.zAngle = math::PI;
|
||||
if (_angularLimit.eSwing == 1) {
|
||||
coneLimit.yAngle = _angularLimit.swing1Extent * 0.5;
|
||||
coneLimit.zAngle = _angularLimit.swing2Extent * 0.5;
|
||||
joint->setSwingLimit(coneLimit);
|
||||
}
|
||||
}
|
||||
|
||||
void PhysXGenericJoint::updateTwistLimit() {
|
||||
if (_angularLimit.eTwist != physx::PxD6Motion::Enum::eLIMITED) {
|
||||
return;
|
||||
}
|
||||
physx::PxD6Joint* joint{static_cast<physx::PxD6Joint*>(_mJoint)};
|
||||
auto twistLimit = joint->getTwistLimit();
|
||||
twistLimit.bounceThreshold = 0.1;
|
||||
twistLimit.contactDistance = 0.1;
|
||||
twistLimit.restitution = _angularLimit.twistRestitution;
|
||||
if (_angularLimit.twistSoft) {
|
||||
twistLimit.stiffness = _angularLimit.twistStiffness;
|
||||
twistLimit.damping = _angularLimit.twistDamping;
|
||||
} else {
|
||||
twistLimit.damping = 0;
|
||||
twistLimit.stiffness = _angularLimit.twistStiffness;
|
||||
}
|
||||
if (_angularLimit.eTwist == 1) {
|
||||
twistLimit.lower = _angularLimit.twistExtent * -0.5;
|
||||
twistLimit.upper = _angularLimit.twistExtent * 0.5;
|
||||
joint->setTwistLimit(twistLimit);
|
||||
}
|
||||
}
|
||||
|
||||
void PhysXGenericJoint::updateDrive(uint32_t axis) {
|
||||
assert(axis < 6 && "axis should be in [0, 5]");
|
||||
physx::PxD6Joint* joint{static_cast<physx::PxD6Joint*>(_mJoint)};
|
||||
auto drive = joint->getDrive(static_cast<physx::PxD6Drive::Enum>(axis));
|
||||
|
||||
uint32_t mode = 0;
|
||||
physx::PxD6Drive::Enum driveAxis = physx::PxD6Drive::Enum::eX;
|
||||
switch (axis) {
|
||||
case 0:
|
||||
mode = _linearMotor.xDrive;
|
||||
driveAxis = physx::PxD6Drive::Enum::eX;
|
||||
break;
|
||||
case 1:
|
||||
mode = _linearMotor.yDrive;
|
||||
driveAxis = physx::PxD6Drive::Enum::eY;
|
||||
break;
|
||||
case 2:
|
||||
mode = _linearMotor.zDrive;
|
||||
driveAxis = physx::PxD6Drive::Enum::eZ;
|
||||
break;
|
||||
case 3:
|
||||
mode = _angularMotor.twistDrive;
|
||||
driveAxis = physx::PxD6Drive::Enum::eTWIST;
|
||||
break;
|
||||
case 4:
|
||||
case 5:
|
||||
if (_angularMotor.swingDrive1 == 2 || _angularMotor.swingDrive2 == 2) {
|
||||
mode = 2;
|
||||
} else if (_angularMotor.swingDrive1 == 1 || _angularMotor.swingDrive2 == 1) {
|
||||
mode = 1;
|
||||
} else {
|
||||
mode = 0;
|
||||
}
|
||||
driveAxis = physx::PxD6Drive::Enum::eSWING;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
};
|
||||
|
||||
if (axis < 3) {
|
||||
drive.forceLimit = _linearMotor.forceLimit;
|
||||
} else if (axis == 3) {
|
||||
drive.forceLimit = _angularMotor.forceLimit;
|
||||
} else if (axis < 6) {
|
||||
drive.forceLimit = _angularMotor.forceLimit;
|
||||
}
|
||||
|
||||
if (mode == 0) { // disabled
|
||||
drive.forceLimit = 0;
|
||||
} else if (mode == 1) { // servo
|
||||
drive.damping = 0.0;
|
||||
drive.stiffness = 1000.0;
|
||||
} else if (mode == 2) { // induction
|
||||
drive.damping = 1000.0;
|
||||
drive.stiffness = 0.0;
|
||||
}
|
||||
joint->setDrive(driveAxis, drive);
|
||||
}
|
||||
|
||||
void PhysXGenericJoint::updateDrivePosition() {
|
||||
physx::PxD6Joint* joint{static_cast<physx::PxD6Joint*>(_mJoint)};
|
||||
physx::PxTransform trans{};
|
||||
|
||||
const auto& ld = _linearMotor.target;
|
||||
const auto& ad = _angularMotor.target;
|
||||
|
||||
Quaternion quat;
|
||||
Quaternion::fromEuler(ad.x, ad.y, ad.z, &quat);
|
||||
pxSetVec3Ext(trans.p, Vec3(ld.x, ld.y, ld.z));
|
||||
pxSetQuatExt(trans.q, quat);
|
||||
|
||||
joint->setDrivePosition(trans, true);
|
||||
}
|
||||
|
||||
void PhysXGenericJoint::updateDriveVelocity() {
|
||||
physx::PxD6Joint* joint{static_cast<physx::PxD6Joint*>(_mJoint)};
|
||||
joint->setDriveVelocity(_linearMotor.velocity, _angularMotor.velocity, true);
|
||||
}
|
||||
|
||||
void PhysXGenericJoint::updatePose() {
|
||||
physx::PxTransform pose0{physx::PxIdentity};
|
||||
physx::PxTransform pose1{physx::PxIdentity};
|
||||
auto* node0 = _mSharedBody->getNode();
|
||||
node0->updateWorldTransform();
|
||||
_mTertiary = _mAxis.cross(_mSecondary);
|
||||
|
||||
Mat4 transform(
|
||||
_mAxis.x, _mAxis.y, _mAxis.z, 0.F,
|
||||
_mSecondary.x, _mSecondary.y, _mSecondary.z, 0.F,
|
||||
_mTertiary.x, _mTertiary.y, _mTertiary.z, 0.F,
|
||||
0.F, 0.F, 0.F, 1.F);
|
||||
|
||||
Quaternion quat{transform};
|
||||
pose0.q = physx::PxQuat{quat.x, quat.y, quat.z, quat.w};
|
||||
Vec3 pos = Vec3(_mPivotA.x, _mPivotA.y, _mPivotA.z) * node0->getWorldScale();
|
||||
pose0.p = physx::PxVec3{pos.x, pos.y, pos.z};
|
||||
_mJoint->setLocalPose(physx::PxJointActorIndex::eACTOR0, pose0);
|
||||
|
||||
if (_mConnectedBody) {
|
||||
auto* node1 = _mConnectedBody->getNode();
|
||||
node1->updateWorldTransform();
|
||||
const auto& rot_1_i = node1->getWorldRotation().getInversed();
|
||||
if (_mAutoPivotB) {
|
||||
pos.transformQuat(node0->getWorldRotation());
|
||||
pos += node0->getWorldPosition();
|
||||
pos -= node1->getWorldPosition();
|
||||
pos.transformQuat(rot_1_i);
|
||||
pxSetVec3Ext(pose1.p, pos);
|
||||
} else {
|
||||
pose1.p = _mPivotB * node1->getWorldScale();
|
||||
}
|
||||
Quaternion::multiply(node0->getWorldRotation(), quat, &quat);
|
||||
Quaternion::multiply(rot_1_i, quat, &quat);
|
||||
pxSetQuatExt(pose1.q, quat);
|
||||
} else {
|
||||
pos.transformQuat(node0->getWorldRotation());
|
||||
pos += node0->getWorldPosition();
|
||||
Quaternion::multiply(node0->getWorldRotation(), quat, &quat);
|
||||
pose1.p = physx::PxVec3{pos.x, pos.y, pos.z};
|
||||
pose1.q = physx::PxQuat{quat.x, quat.y, quat.z, quat.w};
|
||||
}
|
||||
_mJoint->setLocalPose(physx::PxJointActorIndex::eACTOR1, pose1);
|
||||
}
|
||||
|
||||
} // namespace physics
|
||||
} // namespace cc
|
||||
143
cocos/physics/physx/joints/PhysXGenericJoint.h
Normal file
143
cocos/physics/physx/joints/PhysXGenericJoint.h
Normal file
@@ -0,0 +1,143 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "physics/physx/joints/PhysXJoint.h"
|
||||
|
||||
namespace cc {
|
||||
namespace physics {
|
||||
|
||||
class PhysXGenericJoint final : public PhysXJoint, public IGenericJoint {
|
||||
public:
|
||||
PhysXGenericJoint() = default;
|
||||
~PhysXGenericJoint() = default;
|
||||
|
||||
void setConstraintMode(uint32_t index, uint32_t mode) override;
|
||||
void setLinearLimit(uint32_t index, float lower, float upper) override; // linear only, angular use extent is better
|
||||
void setAngularExtent(float twist, float swing1, float swing2) override;
|
||||
void setLinearSoftConstraint(bool enable) override;
|
||||
void setLinearStiffness(float stiffness) override;
|
||||
void setLinearDamping(float damping) override;
|
||||
void setLinearRestitution(float restitution) override;
|
||||
|
||||
// TODO (yiwenxue): add new function to set angular limit
|
||||
void setSwingSoftConstraint(bool enable) override;
|
||||
void setTwistSoftConstraint(bool enable) override;
|
||||
void setSwingStiffness(float stiffness) override;
|
||||
void setSwingDamping(float damping) override;
|
||||
void setSwingRestitution(float restitution) override;
|
||||
void setTwistStiffness(float stiffness) override;
|
||||
void setTwistDamping(float damping) override;
|
||||
void setTwistRestitution(float restitution) override;
|
||||
|
||||
void setDriverMode(uint32_t index, uint32_t mode) override;
|
||||
void setLinearMotorTarget(float x, float y, float z) override;
|
||||
void setLinearMotorVelocity(float x, float y, float z) override;
|
||||
void setLinearMotorForceLimit(float limit) override;
|
||||
|
||||
void setAngularMotorTarget(float x, float y, float z) override;
|
||||
void setAngularMotorVelocity(float x, float y, float z) override;
|
||||
void setAngularMotorForceLimit(float limit) override;
|
||||
|
||||
void setPivotA(float x, float y, float z) override;
|
||||
void setPivotB(float x, float y, float z) override;
|
||||
void setAutoPivotB(bool autoPivot) override;
|
||||
void setAxis(float x, float y, float z) override;
|
||||
void setSecondaryAxis(float x, float y, float z) override;
|
||||
|
||||
void setBreakForce(float force) override;
|
||||
void setBreakTorque(float torque) override;
|
||||
|
||||
void updateScale0() override;
|
||||
void updateScale1() override;
|
||||
|
||||
private:
|
||||
void onComponentSet() override;
|
||||
void updatePose();
|
||||
void updateLinearLimit();
|
||||
|
||||
void updateSwingLimit();
|
||||
void updateTwistLimit();
|
||||
|
||||
void updateDrive(uint32_t axis);
|
||||
void updateDrivePosition();
|
||||
void updateDriveVelocity();
|
||||
|
||||
physx::PxVec3 _mPivotA{physx::PxZero};
|
||||
physx::PxVec3 _mPivotB{physx::PxZero};
|
||||
bool _mAutoPivotB{false};
|
||||
physx::PxVec3 _mAxis{physx::PxZero};
|
||||
physx::PxVec3 _mSecondary{physx::PxZero};
|
||||
physx::PxVec3 _mTertiary{physx::PxZero};
|
||||
|
||||
float _breakForce{0.F};
|
||||
float _breakTorque{0.F};
|
||||
|
||||
struct {
|
||||
physx::PxD6Motion::Enum x, y, z;
|
||||
float lower[3];
|
||||
float upper[3];
|
||||
|
||||
bool soft;
|
||||
float stiffness;
|
||||
float damping;
|
||||
float restitution;
|
||||
float forceLimit;
|
||||
} _linearLimit;
|
||||
|
||||
struct {
|
||||
physx::PxD6Motion::Enum eTwist, eSwing, eSlerp;
|
||||
float swing1Extent, swing2Extent, twistExtent;
|
||||
|
||||
bool swingSoft, twistSoft;
|
||||
float swingStiffness;
|
||||
float swingDamping;
|
||||
float swingRestitution;
|
||||
float twistStiffness;
|
||||
float twistDamping;
|
||||
float twistRestitution;
|
||||
} _angularLimit;
|
||||
|
||||
struct {
|
||||
uint32_t xDrive;
|
||||
uint32_t yDrive;
|
||||
uint32_t zDrive;
|
||||
float forceLimit;
|
||||
physx::PxVec3 target;
|
||||
physx::PxVec3 velocity;
|
||||
} _linearMotor;
|
||||
|
||||
struct {
|
||||
uint32_t twistDrive;
|
||||
uint32_t swingDrive1;
|
||||
uint32_t swingDrive2;
|
||||
float forceLimit;
|
||||
physx::PxVec3 target;
|
||||
physx::PxVec3 velocity;
|
||||
} _angularMotor;
|
||||
};
|
||||
|
||||
} // namespace physics
|
||||
} // namespace cc
|
||||
129
cocos/physics/physx/joints/PhysXJoint.cpp
Normal file
129
cocos/physics/physx/joints/PhysXJoint.cpp
Normal file
@@ -0,0 +1,129 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#include "physics/physx/joints/PhysXJoint.h"
|
||||
#include "physics/physx/PhysXSharedBody.h"
|
||||
#include "physics/physx/PhysXUtils.h"
|
||||
#include "physics/physx/PhysXWorld.h"
|
||||
|
||||
namespace cc {
|
||||
namespace physics {
|
||||
|
||||
physx::PxRigidActor *PhysXJoint::tempRigidActor = nullptr;
|
||||
|
||||
PhysXJoint::PhysXJoint() {
|
||||
_mObjectID = PhysXWorld::getInstance().addWrapperObject(reinterpret_cast<uintptr_t>(this));
|
||||
};
|
||||
|
||||
void PhysXJoint::initialize(Node *node) {
|
||||
auto &ins = PhysXWorld::getInstance();
|
||||
_mSharedBody = ins.getSharedBody(node);
|
||||
_mSharedBody->reference(true);
|
||||
onComponentSet();
|
||||
}
|
||||
|
||||
void PhysXJoint::onEnable() {
|
||||
_mSharedBody->addJoint(*this, physx::PxJointActorIndex::eACTOR0);
|
||||
if (_mConnectedBody) {
|
||||
_mConnectedBody->addJoint(*this, physx::PxJointActorIndex::eACTOR1);
|
||||
_mJoint->setActors(_mSharedBody->getImpl().rigidActor, _mConnectedBody->getImpl().rigidActor);
|
||||
} else {
|
||||
_mJoint->setActors(_mSharedBody->getImpl().rigidActor, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
void PhysXJoint::onDisable() {
|
||||
_mJoint->setActors(&getTempRigidActor(), nullptr);
|
||||
_mSharedBody->removeJoint(*this, physx::PxJointActorIndex::eACTOR0);
|
||||
if (_mConnectedBody) _mConnectedBody->removeJoint(*this, physx::PxJointActorIndex::eACTOR1);
|
||||
}
|
||||
|
||||
void PhysXJoint::onDestroy() {
|
||||
_mSharedBody->reference(false);
|
||||
PhysXWorld::getInstance().removeWrapperObject(_mObjectID);
|
||||
}
|
||||
|
||||
void PhysXJoint::setConnectedBody(uint32_t rigidBodyID) {
|
||||
PhysXRigidBody *pxRigidBody = reinterpret_cast<PhysXRigidBody *>(PhysXWorld::getInstance().getWrapperPtrWithObjectID(rigidBodyID));
|
||||
if (pxRigidBody == nullptr)
|
||||
return;
|
||||
|
||||
|
||||
auto *oldConnectedBody = _mConnectedBody;
|
||||
if (oldConnectedBody) {
|
||||
oldConnectedBody->removeJoint(*this, physx::PxJointActorIndex::eACTOR1);
|
||||
}
|
||||
|
||||
uintptr_t nodePtr = reinterpret_cast<uintptr_t>(pxRigidBody->getSharedBody().getNode());
|
||||
if (nodePtr) {
|
||||
auto &ins = PhysXWorld::getInstance();
|
||||
_mConnectedBody = ins.getSharedBody(reinterpret_cast<Node *>(nodePtr));
|
||||
_mConnectedBody->addJoint(*this, physx::PxJointActorIndex::eACTOR1);
|
||||
} else {
|
||||
_mConnectedBody = nullptr;
|
||||
}
|
||||
if (_mJoint) {
|
||||
_mJoint->setActors(_mSharedBody->getImpl().rigidActor, _mConnectedBody ? _mConnectedBody->getImpl().rigidActor : nullptr);
|
||||
}
|
||||
|
||||
if (oldConnectedBody) {
|
||||
if (oldConnectedBody->isDynamic()) {
|
||||
oldConnectedBody->getImpl().rigidDynamic->wakeUp();
|
||||
}
|
||||
}
|
||||
|
||||
updateScale0();
|
||||
updateScale1();
|
||||
}
|
||||
|
||||
void PhysXJoint::setEnableCollision(const bool v) {
|
||||
_mEnableCollision = v;
|
||||
if (_mJoint) {
|
||||
_mJoint->setConstraintFlag(physx::PxConstraintFlag::eCOLLISION_ENABLED, _mEnableCollision);
|
||||
}
|
||||
}
|
||||
|
||||
void PhysXJoint::setEnableDebugVisualization(const bool v) {
|
||||
_mEnableDebugVisualization = v;
|
||||
if (_mJoint) {
|
||||
_mJoint->setConstraintFlag(physx::PxConstraintFlag::eVISUALIZATION, _mEnableDebugVisualization);
|
||||
}
|
||||
}
|
||||
|
||||
physx::PxRigidActor &PhysXJoint::getTempRigidActor() {
|
||||
if (!PhysXJoint::tempRigidActor) {
|
||||
PhysXJoint::tempRigidActor = PxGetPhysics().createRigidDynamic(physx::PxTransform{physx::PxIdentity});
|
||||
}
|
||||
return *PhysXJoint::tempRigidActor;
|
||||
};
|
||||
|
||||
void PhysXJoint::releaseTempRigidActor() {
|
||||
if (PhysXJoint::tempRigidActor) {
|
||||
PhysXJoint::tempRigidActor->release();
|
||||
PhysXJoint::tempRigidActor = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace physics
|
||||
} // namespace cc
|
||||
69
cocos/physics/physx/joints/PhysXJoint.h
Normal file
69
cocos/physics/physx/joints/PhysXJoint.h
Normal file
@@ -0,0 +1,69 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "base/Macros.h"
|
||||
#include "core/scene-graph/Node.h"
|
||||
#include "physics/physx/PhysXInc.h"
|
||||
#include "physics/spec/IJoint.h"
|
||||
|
||||
namespace cc {
|
||||
namespace physics {
|
||||
class PhysXSharedBody;
|
||||
|
||||
class PhysXJoint : virtual public IBaseJoint {
|
||||
PX_NOCOPY(PhysXJoint)
|
||||
|
||||
public:
|
||||
PhysXJoint();
|
||||
~PhysXJoint() override = default;
|
||||
void initialize(Node *node) override;
|
||||
void onEnable() override;
|
||||
void onDisable() override;
|
||||
void onDestroy() override;
|
||||
void setConnectedBody(uint32_t rigidBodyID) override;
|
||||
void setEnableCollision(bool v) override;
|
||||
void setEnableDebugVisualization(bool v);
|
||||
virtual void updateScale0() = 0;
|
||||
virtual void updateScale1() = 0;
|
||||
static physx::PxRigidActor &getTempRigidActor();
|
||||
static void releaseTempRigidActor();
|
||||
uint32_t getObjectID() const override { return _mObjectID; };
|
||||
|
||||
protected:
|
||||
physx::PxJoint *_mJoint{nullptr};
|
||||
PhysXSharedBody *_mSharedBody{nullptr};
|
||||
PhysXSharedBody *_mConnectedBody{nullptr};
|
||||
bool _mEnableCollision{false};
|
||||
bool _mEnableDebugVisualization{ false };
|
||||
virtual void onComponentSet() = 0;
|
||||
uint32_t _mObjectID{0};
|
||||
|
||||
private:
|
||||
static physx::PxRigidActor *tempRigidActor;
|
||||
};
|
||||
|
||||
} // namespace physics
|
||||
} // namespace cc
|
||||
181
cocos/physics/physx/joints/PhysXRevolute.cpp
Normal file
181
cocos/physics/physx/joints/PhysXRevolute.cpp
Normal file
@@ -0,0 +1,181 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#include "physics/physx/joints/PhysXRevolute.h"
|
||||
#include "math/Quaternion.h"
|
||||
#include "math/Utils.h"
|
||||
#include "math/Vec3.h"
|
||||
#include "physics/physx/PhysXSharedBody.h"
|
||||
#include "physics/physx/PhysXUtils.h"
|
||||
#include "physics/physx/PhysXWorld.h"
|
||||
|
||||
namespace cc {
|
||||
namespace physics {
|
||||
|
||||
void PhysXRevolute::onComponentSet() {
|
||||
_mJoint = PxRevoluteJointCreate(PxGetPhysics(), &getTempRigidActor(), physx::PxTransform{physx::PxIdentity}, nullptr, physx::PxTransform{physx::PxIdentity});
|
||||
_mlimit.stiffness = 0;
|
||||
_mlimit.damping = 0;
|
||||
_mlimit.restitution = 0.4;
|
||||
_mlimit.contactDistance = 0.01;
|
||||
|
||||
auto *joint = static_cast<physx::PxRevoluteJoint *>(_mJoint);
|
||||
joint->setConstraintFlag(physx::PxConstraintFlag::ePROJECTION, true);
|
||||
joint->setConstraintFlag(physx::PxConstraintFlag::eDRIVE_LIMITS_ARE_FORCES, true);
|
||||
joint->setProjectionAngularTolerance(0.2);
|
||||
joint->setProjectionLinearTolerance(0.2);
|
||||
|
||||
setEnableDebugVisualization(true);
|
||||
}
|
||||
|
||||
void PhysXRevolute::setPivotA(float x, float y, float z) {
|
||||
_mPivotA = physx::PxVec3{x, y, z};
|
||||
updatePose();
|
||||
}
|
||||
|
||||
void PhysXRevolute::setPivotB(float x, float y, float z) {
|
||||
_mPivotB = physx::PxVec3{x, y, z};
|
||||
updatePose();
|
||||
}
|
||||
|
||||
void PhysXRevolute::setAxis(float x, float y, float z) {
|
||||
_mAxis = physx::PxVec3{x, y, z};
|
||||
updatePose();
|
||||
}
|
||||
|
||||
void PhysXRevolute::setLimitEnabled(bool v) {
|
||||
_limitEnabled = v;
|
||||
auto *joint = static_cast<physx::PxRevoluteJoint *>(_mJoint);
|
||||
joint->setRevoluteJointFlag(physx::PxRevoluteJointFlag::eLIMIT_ENABLED, _limitEnabled);
|
||||
if (v) {
|
||||
joint->setLimit(_mlimit);
|
||||
}
|
||||
}
|
||||
|
||||
void PhysXRevolute::setLowerLimit(float v) {
|
||||
_lowerLimit = v;
|
||||
_mlimit.lower = mathutils::toRadian(_lowerLimit);
|
||||
if (_limitEnabled) {
|
||||
auto *joint = static_cast<physx::PxRevoluteJoint *>(_mJoint);
|
||||
joint->setLimit(_mlimit);
|
||||
}
|
||||
}
|
||||
|
||||
void PhysXRevolute::setUpperLimit(float v) {
|
||||
_upperLimit = v;
|
||||
_mlimit.upper = mathutils::toRadian(_upperLimit);
|
||||
if (_limitEnabled) {
|
||||
auto *joint = static_cast<physx::PxRevoluteJoint *>(_mJoint);
|
||||
joint->setLimit(_mlimit);
|
||||
}
|
||||
}
|
||||
|
||||
void PhysXRevolute::setMotorEnabled(bool v) {
|
||||
_motorEnabled = v;
|
||||
auto *joint = static_cast<physx::PxRevoluteJoint *>(_mJoint);
|
||||
joint->setRevoluteJointFlag(physx::PxRevoluteJointFlag::eDRIVE_ENABLED, _motorEnabled);
|
||||
if (v) {
|
||||
joint->setDriveVelocity(_motorVelocity / 60.0);
|
||||
joint->setDriveForceLimit(_motorForceLimit);
|
||||
}
|
||||
}
|
||||
|
||||
void PhysXRevolute::setMotorVelocity(float v) {
|
||||
_motorVelocity = v;
|
||||
if (_motorEnabled) {
|
||||
auto *joint = static_cast<physx::PxRevoluteJoint *>(_mJoint);
|
||||
joint->setDriveVelocity(_motorVelocity / 60.0);
|
||||
}
|
||||
}
|
||||
|
||||
void PhysXRevolute::setMotorForceLimit(float v) {
|
||||
_motorForceLimit = v;
|
||||
if (_motorEnabled) {
|
||||
auto *joint = static_cast<physx::PxRevoluteJoint *>(_mJoint);
|
||||
joint->setDriveForceLimit(_motorForceLimit);
|
||||
}
|
||||
}
|
||||
|
||||
void PhysXRevolute::updateScale0() {
|
||||
updatePose();
|
||||
}
|
||||
|
||||
void PhysXRevolute::updateScale1() {
|
||||
updatePose();
|
||||
}
|
||||
|
||||
void PhysXRevolute::updatePose() {
|
||||
physx::PxTransform pose0{physx::PxIdentity};
|
||||
physx::PxTransform pose1{physx::PxIdentity};
|
||||
|
||||
auto xAxis = _mAxis.getNormalized();
|
||||
auto yAxis = physx::PxVec3(0, 1, 0);
|
||||
auto zAxis = _mAxis.cross(yAxis);
|
||||
if (zAxis.magnitude() < 0.0001) {
|
||||
yAxis = physx::PxVec3(0, 0, 1).cross(xAxis);
|
||||
zAxis = xAxis.cross(yAxis);
|
||||
} else {
|
||||
yAxis = zAxis.cross(xAxis);
|
||||
}
|
||||
|
||||
yAxis = yAxis.getNormalized();
|
||||
zAxis = zAxis.getNormalized();
|
||||
|
||||
Mat4 transform(
|
||||
xAxis.x, xAxis.y, xAxis.z, 0,
|
||||
yAxis.x, yAxis.y, yAxis.z, 0,
|
||||
zAxis.x, zAxis.y, zAxis.z, 0,
|
||||
0.F, 0.F, 0.F, 1.F);
|
||||
|
||||
auto quat = Quaternion();
|
||||
transform.getRotation(&quat);
|
||||
|
||||
// pos and rot in with respect to bodyA
|
||||
auto *node0 = _mSharedBody->getNode();
|
||||
node0->updateWorldTransform();
|
||||
pose0.p = _mPivotA * node0->getWorldScale();
|
||||
pose0.q = physx::PxQuat(quat.x, quat.y, quat.z, quat.w);
|
||||
_mJoint->setLocalPose(physx::PxJointActorIndex::eACTOR0, pose0);
|
||||
|
||||
if (_mConnectedBody) {
|
||||
auto *node1 = _mConnectedBody->getNode();
|
||||
node1->updateWorldTransform();
|
||||
pose1.p = _mPivotB * node1->getWorldScale();
|
||||
const auto &rot_0 = node0->getWorldRotation();
|
||||
const auto &rot_1_i = node1->getWorldRotation().getInversed();
|
||||
pose1.q = physx::PxQuat(rot_1_i.x, rot_1_i.y, rot_1_i.z, rot_1_i.w) * physx::PxQuat(rot_0.x, rot_0.y, rot_0.z, rot_0.w) * pose0.q;
|
||||
} else {
|
||||
const auto &wr = node0->getWorldRotation();
|
||||
auto pos = Vec3(_mPivotA.x, _mPivotA.y, _mPivotA.z);
|
||||
pos.multiply(node0->getWorldScale());
|
||||
pos.transformQuat(node0->getWorldRotation());
|
||||
pos.add(node0->getWorldPosition());
|
||||
pose1.p = physx::PxVec3(pos.x, pos.y, pos.z);
|
||||
pose1.q = physx::PxQuat{wr.x, wr.y, wr.z, wr.w} * pose0.q;
|
||||
}
|
||||
_mJoint->setLocalPose(physx::PxJointActorIndex::eACTOR1, pose1);
|
||||
}
|
||||
|
||||
} // namespace physics
|
||||
} // namespace cc
|
||||
67
cocos/physics/physx/joints/PhysXRevolute.h
Normal file
67
cocos/physics/physx/joints/PhysXRevolute.h
Normal file
@@ -0,0 +1,67 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "physics/physx/joints/PhysXJoint.h"
|
||||
|
||||
namespace cc {
|
||||
namespace physics {
|
||||
|
||||
class PhysXRevolute final : public PhysXJoint, public IRevoluteJoint {
|
||||
public:
|
||||
PhysXRevolute() : _mPivotA(physx::PxZero),
|
||||
_mPivotB(physx::PxZero),
|
||||
_mAxis(physx::PxZero) {}
|
||||
~PhysXRevolute() override = default;
|
||||
void setPivotA(float x, float y, float z) override;
|
||||
void setPivotB(float x, float y, float z) override;
|
||||
void setAxis(float x, float y, float z) override;
|
||||
void setLimitEnabled(bool v) override;
|
||||
void setLowerLimit(float v) override;
|
||||
void setUpperLimit(float v) override;
|
||||
void setMotorEnabled(bool v) override;
|
||||
void setMotorVelocity(float v) override;
|
||||
void setMotorForceLimit(float v) override;
|
||||
void updateScale0() override;
|
||||
void updateScale1() override;
|
||||
|
||||
private:
|
||||
void onComponentSet() override;
|
||||
void updatePose();
|
||||
physx::PxVec3 _mPivotA;
|
||||
physx::PxVec3 _mPivotB;
|
||||
physx::PxVec3 _mAxis;
|
||||
physx::PxJointAngularLimitPair _mlimit{0, 0};
|
||||
|
||||
bool _limitEnabled{false};
|
||||
float _lowerLimit{0.0F};
|
||||
float _upperLimit{0.0F};
|
||||
bool _motorEnabled{false};
|
||||
float _motorVelocity{0.0F};
|
||||
float _motorForceLimit{0.0F};
|
||||
};
|
||||
|
||||
} // namespace physics
|
||||
} // namespace cc
|
||||
80
cocos/physics/physx/joints/PhysXSpherical.cpp
Normal file
80
cocos/physics/physx/joints/PhysXSpherical.cpp
Normal file
@@ -0,0 +1,80 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#include "physics/physx/joints/PhysXSpherical.h"
|
||||
#include "math/Quaternion.h"
|
||||
#include "physics/physx/PhysXSharedBody.h"
|
||||
#include "physics/physx/PhysXUtils.h"
|
||||
|
||||
namespace cc {
|
||||
namespace physics {
|
||||
|
||||
void PhysXSpherical::onComponentSet() {
|
||||
_mJoint = PxSphericalJointCreate(PxGetPhysics(), &getTempRigidActor(), physx::PxTransform{physx::PxIdentity}, nullptr, physx::PxTransform{physx::PxIdentity});
|
||||
setEnableDebugVisualization(true);
|
||||
}
|
||||
|
||||
void PhysXSpherical::setPivotA(float x, float y, float z) {
|
||||
_mPivotA = physx::PxVec3{x, y, z};
|
||||
updatePose();
|
||||
}
|
||||
|
||||
void PhysXSpherical::setPivotB(float x, float y, float z) {
|
||||
_mPivotB = physx::PxVec3{x, y, z};
|
||||
updatePose();
|
||||
}
|
||||
|
||||
void PhysXSpherical::updateScale0() {
|
||||
updatePose();
|
||||
}
|
||||
|
||||
void PhysXSpherical::updateScale1() {
|
||||
updatePose();
|
||||
}
|
||||
|
||||
void PhysXSpherical::updatePose() {
|
||||
physx::PxTransform pose0{physx::PxIdentity};
|
||||
physx::PxTransform pose1{physx::PxIdentity};
|
||||
auto *node0 = _mSharedBody->getNode();
|
||||
node0->updateWorldTransform();
|
||||
pose0.p = _mPivotA * node0->getWorldScale();
|
||||
_mJoint->setLocalPose(physx::PxJointActorIndex::eACTOR0, pose0);
|
||||
if (_mConnectedBody) {
|
||||
auto *node1 = _mConnectedBody->getNode();
|
||||
node1->updateWorldTransform();
|
||||
pose1.p = _mPivotB * node1->getWorldScale();
|
||||
} else {
|
||||
const auto &wr = node0->getWorldRotation();
|
||||
auto pos = Vec3(_mPivotA.x, _mPivotA.y, _mPivotA.z);
|
||||
pos.multiply(node0->getWorldScale());
|
||||
pos.transformQuat(node0->getWorldRotation());
|
||||
pos.add(node0->getWorldPosition());
|
||||
pose1.p = physx::PxVec3(pos.x, pos.y, pos.z);
|
||||
pose1.q = physx::PxQuat{wr.x, wr.y, wr.z, wr.w} * pose0.q;
|
||||
}
|
||||
_mJoint->setLocalPose(physx::PxJointActorIndex::eACTOR1, pose1);
|
||||
}
|
||||
|
||||
} // namespace physics
|
||||
} // namespace cc
|
||||
51
cocos/physics/physx/joints/PhysXSpherical.h
Normal file
51
cocos/physics/physx/joints/PhysXSpherical.h
Normal file
@@ -0,0 +1,51 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "physics/physx/joints/PhysXJoint.h"
|
||||
|
||||
namespace cc {
|
||||
namespace physics {
|
||||
|
||||
class PhysXSpherical final : public PhysXJoint, public ISphericalJoint {
|
||||
public:
|
||||
PhysXSpherical() : _mPivotA(physx::PxZero),
|
||||
_mPivotB(physx::PxZero){};
|
||||
|
||||
~PhysXSpherical() override = default;
|
||||
void setPivotA(float x, float y, float z) override;
|
||||
void setPivotB(float x, float y, float z) override;
|
||||
void updateScale0() override;
|
||||
void updateScale1() override;
|
||||
|
||||
private:
|
||||
void onComponentSet() override;
|
||||
void updatePose();
|
||||
physx::PxVec3 _mPivotA;
|
||||
physx::PxVec3 _mPivotB;
|
||||
};
|
||||
|
||||
} // namespace physics
|
||||
} // namespace cc
|
||||
Reference in New Issue
Block a user