no message
This commit is contained in:
31
cocos/physics/PhysicsSDK.h
Normal file
31
cocos/physics/PhysicsSDK.h
Normal file
@@ -0,0 +1,31 @@
|
||||
/****************************************************************************
|
||||
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/sdk/Joint.h"
|
||||
#include "physics/sdk/RigidBody.h"
|
||||
#include "physics/sdk/Shape.h"
|
||||
#include "physics/sdk/World.h"
|
||||
#include "physics/sdk/CharacterController.h"
|
||||
47
cocos/physics/PhysicsSelector.h
Normal file
47
cocos/physics/PhysicsSelector.h
Normal file
@@ -0,0 +1,47 @@
|
||||
/****************************************************************************
|
||||
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
|
||||
|
||||
#if defined(USE_PHYSICS_BULLET)
|
||||
#include "physics/bullet/Bullet.h"
|
||||
#else
|
||||
#include "physics/physx/PhysX.h"
|
||||
#define WrappedWorld PhysXWorld
|
||||
#define WrappedRigidBody PhysXRigidBody
|
||||
#define WrappedSphereShape PhysXSphere
|
||||
#define WrappedBoxShape PhysXBox
|
||||
#define WrappedPlaneShape PhysXPlane
|
||||
#define WrappedCapsuleShape PhysXCapsule
|
||||
#define WrappedTrimeshShape PhysXTrimesh
|
||||
#define WrappedTerrainShape PhysXTerrain
|
||||
#define WrappedConeShape PhysXCone
|
||||
#define WrappedCylinderShape PhysXCylinder
|
||||
#define WrappedRevoluteJoint PhysXRevolute
|
||||
#define WrappedFixedJoint PhysXFixedJoint
|
||||
#define WrappedSphericalJoint PhysXSpherical
|
||||
#define WrappedGenericJoint PhysXGenericJoint
|
||||
#define WrappedCapsuleCharacterController PhysXCapsuleCharacterController
|
||||
#define WrappedBoxCharacterController PhysXBoxCharacterController
|
||||
#endif
|
||||
46
cocos/physics/physx/PhysX.h
Normal file
46
cocos/physics/physx/PhysX.h
Normal file
@@ -0,0 +1,46 @@
|
||||
/****************************************************************************
|
||||
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/PhysXWorld.h"
|
||||
|
||||
#include "physics/physx/PhysXRigidBody.h"
|
||||
|
||||
#include "physics/physx/shapes/PhysXBox.h"
|
||||
#include "physics/physx/shapes/PhysXCapsule.h"
|
||||
#include "physics/physx/shapes/PhysXCone.h"
|
||||
#include "physics/physx/shapes/PhysXCylinder.h"
|
||||
#include "physics/physx/shapes/PhysXPlane.h"
|
||||
#include "physics/physx/shapes/PhysXSphere.h"
|
||||
#include "physics/physx/shapes/PhysXTerrain.h"
|
||||
#include "physics/physx/shapes/PhysXTrimesh.h"
|
||||
|
||||
#include "physics/physx/joints/PhysXFixedJoint.h"
|
||||
#include "physics/physx/joints/PhysXGenericJoint.h"
|
||||
#include "physics/physx/joints/PhysXRevolute.h"
|
||||
#include "physics/physx/joints/PhysXSpherical.h"
|
||||
|
||||
#include "physics/physx/character-controllers/PhysXBoxCharacterController.h"
|
||||
#include "physics/physx/character-controllers/PhysXCapsuleCharacterController.h"
|
||||
195
cocos/physics/physx/PhysXEventManager.cpp
Normal file
195
cocos/physics/physx/PhysXEventManager.cpp
Normal file
@@ -0,0 +1,195 @@
|
||||
/****************************************************************************
|
||||
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/PhysXEventManager.h"
|
||||
#include <algorithm>
|
||||
#include "physics/physx/PhysXInc.h"
|
||||
#include "physics/physx/PhysXUtils.h"
|
||||
#include "physics/physx/PhysXWorld.h"
|
||||
#include "physics/physx/shapes/PhysXShape.h"
|
||||
|
||||
namespace cc {
|
||||
namespace physics {
|
||||
|
||||
void PhysXEventManager::SimulationEventCallback::onTrigger(physx::PxTriggerPair *pairs, physx::PxU32 count) {
|
||||
for (physx::PxU32 i = 0; i < count; i++) {
|
||||
const physx::PxTriggerPair &triggerPair = pairs[i];
|
||||
if (triggerPair.flags & (physx::PxTriggerPairFlag::eREMOVED_SHAPE_TRIGGER | physx::PxTriggerPairFlag::eREMOVED_SHAPE_OTHER)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
bool processed = false;
|
||||
|
||||
//collider trigger event
|
||||
if (!processed) {
|
||||
const auto &selfIter = getPxShapeMap().find(reinterpret_cast<uintptr_t>(triggerPair.triggerShape));
|
||||
const auto &otherIter = getPxShapeMap().find(reinterpret_cast<uintptr_t>(triggerPair.otherShape));
|
||||
if (selfIter != getPxShapeMap().end() && otherIter != getPxShapeMap().end()) {
|
||||
processed = true;
|
||||
const auto &self = selfIter->second;
|
||||
const auto &other = otherIter->second;
|
||||
auto &pairs = mManager->getTriggerPairs();
|
||||
const auto &iter = std::find_if(pairs.begin(), pairs.end(), [self, other](std::shared_ptr<TriggerEventPair> &pair) {
|
||||
return (pair->shapeA == self || pair->shapeA == other) && (pair->shapeB == self || pair->shapeB == other);
|
||||
});
|
||||
if (triggerPair.status & physx::PxPairFlag::eNOTIFY_TOUCH_FOUND) {
|
||||
if (iter == pairs.end()) pairs.push_back(std::shared_ptr<TriggerEventPair>(ccnew TriggerEventPair{self, other}));
|
||||
} else if (triggerPair.status & physx::PxPairFlag::eNOTIFY_TOUCH_LOST) {
|
||||
if (iter != pairs.end()) iter->get()->state = ETouchState::EXIT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//cct trigger event
|
||||
if (!processed) {
|
||||
const auto &shapeIter = getPxShapeMap().find(reinterpret_cast<uintptr_t>(triggerPair.triggerShape));
|
||||
const auto &cctIter = getPxCCTMap().find(reinterpret_cast<uintptr_t>(triggerPair.otherShape));
|
||||
if (shapeIter != getPxShapeMap().end() && cctIter != getPxCCTMap().end()) {
|
||||
processed = true;
|
||||
const auto &shape = shapeIter->second;
|
||||
const auto &cct = cctIter->second;
|
||||
auto &pairs = mManager->getCCTTriggerPairs();
|
||||
const auto &iter = std::find_if(pairs.begin(), pairs.end(), [shape, cct](std::shared_ptr<CCTTriggerEventPair> &pair) {
|
||||
return (pair->shape == shape && pair->cct == cct);
|
||||
});
|
||||
if (triggerPair.status & physx::PxPairFlag::eNOTIFY_TOUCH_FOUND) {
|
||||
if (iter == pairs.end()) pairs.push_back(std::shared_ptr<CCTTriggerEventPair>(ccnew CCTTriggerEventPair{cct, shape}));
|
||||
} else if (triggerPair.status & physx::PxPairFlag::eNOTIFY_TOUCH_LOST) {
|
||||
if (iter != pairs.end()) iter->get()->state = ETouchState::EXIT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//cct trigger event
|
||||
if (!processed) {
|
||||
const auto &cctIter = getPxCCTMap().find(reinterpret_cast<uintptr_t>(triggerPair.triggerShape));
|
||||
const auto &shapeIter = getPxShapeMap().find(reinterpret_cast<uintptr_t>(triggerPair.otherShape));
|
||||
if (shapeIter != getPxShapeMap().end() && cctIter != getPxCCTMap().end()) {
|
||||
processed = true;
|
||||
const auto &shape = shapeIter->second;
|
||||
const auto &cct = cctIter->second;
|
||||
auto &pairs = mManager->getCCTTriggerPairs();
|
||||
const auto &iter = std::find_if(pairs.begin(), pairs.end(), [shape, cct](std::shared_ptr<CCTTriggerEventPair> &pair) {
|
||||
return (pair->shape == shape && pair->cct == cct);
|
||||
});
|
||||
if (triggerPair.status & physx::PxPairFlag::eNOTIFY_TOUCH_FOUND) {
|
||||
if (iter == pairs.end()) pairs.push_back(std::shared_ptr<CCTTriggerEventPair>(ccnew CCTTriggerEventPair{cct, shape}));
|
||||
} else if (triggerPair.status & physx::PxPairFlag::eNOTIFY_TOUCH_LOST) {
|
||||
if (iter != pairs.end()) iter->get()->state = ETouchState::EXIT;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PhysXEventManager::SimulationEventCallback::onContact(const physx::PxContactPairHeader & /*header*/, const physx::PxContactPair *pairs, physx::PxU32 count) {
|
||||
for (physx::PxU32 i = 0; i < count; i++) {
|
||||
const physx::PxContactPair &cp = pairs[i];
|
||||
if (cp.flags & (physx::PxContactPairFlag::eREMOVED_SHAPE_0 | physx::PxContactPairFlag::eREMOVED_SHAPE_1)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto &selfIter = getPxShapeMap().find(reinterpret_cast<uintptr_t>(cp.shapes[0]));
|
||||
const auto &otherIter = getPxShapeMap().find(reinterpret_cast<uintptr_t>(cp.shapes[1]));
|
||||
if (selfIter == getPxShapeMap().end() || otherIter == getPxShapeMap().end()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto &self = selfIter->second;
|
||||
const auto &other = otherIter->second;
|
||||
auto &pairs = mManager->getConatctPairs();
|
||||
auto iter = std::find_if(pairs.begin(), pairs.end(), [self, other](std::shared_ptr<ContactEventPair> &pair) {
|
||||
return (pair->shapeA == self || pair->shapeA == other) && (pair->shapeB == self || pair->shapeB == other);
|
||||
});
|
||||
|
||||
if (iter == pairs.end()) {
|
||||
pairs.push_back(std::shared_ptr<ContactEventPair>(ccnew ContactEventPair{self, other}));
|
||||
iter = pairs.end() - 1;
|
||||
}
|
||||
|
||||
if (cp.events & physx::PxPairFlag::eNOTIFY_TOUCH_PERSISTS) {
|
||||
iter->get()->state = ETouchState::STAY;
|
||||
} else if (cp.events & physx::PxPairFlag::eNOTIFY_TOUCH_FOUND) {
|
||||
iter->get()->state = ETouchState::ENTER;
|
||||
} else if (cp.events & physx::PxPairFlag::eNOTIFY_TOUCH_LOST) {
|
||||
iter->get()->state = ETouchState::EXIT;
|
||||
}
|
||||
|
||||
const physx::PxU8 &contactCount = cp.contactCount;
|
||||
iter->get()->contacts.resize(contactCount);
|
||||
if (contactCount > 0) {
|
||||
cp.extractContacts(reinterpret_cast<physx::PxContactPairPoint *>(&iter->get()->contacts[0]), contactCount);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PhysXEventManager::refreshPairs() {
|
||||
for (auto iter = getTriggerPairs().begin(); iter != getTriggerPairs().end();) {
|
||||
uintptr_t wrapperPtrShapeA = PhysXWorld::getInstance().getWrapperPtrWithObjectID(iter->get()->shapeA);
|
||||
uintptr_t wrapperPtrShapeB = PhysXWorld::getInstance().getWrapperPtrWithObjectID(iter->get()->shapeB);
|
||||
if (wrapperPtrShapeA == 0 || wrapperPtrShapeB == 0) {
|
||||
iter = getTriggerPairs().erase(iter);
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto &selfIter = getPxShapeMap().find(reinterpret_cast<uintptr_t>(&(reinterpret_cast<PhysXShape *>(wrapperPtrShapeA)->getShape())));
|
||||
const auto &otherIter = getPxShapeMap().find(reinterpret_cast<uintptr_t>(&(reinterpret_cast<PhysXShape *>(wrapperPtrShapeB)->getShape())));
|
||||
if (selfIter == getPxShapeMap().end() || otherIter == getPxShapeMap().end()) {
|
||||
iter = getTriggerPairs().erase(iter);
|
||||
} else if (iter->get()->state == ETouchState::EXIT) {
|
||||
iter = getTriggerPairs().erase(iter);
|
||||
} else {
|
||||
iter->get()->state = ETouchState::STAY;
|
||||
iter++;
|
||||
}
|
||||
}
|
||||
|
||||
for (auto iter = getCCTTriggerPairs().begin(); iter != getCCTTriggerPairs().end();) {
|
||||
uintptr_t wrapperPtrCCT = PhysXWorld::getInstance().getWrapperPtrWithObjectID(iter->get()->cct);
|
||||
uintptr_t wrapperPtrShape = PhysXWorld::getInstance().getWrapperPtrWithObjectID(iter->get()->shape);
|
||||
if (wrapperPtrCCT == 0 || wrapperPtrShape == 0) {
|
||||
iter = getCCTTriggerPairs().erase(iter);
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto& cctIter = getPxCCTMap().find(reinterpret_cast<uintptr_t>(&(reinterpret_cast<PhysXCharacterController*>(wrapperPtrCCT)->getCCT())));
|
||||
const auto& shapeIter = getPxShapeMap().find(reinterpret_cast<uintptr_t>(&(reinterpret_cast<PhysXShape*>(wrapperPtrShape)->getShape())));
|
||||
if (cctIter == getPxCCTMap().end() || shapeIter == getPxShapeMap().end()) {
|
||||
iter = getCCTTriggerPairs().erase(iter);
|
||||
}
|
||||
else if (iter->get()->state == ETouchState::EXIT) {
|
||||
iter = getCCTTriggerPairs().erase(iter);
|
||||
}
|
||||
else {
|
||||
iter->get()->state = ETouchState::STAY;
|
||||
iter++;
|
||||
}
|
||||
}
|
||||
|
||||
getConatctPairs().clear();
|
||||
getCCTShapePairs().clear();
|
||||
}
|
||||
|
||||
} // namespace physics
|
||||
} // namespace cc
|
||||
76
cocos/physics/physx/PhysXEventManager.h
Normal file
76
cocos/physics/physx/PhysXEventManager.h
Normal file
@@ -0,0 +1,76 @@
|
||||
/****************************************************************************
|
||||
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 <memory>
|
||||
#include "base/Macros.h"
|
||||
#include "base/memory/Memory.h"
|
||||
#include "base/std/container/vector.h"
|
||||
#include "physics/physx/PhysXInc.h"
|
||||
#include "physics/spec/IWorld.h"
|
||||
|
||||
namespace cc {
|
||||
namespace physics {
|
||||
|
||||
class PhysXEventManager final {
|
||||
public:
|
||||
PhysXEventManager() {
|
||||
_mCallback = ccnew SimulationEventCallback(this);
|
||||
}
|
||||
|
||||
~PhysXEventManager() {
|
||||
delete _mCallback;
|
||||
}
|
||||
|
||||
struct SimulationEventCallback : public physx::PxSimulationEventCallback {
|
||||
void onConstraintBreak(physx::PxConstraintInfo * /*constraints*/, physx::PxU32 /*count*/) override{};
|
||||
void onWake(physx::PxActor ** /*actors*/, physx::PxU32 /*count*/) override{};
|
||||
void onSleep(physx::PxActor ** /*actors*/, physx::PxU32 /*count*/) override{};
|
||||
void onTrigger(physx::PxTriggerPair * /*pairs*/, physx::PxU32 /*count*/) override;
|
||||
void onContact(const physx::PxContactPairHeader & /*pairHeader*/, const physx::PxContactPair * /*pairs*/, physx::PxU32 /*nbPairs*/) override;
|
||||
void onAdvance(const physx::PxRigidBody *const * /*bodyBuffer*/, const physx::PxTransform * /*poseBuffer*/, const physx::PxU32 /*count*/) override{};
|
||||
PhysXEventManager *mManager;
|
||||
|
||||
public:
|
||||
explicit SimulationEventCallback(PhysXEventManager *m) : mManager(m) {}
|
||||
};
|
||||
|
||||
inline SimulationEventCallback &getEventCallback() { return *_mCallback; }
|
||||
inline ccstd::vector<std::shared_ptr<TriggerEventPair>> &getTriggerPairs() { return _mTriggerPairs; }
|
||||
inline ccstd::vector<std::shared_ptr<ContactEventPair>>& getConatctPairs() { return _mConatctPairs; }
|
||||
inline ccstd::vector<std::shared_ptr<CCTShapeEventPair>>& getCCTShapePairs() { return _mCCTShapePairs; }
|
||||
inline ccstd::vector<std::shared_ptr<CCTTriggerEventPair>> &getCCTTriggerPairs() { return _mCCTTriggerPairs; }
|
||||
void refreshPairs();
|
||||
|
||||
private:
|
||||
ccstd::vector<std::shared_ptr<TriggerEventPair>> _mTriggerPairs;
|
||||
ccstd::vector<std::shared_ptr<ContactEventPair>> _mConatctPairs;
|
||||
ccstd::vector<std::shared_ptr<CCTShapeEventPair>> _mCCTShapePairs;
|
||||
ccstd::vector<std::shared_ptr<CCTTriggerEventPair>> _mCCTTriggerPairs;
|
||||
SimulationEventCallback *_mCallback;
|
||||
};
|
||||
|
||||
} // namespace physics
|
||||
} // namespace cc
|
||||
114
cocos/physics/physx/PhysXFilterShader.cpp
Normal file
114
cocos/physics/physx/PhysXFilterShader.cpp
Normal file
@@ -0,0 +1,114 @@
|
||||
/****************************************************************************
|
||||
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/PhysXFilterShader.h"
|
||||
#include "physics/physx/PhysXInc.h"
|
||||
|
||||
namespace cc {
|
||||
namespace physics {
|
||||
|
||||
physx::PxFilterFlags simpleFilterShader(
|
||||
physx::PxFilterObjectAttributes attributes0, physx::PxFilterData fd0,
|
||||
physx::PxFilterObjectAttributes attributes1, physx::PxFilterData fd1,
|
||||
physx::PxPairFlags &pairFlags, const void *constantBlock, physx::PxU32 constantBlockSize) {
|
||||
PX_UNUSED(constantBlock);
|
||||
PX_UNUSED(constantBlockSize);
|
||||
// group mask filter
|
||||
if (!(fd0.word0 & fd1.word1) || !(fd0.word1 & fd1.word0)) {
|
||||
return physx::PxFilterFlag::eSUPPRESS;
|
||||
}
|
||||
|
||||
if (physx::PxFilterObjectIsTrigger(attributes0) || physx::PxFilterObjectIsTrigger(attributes1)) {
|
||||
pairFlags |= physx::PxPairFlag::eTRIGGER_DEFAULT | physx::PxPairFlag::eNOTIFY_TOUCH_CCD;
|
||||
return physx::PxFilterFlag::eDEFAULT;
|
||||
}
|
||||
if (!physx::PxFilterObjectIsKinematic(attributes0) || !physx::PxFilterObjectIsKinematic(attributes1)) {
|
||||
pairFlags |= physx::PxPairFlag::eSOLVE_CONTACT;
|
||||
}
|
||||
pairFlags |= physx::PxPairFlag::eDETECT_DISCRETE_CONTACT |
|
||||
physx::PxPairFlag::eNOTIFY_TOUCH_FOUND | physx::PxPairFlag::eNOTIFY_TOUCH_LOST | physx::PxPairFlag::eNOTIFY_TOUCH_PERSISTS |
|
||||
physx::PxPairFlag::eDETECT_CCD_CONTACT | physx::PxPairFlag::eNOTIFY_CONTACT_POINTS;
|
||||
return physx::PxFilterFlag::eDEFAULT;
|
||||
}
|
||||
|
||||
physx::PxFilterFlags advanceFilterShader(
|
||||
physx::PxFilterObjectAttributes attributes0, physx::PxFilterData fd0,
|
||||
physx::PxFilterObjectAttributes attributes1, physx::PxFilterData fd1,
|
||||
physx::PxPairFlags &pairFlags, const void *constantBlock, physx::PxU32 constantBlockSize) {
|
||||
PX_UNUSED(constantBlock);
|
||||
PX_UNUSED(constantBlockSize);
|
||||
// group mask filter
|
||||
if (!(fd0.word0 & fd1.word1) || !(fd0.word1 & fd1.word0)) {
|
||||
return physx::PxFilterFlag::eSUPPRESS;
|
||||
}
|
||||
|
||||
pairFlags = physx::PxPairFlags(0);
|
||||
|
||||
// trigger filter
|
||||
if (physx::PxFilterObjectIsTrigger(attributes0) || physx::PxFilterObjectIsTrigger(attributes1)) {
|
||||
pairFlags |= physx::PxPairFlag::eDETECT_DISCRETE_CONTACT;
|
||||
|
||||
// need trigger event?
|
||||
const physx::PxU16 needTriggerEvent = (fd0.word3 & DETECT_TRIGGER_EVENT) | (fd1.word3 & DETECT_TRIGGER_EVENT);
|
||||
if (needTriggerEvent) {
|
||||
pairFlags |= physx::PxPairFlag::eNOTIFY_TOUCH_FOUND | physx::PxPairFlag::eNOTIFY_TOUCH_LOST;
|
||||
return physx::PxFilterFlag::eDEFAULT;
|
||||
}
|
||||
return physx::PxFilterFlag::eSUPPRESS;
|
||||
}
|
||||
|
||||
// need detect ccd contact?
|
||||
const physx::PxU16 needDetectCCD = (fd0.word3 & DETECT_CONTACT_CCD) | (fd1.word3 & DETECT_CONTACT_CCD);
|
||||
if (needDetectCCD) pairFlags |= physx::PxPairFlag::eDETECT_CCD_CONTACT;
|
||||
|
||||
if (!physx::PxFilterObjectIsKinematic(attributes0) || !physx::PxFilterObjectIsKinematic(attributes1)) {
|
||||
pairFlags |= physx::PxPairFlag::eSOLVE_CONTACT;
|
||||
}
|
||||
|
||||
// simple collision process
|
||||
pairFlags |= physx::PxPairFlag::eDETECT_DISCRETE_CONTACT;
|
||||
|
||||
// need contact event?
|
||||
const physx::PxU16 needContactEvent = (fd0.word3 & DETECT_CONTACT_EVENT) | (fd1.word3 & DETECT_CONTACT_EVENT);
|
||||
if (needContactEvent) pairFlags |= physx::PxPairFlag::eNOTIFY_TOUCH_FOUND | physx::PxPairFlag::eNOTIFY_TOUCH_LOST | physx::PxPairFlag::eNOTIFY_TOUCH_PERSISTS;
|
||||
|
||||
// need contact point?
|
||||
const physx::PxU16 needContactPoint = (fd0.word3 & DETECT_CONTACT_POINT) | (fd1.word3 & DETECT_CONTACT_POINT);
|
||||
if (needContactPoint) pairFlags |= physx::PxPairFlag::eNOTIFY_CONTACT_POINTS;
|
||||
|
||||
return physx::PxFilterFlag::eDEFAULT;
|
||||
}
|
||||
|
||||
physx::PxQueryHitType::Enum QueryFilterShader::preFilter(const physx::PxFilterData &filterData, const physx::PxShape *shape,
|
||||
const physx::PxRigidActor *actor, physx::PxHitFlags &queryFlags) {
|
||||
PX_UNUSED(actor);
|
||||
PX_UNUSED(queryFlags);
|
||||
if ((filterData.word3 & QUERY_CHECK_TRIGGER) && shape->getFlags().isSet(physx::PxShapeFlag::eTRIGGER_SHAPE)) {
|
||||
return physx::PxQueryHitType::eNONE;
|
||||
}
|
||||
return filterData.word3 & QUERY_SINGLE_HIT ? physx::PxQueryHitType::eBLOCK : physx::PxQueryHitType::eTOUCH;
|
||||
}
|
||||
|
||||
} // namespace physics
|
||||
} // namespace cc
|
||||
62
cocos/physics/physx/PhysXFilterShader.h
Normal file
62
cocos/physics/physx/PhysXFilterShader.h
Normal file
@@ -0,0 +1,62 @@
|
||||
/****************************************************************************
|
||||
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/PhysXInc.h"
|
||||
|
||||
namespace cc {
|
||||
namespace physics {
|
||||
|
||||
constexpr physx::PxU32 QUERY_FILTER = 1 << 0;
|
||||
constexpr physx::PxU32 QUERY_CHECK_TRIGGER = 1 << 1;
|
||||
constexpr physx::PxU32 QUERY_SINGLE_HIT = 1 << 2;
|
||||
constexpr physx::PxU32 DETECT_TRIGGER_EVENT = 1 << 3;
|
||||
constexpr physx::PxU32 DETECT_CONTACT_EVENT = 1 << 4;
|
||||
constexpr physx::PxU32 DETECT_CONTACT_POINT = 1 << 5;
|
||||
constexpr physx::PxU32 DETECT_CONTACT_CCD = 1 << 6;
|
||||
|
||||
physx::PxFilterFlags simpleFilterShader(
|
||||
physx::PxFilterObjectAttributes attributes0, physx::PxFilterData fd0,
|
||||
physx::PxFilterObjectAttributes attributes1, physx::PxFilterData fd1,
|
||||
physx::PxPairFlags &pairFlags, const void *constantBlock, physx::PxU32 constantBlockSize);
|
||||
|
||||
physx::PxFilterFlags advanceFilterShader(
|
||||
physx::PxFilterObjectAttributes attributes0, physx::PxFilterData fd0,
|
||||
physx::PxFilterObjectAttributes attributes1, physx::PxFilterData fd1,
|
||||
physx::PxPairFlags &pairFlags, const void *constantBlock, physx::PxU32 constantBlockSize);
|
||||
|
||||
class QueryFilterShader : public physx::PxSceneQueryFilterCallback {
|
||||
public:
|
||||
physx::PxQueryHitType::Enum preFilter(const physx::PxFilterData &filterData, const physx::PxShape *shape,
|
||||
const physx::PxRigidActor *actor, physx::PxHitFlags &queryFlags) override;
|
||||
physx::PxQueryHitType::Enum postFilter(const physx::PxFilterData &filterData, const physx::PxQueryHit &hit) override {
|
||||
PX_UNUSED(filterData);
|
||||
PX_UNUSED(hit);
|
||||
return physx::PxQueryHitType::eNONE;
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace physics
|
||||
} // namespace cc
|
||||
45
cocos/physics/physx/PhysXInc.h
Normal file
45
cocos/physics/physx/PhysXInc.h
Normal file
@@ -0,0 +1,45 @@
|
||||
/****************************************************************************
|
||||
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
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(disable : 4250)
|
||||
#pragma warning(disable : 4996)
|
||||
#endif
|
||||
|
||||
#include "base/Macros.h"
|
||||
|
||||
#if !defined(NDEBUG) ^ defined(_DEBUG)
|
||||
#ifdef CC_DEBUG
|
||||
#define _DEBUG
|
||||
#else
|
||||
#define NDEBUG
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <PxConfig.h>
|
||||
#include <PxPhysicsAPI.h>
|
||||
#include <extensions/PxDefaultAllocator.h>
|
||||
#include <extensions/PxDefaultErrorCallback.h>
|
||||
269
cocos/physics/physx/PhysXRigidBody.cpp
Normal file
269
cocos/physics/physx/PhysXRigidBody.cpp
Normal file
@@ -0,0 +1,269 @@
|
||||
/****************************************************************************
|
||||
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/PhysXRigidBody.h"
|
||||
#include "physics/physx/PhysXInc.h"
|
||||
#include "physics/physx/PhysXUtils.h"
|
||||
#include "physics/physx/PhysXWorld.h"
|
||||
|
||||
using physx::PxActorFlag;
|
||||
using physx::PxForceMode;
|
||||
using physx::PxReal;
|
||||
using physx::PxTransform;
|
||||
using physx::PxVec3;
|
||||
|
||||
namespace cc {
|
||||
namespace physics {
|
||||
|
||||
PhysXRigidBody::PhysXRigidBody() {
|
||||
_mObjectID = PhysXWorld::getInstance().addWrapperObject(reinterpret_cast<uintptr_t>(this));
|
||||
}
|
||||
|
||||
void PhysXRigidBody::initialize(Node *node, ERigidBodyType t, uint32_t g) {
|
||||
_mGroup = g;
|
||||
PhysXWorld &ins = PhysXWorld::getInstance();
|
||||
_mSharedBody = ins.getSharedBody(node, this);
|
||||
getSharedBody().reference(true);
|
||||
getSharedBody().setType(t);
|
||||
}
|
||||
|
||||
void PhysXRigidBody::onEnable() {
|
||||
_mEnabled = true;
|
||||
getSharedBody().enabled(true);
|
||||
}
|
||||
|
||||
void PhysXRigidBody::onDisable() {
|
||||
_mEnabled = false;
|
||||
getSharedBody().enabled(false);
|
||||
}
|
||||
|
||||
void PhysXRigidBody::onDestroy() {
|
||||
getSharedBody().reference(false);
|
||||
PhysXWorld::getInstance().removeWrapperObject(_mObjectID);
|
||||
}
|
||||
|
||||
bool PhysXRigidBody::isAwake() {
|
||||
if (!getSharedBody().isInWorld() || getSharedBody().isStatic()) return false;
|
||||
return !getSharedBody().getImpl().rigidDynamic->isSleeping();
|
||||
}
|
||||
|
||||
bool PhysXRigidBody::isSleepy() {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PhysXRigidBody::isSleeping() {
|
||||
if (!getSharedBody().isInWorld() || getSharedBody().isStatic()) return true;
|
||||
return getSharedBody().getImpl().rigidDynamic->isSleeping();
|
||||
}
|
||||
|
||||
void PhysXRigidBody::setType(ERigidBodyType v) {
|
||||
getSharedBody().setType(v);
|
||||
}
|
||||
|
||||
void PhysXRigidBody::setMass(float v) {
|
||||
getSharedBody().setMass(v);
|
||||
}
|
||||
|
||||
void PhysXRigidBody::setLinearDamping(float v) {
|
||||
if (getSharedBody().isStatic()) return;
|
||||
getSharedBody().getImpl().rigidDynamic->setLinearDamping(v);
|
||||
}
|
||||
|
||||
void PhysXRigidBody::setAngularDamping(float v) {
|
||||
if (getSharedBody().isStatic()) return;
|
||||
getSharedBody().getImpl().rigidDynamic->setAngularDamping(v);
|
||||
}
|
||||
|
||||
void PhysXRigidBody::useGravity(bool v) {
|
||||
if (getSharedBody().isStatic()) return;
|
||||
getSharedBody().getImpl().rigidDynamic->setActorFlag(PxActorFlag::eDISABLE_GRAVITY, !v);
|
||||
}
|
||||
|
||||
void PhysXRigidBody::useCCD(bool v) {
|
||||
if (getSharedBody().isStatic()) return;
|
||||
getSharedBody().getImpl().rigidDynamic->setRigidBodyFlag(physx::PxRigidBodyFlag::eENABLE_CCD, v);
|
||||
}
|
||||
|
||||
void PhysXRigidBody::setLinearFactor(float x, float y, float z) {
|
||||
if (getSharedBody().isStatic()) return;
|
||||
getSharedBody().getImpl().rigidDynamic->setRigidDynamicLockFlag(physx::PxRigidDynamicLockFlag::eLOCK_LINEAR_X, x == 0.);
|
||||
getSharedBody().getImpl().rigidDynamic->setRigidDynamicLockFlag(physx::PxRigidDynamicLockFlag::eLOCK_LINEAR_Y, y == 0.);
|
||||
getSharedBody().getImpl().rigidDynamic->setRigidDynamicLockFlag(physx::PxRigidDynamicLockFlag::eLOCK_LINEAR_Z, z == 0.);
|
||||
}
|
||||
|
||||
void PhysXRigidBody::setAngularFactor(float x, float y, float z) {
|
||||
if (getSharedBody().isStatic()) return;
|
||||
getSharedBody().getImpl().rigidDynamic->setRigidDynamicLockFlag(physx::PxRigidDynamicLockFlag::eLOCK_ANGULAR_X, x == 0.);
|
||||
getSharedBody().getImpl().rigidDynamic->setRigidDynamicLockFlag(physx::PxRigidDynamicLockFlag::eLOCK_ANGULAR_Y, y == 0.);
|
||||
getSharedBody().getImpl().rigidDynamic->setRigidDynamicLockFlag(physx::PxRigidDynamicLockFlag::eLOCK_ANGULAR_Z, z == 0.);
|
||||
}
|
||||
|
||||
void PhysXRigidBody::setAllowSleep(bool v) {
|
||||
if (!getSharedBody().isDynamic()) return;
|
||||
PxReal wc = v ? 0.0001F : FLT_MAX;
|
||||
getSharedBody().getImpl().rigidDynamic->setWakeCounter(wc);
|
||||
}
|
||||
|
||||
void PhysXRigidBody::wakeUp() {
|
||||
if (!getSharedBody().isInWorld() || getSharedBody().isStatic()) return;
|
||||
getSharedBody().getImpl().rigidDynamic->wakeUp();
|
||||
}
|
||||
|
||||
void PhysXRigidBody::sleep() {
|
||||
if (!getSharedBody().isInWorld() || getSharedBody().isStatic()) return;
|
||||
getSharedBody().getImpl().rigidDynamic->putToSleep();
|
||||
}
|
||||
|
||||
void PhysXRigidBody::clearState() {
|
||||
if (!getSharedBody().isInWorld()) return;
|
||||
clearForces();
|
||||
clearVelocity();
|
||||
}
|
||||
|
||||
void PhysXRigidBody::clearForces() {
|
||||
if (!getSharedBody().isInWorld()) return;
|
||||
getSharedBody().clearForces();
|
||||
}
|
||||
|
||||
void PhysXRigidBody::clearVelocity() {
|
||||
getSharedBody().clearVelocity();
|
||||
}
|
||||
|
||||
void PhysXRigidBody::setSleepThreshold(float v) {
|
||||
if (getSharedBody().isStatic()) return;
|
||||
//(approximated) mass-normalized kinetic energy
|
||||
float ke = 0.5F * v * v;
|
||||
getSharedBody().getImpl().rigidDynamic->setSleepThreshold(ke);
|
||||
}
|
||||
|
||||
float PhysXRigidBody::getSleepThreshold() {
|
||||
float ke = getSharedBody().getImpl().rigidDynamic->getSleepThreshold();
|
||||
float v = sqrtf(2.F * ke);
|
||||
return v;
|
||||
}
|
||||
|
||||
cc::Vec3 PhysXRigidBody::getLinearVelocity() {
|
||||
if (getSharedBody().isStatic()) return cc::Vec3::ZERO;
|
||||
cc::Vec3 cv;
|
||||
pxSetVec3Ext(cv, getSharedBody().getImpl().rigidDynamic->getLinearVelocity());
|
||||
return cv;
|
||||
}
|
||||
|
||||
void PhysXRigidBody::setLinearVelocity(float x, float y, float z) {
|
||||
if (getSharedBody().isStatic()) return;
|
||||
getSharedBody().getImpl().rigidDynamic->setLinearVelocity(PxVec3{x, y, z});
|
||||
}
|
||||
|
||||
cc::Vec3 PhysXRigidBody::getAngularVelocity() {
|
||||
if (getSharedBody().isStatic()) return cc::Vec3::ZERO;
|
||||
cc::Vec3 cv;
|
||||
pxSetVec3Ext(cv, getSharedBody().getImpl().rigidDynamic->getAngularVelocity());
|
||||
return cv;
|
||||
}
|
||||
|
||||
void PhysXRigidBody::setAngularVelocity(float x, float y, float z) {
|
||||
if (getSharedBody().isStatic()) return;
|
||||
getSharedBody().getImpl().rigidDynamic->setAngularVelocity(PxVec3{x, y, z});
|
||||
}
|
||||
|
||||
void PhysXRigidBody::applyForce(float x, float y, float z, float rx, float ry, float rz) {
|
||||
if (!getSharedBody().isInWorld() || getSharedBody().isStaticOrKinematic()) return;
|
||||
const PxVec3 force{x, y, z};
|
||||
if (force.isZero()) return;
|
||||
auto *body = getSharedBody().getImpl().rigidDynamic;
|
||||
body->addForce(force, PxForceMode::eFORCE, true);
|
||||
const PxVec3 torque = (PxVec3{rx, ry, rz}).cross(force);
|
||||
if (!torque.isZero()) body->addTorque(torque, PxForceMode::eFORCE, true);
|
||||
}
|
||||
|
||||
void PhysXRigidBody::applyLocalForce(float x, float y, float z, float rx, float ry, float rz) {
|
||||
if (!getSharedBody().isInWorld() || getSharedBody().isStaticOrKinematic()) return;
|
||||
const PxVec3 force{x, y, z};
|
||||
if (force.isZero()) return;
|
||||
auto *body = getSharedBody().getImpl().rigidDynamic;
|
||||
const PxTransform bodyPose = body->getGlobalPose();
|
||||
const PxVec3 worldForce = bodyPose.rotate(force);
|
||||
const PxVec3 worldPos = bodyPose.rotate(PxVec3{rx, ry, rz});
|
||||
body->addForce(worldForce, PxForceMode::eFORCE, true);
|
||||
const PxVec3 torque = worldPos.cross(worldForce);
|
||||
if (!torque.isZero()) body->addTorque(torque, PxForceMode::eFORCE, true);
|
||||
}
|
||||
|
||||
void PhysXRigidBody::applyImpulse(float x, float y, float z, float rx, float ry, float rz) {
|
||||
if (!getSharedBody().isInWorld() || getSharedBody().isStaticOrKinematic()) return;
|
||||
const PxVec3 impulse{x, y, z};
|
||||
if (impulse.isZero()) return;
|
||||
auto *body = getSharedBody().getImpl().rigidDynamic;
|
||||
const PxVec3 torque = (PxVec3{rx, ry, rz}).cross(impulse);
|
||||
body->addForce(impulse, PxForceMode::eIMPULSE, true);
|
||||
if (!torque.isZero()) body->addTorque(torque, PxForceMode::eIMPULSE, true);
|
||||
}
|
||||
|
||||
void PhysXRigidBody::applyLocalImpulse(float x, float y, float z, float rx, float ry, float rz) {
|
||||
if (!getSharedBody().isInWorld() || getSharedBody().isStaticOrKinematic()) return;
|
||||
const PxVec3 impulse{x, y, z};
|
||||
if (impulse.isZero()) return;
|
||||
auto *body = getSharedBody().getImpl().rigidDynamic;
|
||||
const PxTransform bodyPose = body->getGlobalPose();
|
||||
const PxVec3 worldImpulse = bodyPose.rotate(impulse);
|
||||
const PxVec3 worldPos = bodyPose.rotate(PxVec3{rx, ry, rz});
|
||||
body->addForce(worldImpulse, PxForceMode::eIMPULSE, true);
|
||||
const PxVec3 torque = worldPos.cross(worldImpulse);
|
||||
if (!torque.isZero()) body->addTorque(torque, PxForceMode::eIMPULSE, true);
|
||||
}
|
||||
|
||||
void PhysXRigidBody::applyTorque(float x, float y, float z) {
|
||||
if (!getSharedBody().isInWorld() || getSharedBody().isStaticOrKinematic()) return;
|
||||
PxVec3 torque{x, y, z};
|
||||
if (torque.isZero()) return;
|
||||
getSharedBody().getImpl().rigidDynamic->addTorque(torque, PxForceMode::eFORCE, true);
|
||||
}
|
||||
|
||||
void PhysXRigidBody::applyLocalTorque(float x, float y, float z) {
|
||||
if (!getSharedBody().isInWorld() || getSharedBody().isStaticOrKinematic()) return;
|
||||
PxVec3 torque{x, y, z};
|
||||
if (torque.isZero()) return;
|
||||
auto *body = getSharedBody().getImpl().rigidDynamic;
|
||||
const PxTransform bodyPose = body->getGlobalPose();
|
||||
body->addTorque(bodyPose.rotate(PxVec3{x, y, z}), PxForceMode::eFORCE, true);
|
||||
}
|
||||
|
||||
uint32_t PhysXRigidBody::getGroup() {
|
||||
return getSharedBody().getGroup();
|
||||
}
|
||||
|
||||
void PhysXRigidBody::setGroup(uint32_t g) {
|
||||
getSharedBody().setGroup(g);
|
||||
}
|
||||
|
||||
uint32_t PhysXRigidBody::getMask() {
|
||||
return getSharedBody().getMask();
|
||||
}
|
||||
|
||||
void PhysXRigidBody::setMask(uint32_t m) {
|
||||
getSharedBody().setMask(m);
|
||||
}
|
||||
|
||||
} // namespace physics
|
||||
} // namespace cc
|
||||
91
cocos/physics/physx/PhysXRigidBody.h
Normal file
91
cocos/physics/physx/PhysXRigidBody.h
Normal file
@@ -0,0 +1,91 @@
|
||||
/****************************************************************************
|
||||
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 "physics/physx//PhysXInc.h"
|
||||
#include "physics/physx/PhysXSharedBody.h"
|
||||
#include "physics/spec/IBody.h"
|
||||
|
||||
namespace cc {
|
||||
namespace physics {
|
||||
|
||||
class PhysXRigidBody final : public IRigidBody {
|
||||
public:
|
||||
PhysXRigidBody();
|
||||
~PhysXRigidBody() override = default;
|
||||
inline bool isEnabled() const { return _mEnabled; }
|
||||
inline const PhysXSharedBody &getSharedBody() const { return *_mSharedBody; }
|
||||
inline PhysXSharedBody &getSharedBody() { return *_mSharedBody; }
|
||||
void initialize(Node *node, ERigidBodyType t, uint32_t g) override;
|
||||
void onEnable() override;
|
||||
void onDisable() override;
|
||||
void onDestroy() override;
|
||||
bool isAwake() override;
|
||||
bool isSleepy() override;
|
||||
bool isSleeping() override;
|
||||
void setType(ERigidBodyType v) override;
|
||||
void setMass(float v) override;
|
||||
void setLinearDamping(float v) override;
|
||||
void setAngularDamping(float v) override;
|
||||
void useGravity(bool v) override;
|
||||
void useCCD(bool v) override;
|
||||
void setLinearFactor(float x, float y, float z) override;
|
||||
void setAngularFactor(float x, float y, float z) override;
|
||||
void setAllowSleep(bool v) override;
|
||||
void wakeUp() override;
|
||||
void sleep() override;
|
||||
void clearState() override;
|
||||
void clearForces() override;
|
||||
void clearVelocity() override;
|
||||
void setSleepThreshold(float v) override;
|
||||
float getSleepThreshold() override;
|
||||
cc::Vec3 getLinearVelocity() override;
|
||||
void setLinearVelocity(float x, float y, float z) override;
|
||||
cc::Vec3 getAngularVelocity() override;
|
||||
void setAngularVelocity(float x, float y, float z) override;
|
||||
void applyForce(float x, float y, float z, float rx, float ry, float rz) override;
|
||||
void applyLocalForce(float x, float y, float z, float rx, float ry, float rz) override;
|
||||
void applyImpulse(float x, float y, float z, float rx, float ry, float rz) override;
|
||||
void applyLocalImpulse(float x, float y, float z, float rx, float ry, float rz) override;
|
||||
void applyTorque(float x, float y, float z) override;
|
||||
void applyLocalTorque(float x, float y, float z) override;
|
||||
uint32_t getGroup() override;
|
||||
uint32_t getMask() override;
|
||||
void setGroup(uint32_t g) override;
|
||||
void setMask(uint32_t m) override;
|
||||
inline uint32_t getInitialGroup() const { return _mGroup; }
|
||||
uint32_t getObjectID() const override { return _mObjectID; };
|
||||
|
||||
protected:
|
||||
// physx::PhysXWorld* mWrappedWorld;
|
||||
PhysXSharedBody *_mSharedBody{nullptr};
|
||||
uint32_t _mGroup{1};
|
||||
bool _mEnabled{false};
|
||||
uint32_t _mObjectID{0};
|
||||
};
|
||||
|
||||
} // namespace physics
|
||||
} // namespace cc
|
||||
354
cocos/physics/physx/PhysXSharedBody.cpp
Normal file
354
cocos/physics/physx/PhysXSharedBody.cpp
Normal file
@@ -0,0 +1,354 @@
|
||||
/****************************************************************************
|
||||
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/PhysXSharedBody.h"
|
||||
#include <cmath>
|
||||
#include "base/memory/Memory.h"
|
||||
#include "physics/physx/PhysXInc.h"
|
||||
#include "physics/physx/PhysXUtils.h"
|
||||
#include "physics/physx/PhysXWorld.h"
|
||||
#include "physics/physx/joints/PhysXJoint.h"
|
||||
#include "physics/physx/shapes/PhysXShape.h"
|
||||
|
||||
using physx::PxFilterData;
|
||||
using physx::PxForceMode;
|
||||
using physx::PxIdentity;
|
||||
using physx::PxJointActorIndex;
|
||||
using physx::PxPhysics;
|
||||
using physx::PxQuat;
|
||||
using physx::PxRigidActor;
|
||||
using physx::PxRigidBodyExt;
|
||||
using physx::PxRigidBodyFlag;
|
||||
using physx::PxTransform;
|
||||
using physx::PxVec3;
|
||||
|
||||
namespace cc {
|
||||
namespace physics {
|
||||
ccstd::unordered_map<Node *, PhysXSharedBody *> PhysXSharedBody::sharedBodesMap;
|
||||
|
||||
static int idCounter = 0;
|
||||
PhysXSharedBody::PhysXSharedBody(
|
||||
Node *node,
|
||||
PhysXWorld *const world,
|
||||
PhysXRigidBody *const body) : _mID(idCounter++),
|
||||
_mRef(0),
|
||||
_mType(ERigidBodyType::STATIC),
|
||||
_mIsStatic(true),
|
||||
_mIndex(-1),
|
||||
_mFilterData(1, 1, 1, 0),
|
||||
_mStaticActor(nullptr),
|
||||
_mDynamicActor(nullptr),
|
||||
_mWrappedWorld(world),
|
||||
_mWrappedBody(body) {
|
||||
_mImpl.ptr = 0;
|
||||
_mNode = node;
|
||||
};
|
||||
|
||||
PhysXSharedBody *PhysXSharedBody::getSharedBody(const Node *node, PhysXWorld *const world, PhysXRigidBody *const body) {
|
||||
auto iter = sharedBodesMap.find(const_cast<Node *>(node));
|
||||
PhysXSharedBody *newSB;
|
||||
if (iter != sharedBodesMap.end()) {
|
||||
newSB = iter->second;
|
||||
} else {
|
||||
newSB = ccnew PhysXSharedBody(const_cast<Node *>(node), world, body);
|
||||
newSB->_mFilterData.word0 = 1;
|
||||
newSB->_mFilterData.word1 = world->getMaskByIndex(0);
|
||||
sharedBodesMap.insert(std::pair<Node *, PhysXSharedBody *>(const_cast<Node *>(node), newSB));
|
||||
}
|
||||
if (body != nullptr) {
|
||||
auto g = body->getInitialGroup();
|
||||
newSB->_mFilterData.word0 = g;
|
||||
newSB->_mFilterData.word1 = world->getMaskByIndex(static_cast<uint32_t>(log2(g)));
|
||||
}
|
||||
return newSB;
|
||||
}
|
||||
|
||||
PhysXSharedBody::~PhysXSharedBody() {
|
||||
sharedBodesMap.erase(_mNode);
|
||||
if (_mStaticActor != nullptr) PX_RELEASE(_mStaticActor);
|
||||
if (_mDynamicActor != nullptr) PX_RELEASE(_mDynamicActor);
|
||||
}
|
||||
|
||||
PhysXSharedBody::UActor PhysXSharedBody::getImpl() {
|
||||
initActor();
|
||||
_mImpl.ptr = isStatic() ? reinterpret_cast<uintptr_t>(_mStaticActor) : reinterpret_cast<uintptr_t>(_mDynamicActor);
|
||||
return _mImpl;
|
||||
}
|
||||
|
||||
void PhysXSharedBody::setType(ERigidBodyType v) {
|
||||
if (_mType == v) return;
|
||||
_mType = v;
|
||||
initActor();
|
||||
if (isStatic()) {
|
||||
_mImpl.ptr = reinterpret_cast<uintptr_t>(_mStaticActor);
|
||||
} else {
|
||||
_mImpl.ptr = reinterpret_cast<uintptr_t>(_mDynamicActor);
|
||||
_mImpl.rigidDynamic->setRigidBodyFlag(physx::PxRigidBodyFlag::eKINEMATIC, _mType == ERigidBodyType::KINEMATIC);
|
||||
}
|
||||
}
|
||||
|
||||
void PhysXSharedBody::reference(bool v) {
|
||||
v ? _mRef++ : _mRef--;
|
||||
if (_mRef == 0) delete this;
|
||||
}
|
||||
|
||||
void PhysXSharedBody::enabled(bool v) {
|
||||
if (v) {
|
||||
if (_mIndex < 0) {
|
||||
_mIndex = 1;
|
||||
_mWrappedWorld->addActor(*this);
|
||||
}
|
||||
} else {
|
||||
auto *wb = _mWrappedBody;
|
||||
auto ws = _mWrappedShapes;
|
||||
auto isRemove = ws.empty() && (wb == nullptr || (wb != nullptr && !wb->isEnabled()));
|
||||
if (isRemove) {
|
||||
_mIndex = -1;
|
||||
if (!isStaticOrKinematic()) {
|
||||
clearVelocity();
|
||||
}
|
||||
_mWrappedWorld->removeActor(*this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PhysXSharedBody::initActor() {
|
||||
const bool temp = _mIsStatic;
|
||||
if (isStatic()) {
|
||||
_mIsStatic = true;
|
||||
initStaticActor();
|
||||
} else {
|
||||
_mIsStatic = false;
|
||||
initDynamicActor();
|
||||
}
|
||||
if (temp != _mIsStatic) switchActor(temp);
|
||||
}
|
||||
|
||||
void PhysXSharedBody::switchActor(const bool isStaticBefore) {
|
||||
if (_mStaticActor == nullptr || _mDynamicActor == nullptr) return;
|
||||
PxRigidActor &a0 = isStaticBefore ? *reinterpret_cast<PxRigidActor *>(_mStaticActor) : *reinterpret_cast<PxRigidActor *>(_mDynamicActor);
|
||||
PxRigidActor &a1 = !isStaticBefore ? *reinterpret_cast<PxRigidActor *>(_mStaticActor) : *reinterpret_cast<PxRigidActor *>(_mDynamicActor);
|
||||
if (_mIndex >= 0) {
|
||||
_mWrappedWorld->getScene().removeActor(a0, false);
|
||||
_mWrappedWorld->getScene().addActor(a1);
|
||||
}
|
||||
for (auto const &ws : _mWrappedShapes) {
|
||||
a0.detachShape(ws->getShape(), false);
|
||||
a1.attachShape(ws->getShape());
|
||||
}
|
||||
if (isStaticBefore) {
|
||||
if (isDynamic()) _mDynamicActor->wakeUp();
|
||||
_mDynamicActor->setRigidBodyFlag(PxRigidBodyFlag::eKINEMATIC, isKinematic());
|
||||
PxRigidBodyExt::setMassAndUpdateInertia(*_mDynamicActor, _mMass);
|
||||
}
|
||||
}
|
||||
|
||||
void PhysXSharedBody::initStaticActor() {
|
||||
if (_mStaticActor == nullptr) {
|
||||
PxTransform transform{PxIdentity};
|
||||
getNode()->updateWorldTransform();
|
||||
pxSetVec3Ext(transform.p, getNode()->getWorldPosition());
|
||||
pxSetQuatExt(transform.q, getNode()->getWorldRotation());
|
||||
if (!transform.p.isFinite()) transform.p = PxVec3{PxIdentity};
|
||||
if (!transform.q.isUnit()) transform.q = PxQuat{PxIdentity};
|
||||
PxPhysics &phy = PxGetPhysics();
|
||||
_mStaticActor = phy.createRigidStatic(transform);
|
||||
}
|
||||
}
|
||||
|
||||
void PhysXSharedBody::initDynamicActor() {
|
||||
if (_mDynamicActor == nullptr) {
|
||||
PxTransform transform{PxIdentity};
|
||||
getNode()->updateWorldTransform();
|
||||
pxSetVec3Ext(transform.p, getNode()->getWorldPosition());
|
||||
pxSetQuatExt(transform.q, getNode()->getWorldRotation());
|
||||
if (!transform.p.isFinite()) transform.p = PxVec3{PxIdentity};
|
||||
if (!transform.q.isUnit()) transform.q = PxQuat{PxIdentity};
|
||||
PxPhysics &phy = PxGetPhysics();
|
||||
_mDynamicActor = phy.createRigidDynamic(transform);
|
||||
_mDynamicActor->setRigidBodyFlag(PxRigidBodyFlag::eKINEMATIC, isKinematic());
|
||||
}
|
||||
}
|
||||
|
||||
void PhysXSharedBody::syncScale() {
|
||||
for (auto const &sb : _mWrappedShapes) {
|
||||
sb->updateScale();
|
||||
}
|
||||
|
||||
for (auto const &sb : _mWrappedJoints0) {
|
||||
sb->updateScale0();
|
||||
}
|
||||
|
||||
for (auto const &sb : _mWrappedJoints1) {
|
||||
sb->updateScale1();
|
||||
}
|
||||
}
|
||||
|
||||
void PhysXSharedBody::syncSceneToPhysics() {
|
||||
uint32_t getChangedFlags = getNode()->getChangedFlags();
|
||||
if (getChangedFlags) {
|
||||
if (getChangedFlags & static_cast<uint32_t>(TransformBit::SCALE)) syncScale();
|
||||
auto wp = getImpl().rigidActor->getGlobalPose();
|
||||
if (getChangedFlags & static_cast<uint32_t>(TransformBit::POSITION)) {
|
||||
getNode()->updateWorldTransform();
|
||||
pxSetVec3Ext(wp.p, getNode()->getWorldPosition());
|
||||
}
|
||||
if (getChangedFlags & static_cast<uint32_t>(TransformBit::ROTATION)) {
|
||||
getNode()->updateWorldTransform();
|
||||
pxSetQuatExt(wp.q, getNode()->getWorldRotation());
|
||||
}
|
||||
|
||||
if (isKinematic()) {
|
||||
getImpl().rigidDynamic->setKinematicTarget(wp);
|
||||
} else {
|
||||
getImpl().rigidActor->setGlobalPose(wp, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PhysXSharedBody::syncSceneWithCheck() {
|
||||
if (getNode()->getChangedFlags() & static_cast<uint32_t>(TransformBit::SCALE)) syncScale();
|
||||
auto wp = getImpl().rigidActor->getGlobalPose();
|
||||
bool needUpdate = false;
|
||||
getNode()->updateWorldTransform();
|
||||
if (wp.p != getNode()->getWorldPosition()) {
|
||||
pxSetVec3Ext(wp.p, getNode()->getWorldPosition());
|
||||
needUpdate = true;
|
||||
}
|
||||
const auto nr = getNode()->getWorldRotation();
|
||||
if (wp.q.x != nr.x && wp.q.y != nr.y && wp.q.z != nr.z) {
|
||||
pxSetQuatExt(wp.q, getNode()->getWorldRotation());
|
||||
needUpdate = true;
|
||||
}
|
||||
if (needUpdate) {
|
||||
getImpl().rigidActor->setGlobalPose(wp, true);
|
||||
}
|
||||
}
|
||||
|
||||
void PhysXSharedBody::syncPhysicsToScene() {
|
||||
if (isStaticOrKinematic()) return;
|
||||
if (_mDynamicActor->isSleeping()) return;
|
||||
const PxTransform &wp = getImpl().rigidActor->getGlobalPose();
|
||||
getNode()->setWorldPosition(wp.p.x, wp.p.y, wp.p.z);
|
||||
getNode()->setWorldRotation(wp.q.x, wp.q.y, wp.q.z, wp.q.w);
|
||||
getNode()->setChangedFlags(getNode()->getChangedFlags() | static_cast<uint32_t>(TransformBit::POSITION) | static_cast<uint32_t>(TransformBit::ROTATION));
|
||||
}
|
||||
|
||||
void PhysXSharedBody::addShape(const PhysXShape &shape) {
|
||||
auto beg = _mWrappedShapes.begin();
|
||||
auto end = _mWrappedShapes.end();
|
||||
auto iter = find(beg, end, &shape);
|
||||
if (iter == end) {
|
||||
shape.getShape().setSimulationFilterData(_mFilterData);
|
||||
shape.getShape().setQueryFilterData(_mFilterData);
|
||||
getImpl().rigidActor->attachShape(shape.getShape());
|
||||
_mWrappedShapes.push_back(&const_cast<PhysXShape &>(shape));
|
||||
if (!shape.isTrigger()) {
|
||||
if (isDynamic()) PxRigidBodyExt::setMassAndUpdateInertia(*getImpl().rigidDynamic, _mMass);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PhysXSharedBody::removeShape(const PhysXShape &shape) {
|
||||
auto beg = _mWrappedShapes.begin();
|
||||
auto end = _mWrappedShapes.end();
|
||||
auto iter = find(beg, end, &shape);
|
||||
if (iter != end) {
|
||||
_mWrappedShapes.erase(iter);
|
||||
getImpl().rigidActor->detachShape(shape.getShape(), true);
|
||||
if (!const_cast<PhysXShape &>(shape).isTrigger()) {
|
||||
if (isDynamic()) PxRigidBodyExt::setMassAndUpdateInertia(*getImpl().rigidDynamic, _mMass);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PhysXSharedBody::addJoint(const PhysXJoint &joint, const PxJointActorIndex::Enum index) {
|
||||
if (index == PxJointActorIndex::eACTOR1) {
|
||||
auto beg = _mWrappedJoints1.begin();
|
||||
auto end = _mWrappedJoints1.end();
|
||||
auto iter = find(beg, end, &joint);
|
||||
if (iter == end) _mWrappedJoints1.push_back(&const_cast<PhysXJoint &>(joint));
|
||||
} else {
|
||||
auto beg = _mWrappedJoints0.begin();
|
||||
auto end = _mWrappedJoints0.end();
|
||||
auto iter = find(beg, end, &joint);
|
||||
if (iter == end) _mWrappedJoints0.push_back(&const_cast<PhysXJoint &>(joint));
|
||||
}
|
||||
}
|
||||
|
||||
void PhysXSharedBody::removeJoint(const PhysXJoint &joint, const PxJointActorIndex::Enum index) {
|
||||
if (index == PxJointActorIndex::eACTOR1) {
|
||||
auto beg = _mWrappedJoints1.begin();
|
||||
auto end = _mWrappedJoints1.end();
|
||||
auto iter = find(beg, end, &joint);
|
||||
if (iter != end) _mWrappedJoints1.erase(iter);
|
||||
} else {
|
||||
auto beg = _mWrappedJoints0.begin();
|
||||
auto end = _mWrappedJoints0.end();
|
||||
auto iter = find(beg, end, &joint);
|
||||
if (iter != end) _mWrappedJoints0.erase(iter);
|
||||
}
|
||||
}
|
||||
|
||||
void PhysXSharedBody::setMass(float v) {
|
||||
if (v <= 0) v = 1e-7F;
|
||||
_mMass = v;
|
||||
if (isDynamic()) PxRigidBodyExt::setMassAndUpdateInertia(*getImpl().rigidDynamic, _mMass);
|
||||
}
|
||||
|
||||
void PhysXSharedBody::setGroup(uint32_t v) {
|
||||
_mFilterData.word0 = v;
|
||||
setCollisionFilter(_mFilterData);
|
||||
}
|
||||
|
||||
void PhysXSharedBody::setMask(uint32_t v) {
|
||||
_mFilterData.word1 = v;
|
||||
setCollisionFilter(_mFilterData);
|
||||
}
|
||||
|
||||
void PhysXSharedBody::setCollisionFilter(const PxFilterData &data) {
|
||||
if (isDynamic()) _mDynamicActor->wakeUp();
|
||||
for (auto const &ws : _mWrappedShapes) {
|
||||
ws->getShape().setQueryFilterData(data);
|
||||
ws->getShape().setSimulationFilterData(data);
|
||||
}
|
||||
}
|
||||
|
||||
void PhysXSharedBody::clearForces() {
|
||||
if (!isInWorld()) return;
|
||||
if (isStaticOrKinematic()) return;
|
||||
_mDynamicActor->clearForce(PxForceMode::eFORCE);
|
||||
_mDynamicActor->clearForce(PxForceMode::eIMPULSE);
|
||||
_mDynamicActor->clearTorque(PxForceMode::eFORCE);
|
||||
_mDynamicActor->clearTorque(PxForceMode::eIMPULSE);
|
||||
}
|
||||
|
||||
void PhysXSharedBody::clearVelocity() {
|
||||
if (isStaticOrKinematic()) return;
|
||||
_mDynamicActor->setLinearVelocity(PxVec3{PxIdentity}, false);
|
||||
_mDynamicActor->setAngularVelocity(PxVec3{PxIdentity}, false);
|
||||
}
|
||||
|
||||
} // namespace physics
|
||||
} // namespace cc
|
||||
109
cocos/physics/physx/PhysXSharedBody.h
Normal file
109
cocos/physics/physx/PhysXSharedBody.h
Normal file
@@ -0,0 +1,109 @@
|
||||
/****************************************************************************
|
||||
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 "base/std/container/unordered_map.h"
|
||||
#include "core/scene-graph/Node.h"
|
||||
#include "physics/physx/PhysXInc.h"
|
||||
#include "physics/spec/IBody.h"
|
||||
|
||||
namespace cc {
|
||||
|
||||
namespace physics {
|
||||
|
||||
class PhysXWorld;
|
||||
class PhysXShape;
|
||||
class PhysXJoint;
|
||||
class PhysXRigidBody;
|
||||
|
||||
class PhysXSharedBody final {
|
||||
public:
|
||||
static PhysXSharedBody *getSharedBody(const Node *node, PhysXWorld *world, PhysXRigidBody *body);
|
||||
PhysXSharedBody() = delete;
|
||||
PhysXSharedBody(const PhysXSharedBody &other) = delete;
|
||||
PhysXSharedBody(PhysXSharedBody &&other) = delete;
|
||||
void reference(bool v);
|
||||
void enabled(bool v);
|
||||
inline bool isInWorld() { return _mIndex >= 0; }
|
||||
inline bool isStatic() { return static_cast<int>(_mType) & static_cast<int>(ERigidBodyType::STATIC); }
|
||||
inline bool isKinematic() { return static_cast<int>(_mType) & static_cast<int>(ERigidBodyType::KINEMATIC); }
|
||||
inline bool isStaticOrKinematic() { return static_cast<int>(_mType) & static_cast<int>(ERigidBodyType::STATIC) || static_cast<int>(_mType) & static_cast<int>(ERigidBodyType::KINEMATIC); }
|
||||
inline bool isDynamic() { return !isStaticOrKinematic(); }
|
||||
inline Node *getNode() const { return _mNode; }
|
||||
inline PhysXWorld &getWorld() const { return *_mWrappedWorld; }
|
||||
union UActor {
|
||||
uintptr_t ptr;
|
||||
physx::PxRigidActor *rigidActor;
|
||||
physx::PxRigidStatic *rigidStatic;
|
||||
physx::PxRigidDynamic *rigidDynamic;
|
||||
};
|
||||
UActor getImpl();
|
||||
void setType(ERigidBodyType v);
|
||||
void setMass(float v);
|
||||
void syncScale();
|
||||
void syncSceneToPhysics();
|
||||
void syncSceneWithCheck();
|
||||
void syncPhysicsToScene();
|
||||
void addShape(const PhysXShape &shape);
|
||||
void removeShape(const PhysXShape &shape);
|
||||
void addJoint(const PhysXJoint &joint, physx::PxJointActorIndex::Enum index);
|
||||
void removeJoint(const PhysXJoint &joint, physx::PxJointActorIndex::Enum index);
|
||||
void setCollisionFilter(const physx::PxFilterData &data);
|
||||
void clearForces();
|
||||
void clearVelocity();
|
||||
void setGroup(uint32_t v);
|
||||
void setMask(uint32_t v);
|
||||
inline uint32_t getGroup() const { return _mFilterData.word0; }
|
||||
inline uint32_t getMask() const { return _mFilterData.word1; }
|
||||
|
||||
private:
|
||||
static ccstd::unordered_map<Node *, PhysXSharedBody *> sharedBodesMap;
|
||||
const uint32_t _mID;
|
||||
uint8_t _mRef;
|
||||
bool _mIsStatic;
|
||||
ERigidBodyType _mType;
|
||||
float _mMass;
|
||||
int _mIndex;
|
||||
physx::PxFilterData _mFilterData;
|
||||
Node *_mNode;
|
||||
UActor _mImpl;
|
||||
physx::PxRigidStatic *_mStaticActor;
|
||||
physx::PxRigidDynamic *_mDynamicActor;
|
||||
PhysXWorld *_mWrappedWorld;
|
||||
PhysXRigidBody *_mWrappedBody;
|
||||
ccstd::vector<PhysXShape *> _mWrappedShapes;
|
||||
ccstd::vector<PhysXJoint *> _mWrappedJoints0;
|
||||
ccstd::vector<PhysXJoint *> _mWrappedJoints1;
|
||||
PhysXSharedBody(Node *node, PhysXWorld *world, PhysXRigidBody *body);
|
||||
~PhysXSharedBody();
|
||||
void initActor();
|
||||
void switchActor(bool isStaticBefore);
|
||||
void initStaticActor();
|
||||
void initDynamicActor();
|
||||
};
|
||||
|
||||
} // namespace physics
|
||||
} // namespace cc
|
||||
47
cocos/physics/physx/PhysXUtils.cpp
Normal file
47
cocos/physics/physx/PhysXUtils.cpp
Normal file
@@ -0,0 +1,47 @@
|
||||
/****************************************************************************
|
||||
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/PhysXUtils.h"
|
||||
|
||||
namespace cc {
|
||||
namespace physics {
|
||||
|
||||
void pxSetFromTwoVectors(physx::PxQuat &out, const physx::PxVec3 &a, const physx::PxVec3 &b) {
|
||||
float dot = a.dot(b);
|
||||
if (dot < -0.999999) {
|
||||
physx::PxVec3 c = (physx::PxVec3{1., 0., 0.}).cross(a);
|
||||
if (c.magnitude() < 0.000001) c = (physx::PxVec3{0., 1., 0.}).cross(a);
|
||||
c.normalize();
|
||||
out = physx::PxQuat(physx::PxPi, c);
|
||||
} else if (dot > 0.999999) {
|
||||
out = physx::PxQuat{physx::PxIdentity};
|
||||
} else {
|
||||
physx::PxVec3 c = a.cross(b);
|
||||
out = physx::PxQuat{c.x, c.y, c.z, 1 + dot};
|
||||
out.normalize();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace physics
|
||||
} // namespace cc
|
||||
170
cocos/physics/physx/PhysXUtils.h
Normal file
170
cocos/physics/physx/PhysXUtils.h
Normal file
@@ -0,0 +1,170 @@
|
||||
/****************************************************************************
|
||||
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 "base/std/container/unordered_map.h"
|
||||
#include "base/std/container/vector.h"
|
||||
#include "renderer/pipeline/Define.h"
|
||||
#include "math/Vec3.h"
|
||||
#include "math/Vec4.h"
|
||||
#include "physics/physx/PhysXFilterShader.h"
|
||||
#include "physics/physx/PhysXInc.h"
|
||||
|
||||
#define PX_RELEASE(x) \
|
||||
if (x) { \
|
||||
(x)->release(); \
|
||||
(x) = NULL; \
|
||||
}
|
||||
|
||||
namespace cc {
|
||||
namespace physics {
|
||||
|
||||
inline bool operator!=(const physx::PxVec3 &a, const cc::Vec3 &b) {
|
||||
return a.x != b.x || a.y == b.y || a.z == b.z;
|
||||
}
|
||||
|
||||
inline bool operator!=(const cc::Vec3 &a, const physx::PxVec3 &b) {
|
||||
return a.x != b.x || a.y == b.y || a.z == b.z;
|
||||
}
|
||||
|
||||
inline bool operator==(const physx::PxVec3 &a, const cc::Vec3 &b) {
|
||||
return a.x == b.x && a.y == b.y && a.z == b.z;
|
||||
}
|
||||
|
||||
inline bool operator==(const cc::Vec3 &a, const physx::PxVec3 &b) {
|
||||
return a.x == b.x && a.y == b.y && a.z == b.z;
|
||||
}
|
||||
|
||||
inline physx::PxVec3 operator*(const physx::PxVec3 &a, const cc::Vec3 &b) {
|
||||
return physx::PxVec3{a.x * b.x, a.y * b.y, a.z * b.z};
|
||||
}
|
||||
|
||||
inline cc::Vec3 operator*(const cc::Vec3 &a, const physx::PxVec3 &b) {
|
||||
return cc::Vec3{a.x * b.x, a.y * b.y, a.z * b.z};
|
||||
}
|
||||
|
||||
inline physx::PxVec3 operator+(const physx::PxVec3 &a, const cc::Vec3 &b) {
|
||||
return physx::PxVec3{a.x + b.x, a.y + b.y, a.z + b.z};
|
||||
}
|
||||
|
||||
inline cc::Vec3 operator+(const cc::Vec3 &a, const physx::PxVec3 &b) {
|
||||
return cc::Vec3{a.x + b.x, a.y + b.y, a.z + b.z};
|
||||
}
|
||||
|
||||
inline physx::PxVec3 &operator*=(physx::PxVec3 &a, const cc::Vec3 &b) {
|
||||
a.x *= b.x;
|
||||
a.y *= b.y;
|
||||
a.z *= b.z;
|
||||
return a;
|
||||
}
|
||||
|
||||
inline cc::Vec3 &operator*=(cc::Vec3 &a, const physx::PxVec3 &b) {
|
||||
a.x *= b.x;
|
||||
a.y *= b.y;
|
||||
a.z *= b.z;
|
||||
return a;
|
||||
}
|
||||
|
||||
inline bool operator!=(const physx::PxQuat &a, const cc::Vec4 &b) {
|
||||
return a.x != b.x || a.y == b.y || a.z == b.z || a.w == b.w;
|
||||
}
|
||||
|
||||
inline bool operator!=(const cc::Vec4 &a, const physx::PxQuat &b) {
|
||||
return a.x != b.x || a.y == b.y || a.z == b.z || a.w == b.w;
|
||||
}
|
||||
|
||||
inline bool operator==(const physx::PxQuat &a, const cc::Vec4 &b) {
|
||||
return a.x == b.x && a.y == b.y && a.z == b.z && a.w == b.w;
|
||||
}
|
||||
|
||||
inline bool operator==(const cc::Vec4 &a, const physx::PxQuat &b) {
|
||||
return a.x == b.x && a.y == b.y && a.z == b.z && a.w == b.w;
|
||||
}
|
||||
|
||||
inline void pxSetVec3Ext(physx::PxVec3 &v, const cc::Vec3 &cv) {
|
||||
v = physx::PxVec3(cv.x, cv.y, cv.z);
|
||||
}
|
||||
|
||||
inline void pxSetVec3Ext(cc::Vec3 &v, const physx::PxVec3 &cv) {
|
||||
v = cc::Vec3(cv.x, cv.y, cv.z);
|
||||
}
|
||||
|
||||
template <typename T1 = physx::PxQuat, typename T2 = cc::Vec4>
|
||||
inline void pxSetQuatExt(T1 &p, const T2 &cp) {
|
||||
p = T1(cp.x, cp.y, cp.z, cp.w);
|
||||
}
|
||||
|
||||
inline void pxSetColor(gfx::Color& color, physx::PxU32 rgba) {
|
||||
color.z = ((rgba >> 16) & 0xff);
|
||||
color.y = ((rgba >> 8) & 0xff);
|
||||
color.x = ((rgba) & 0xff);
|
||||
color.w = 255;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline T pxAbsMax(const T &a, const T &b) {
|
||||
return physx::PxAbs(a) > physx::PxAbs(b) ? a : b;
|
||||
}
|
||||
|
||||
void pxSetFromTwoVectors(physx::PxQuat &out, const physx::PxVec3 &a, const physx::PxVec3 &b);
|
||||
|
||||
inline ccstd::unordered_map<uintptr_t, uint32_t> &getPxShapeMap() {
|
||||
static ccstd::unordered_map<uintptr_t, uint32_t> m;
|
||||
return m;
|
||||
}
|
||||
|
||||
//physx::PxCharacterController ptr <--> PhysxCharacterController ObjectID
|
||||
inline ccstd::unordered_map<uintptr_t, uint32_t>& getPxCCTMap() {
|
||||
static ccstd::unordered_map<uintptr_t, uint32_t> m;
|
||||
return m;
|
||||
}
|
||||
|
||||
inline ccstd::unordered_map<uint16_t, uintptr_t> &getPxMaterialMap() {
|
||||
static ccstd::unordered_map<uint16_t, uintptr_t> m;
|
||||
return m;
|
||||
}
|
||||
|
||||
inline physx::PxMaterial &getDefaultMaterial() {
|
||||
return *(reinterpret_cast<physx::PxMaterial *>(getPxMaterialMap()[0]));
|
||||
}
|
||||
|
||||
inline ccstd::vector<physx::PxRaycastHit> &getPxRaycastHitBuffer() {
|
||||
static ccstd::vector<physx::PxRaycastHit> m{12};
|
||||
return m;
|
||||
}
|
||||
|
||||
inline ccstd::vector<physx::PxSweepHit> &getPxSweepHitBuffer() {
|
||||
static ccstd::vector<physx::PxSweepHit> m{12};
|
||||
return m;
|
||||
}
|
||||
|
||||
inline QueryFilterShader &getQueryFilterShader() {
|
||||
static QueryFilterShader shader;
|
||||
return shader;
|
||||
}
|
||||
|
||||
} // namespace physics
|
||||
} // namespace cc
|
||||
619
cocos/physics/physx/PhysXWorld.cpp
Normal file
619
cocos/physics/physx/PhysXWorld.cpp
Normal file
@@ -0,0 +1,619 @@
|
||||
/****************************************************************************
|
||||
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/PhysXWorld.h"
|
||||
#include "base/memory/Memory.h"
|
||||
#include "physics/physx/PhysXFilterShader.h"
|
||||
#include "physics/physx/PhysXInc.h"
|
||||
#include "physics/physx/PhysXUtils.h"
|
||||
#include "physics/physx/joints/PhysXJoint.h"
|
||||
#include "physics/spec/IWorld.h"
|
||||
#include "core/Root.h"
|
||||
#include "scene/Camera.h"
|
||||
#include "scene/RenderWindow.h"
|
||||
#include "renderer/pipeline/Define.h"
|
||||
#include "renderer/pipeline/RenderPipeline.h"
|
||||
|
||||
namespace cc {
|
||||
namespace physics {
|
||||
|
||||
PhysXWorld *PhysXWorld::instance = nullptr;
|
||||
uint32_t PhysXWorld::_msWrapperObjectID = 1; // starts from 1 because 0 means null
|
||||
uint32_t PhysXWorld::_msPXObjectID = 0;
|
||||
|
||||
PhysXWorld &PhysXWorld::getInstance() {
|
||||
return *instance;
|
||||
}
|
||||
|
||||
physx::PxFoundation &PhysXWorld::getFundation() {
|
||||
return *getInstance()._mFoundation;
|
||||
}
|
||||
|
||||
physx::PxCooking &PhysXWorld::getCooking() {
|
||||
return *getInstance()._mCooking;
|
||||
}
|
||||
|
||||
physx::PxPhysics &PhysXWorld::getPhysics() {
|
||||
return *getInstance()._mPhysics;
|
||||
}
|
||||
|
||||
physx::PxControllerManager &PhysXWorld::getControllerManager() {
|
||||
return *getInstance()._mControllerManager;
|
||||
}
|
||||
|
||||
PhysXWorld::PhysXWorld() {
|
||||
instance = this;
|
||||
static physx::PxDefaultAllocator gAllocator;
|
||||
static physx::PxDefaultErrorCallback gErrorCallback;
|
||||
_mFoundation = PxCreateFoundation(PX_PHYSICS_VERSION, gAllocator, gErrorCallback);
|
||||
physx::PxTolerancesScale scale{};
|
||||
_mCooking = PxCreateCooking(PX_PHYSICS_VERSION, *_mFoundation, physx::PxCookingParams(scale));
|
||||
|
||||
physx::PxPvd *pvd = nullptr;
|
||||
#ifdef CC_DEBUG
|
||||
pvd = _mPvd = physx::PxCreatePvd(*_mFoundation);
|
||||
physx::PxPvdTransport *transport = physx::PxDefaultPvdSocketTransportCreate("127.0.0.1", 5425, 10);
|
||||
_mPvd->connect(*transport, physx::PxPvdInstrumentationFlag::eALL);
|
||||
#endif
|
||||
_mPhysics = PxCreatePhysics(PX_PHYSICS_VERSION, *_mFoundation, scale, true, pvd);
|
||||
PxInitExtensions(*_mPhysics, pvd);
|
||||
_mDispatcher = physx::PxDefaultCpuDispatcherCreate(0);
|
||||
|
||||
_mEventMgr = ccnew PhysXEventManager();
|
||||
|
||||
physx::PxSceneDesc sceneDesc(_mPhysics->getTolerancesScale());
|
||||
sceneDesc.gravity = physx::PxVec3(0.0F, -10.0F, 0.0F);
|
||||
sceneDesc.cpuDispatcher = _mDispatcher;
|
||||
sceneDesc.kineKineFilteringMode = physx::PxPairFilteringMode::eKEEP;
|
||||
sceneDesc.staticKineFilteringMode = physx::PxPairFilteringMode::eKEEP;
|
||||
sceneDesc.flags |= physx::PxSceneFlag::eENABLE_CCD;
|
||||
sceneDesc.filterShader = simpleFilterShader;
|
||||
sceneDesc.simulationEventCallback = &_mEventMgr->getEventCallback();
|
||||
_mScene = _mPhysics->createScene(sceneDesc);
|
||||
_mScene->setVisualizationParameter(physx::PxVisualizationParameter::eSCALE, 1.0F);
|
||||
|
||||
_mControllerManager = PxCreateControllerManager(*_mScene);
|
||||
|
||||
_mCollisionMatrix[0] = 1;
|
||||
|
||||
createMaterial(0, 0.6F, 0.6F, 0.1F, 2, 2);
|
||||
}
|
||||
|
||||
PhysXWorld::~PhysXWorld() {
|
||||
auto &materialMap = getPxMaterialMap();
|
||||
// clear material cache
|
||||
materialMap.clear();
|
||||
delete _mEventMgr;
|
||||
PhysXJoint::releaseTempRigidActor();
|
||||
PX_RELEASE(_mControllerManager);
|
||||
PX_RELEASE(_mScene);
|
||||
PX_RELEASE(_mDispatcher);
|
||||
PX_RELEASE(_mPhysics);
|
||||
#ifdef CC_DEBUG
|
||||
physx::PxPvdTransport *transport = _mPvd->getTransport();
|
||||
PX_RELEASE(_mPvd);
|
||||
PX_RELEASE(transport);
|
||||
#endif
|
||||
// release cooking before foundation
|
||||
PX_RELEASE(_mCooking);
|
||||
PxCloseExtensions();
|
||||
PX_RELEASE(_mFoundation);
|
||||
}
|
||||
|
||||
void PhysXWorld::step(float fixedTimeStep) {
|
||||
_mScene->simulate(fixedTimeStep);
|
||||
_mScene->fetchResults(true);
|
||||
syncPhysicsToScene();
|
||||
#if CC_USE_GEOMETRY_RENDERER
|
||||
debugDraw();
|
||||
#endif
|
||||
}
|
||||
|
||||
#if CC_USE_GEOMETRY_RENDERER
|
||||
pipeline::GeometryRenderer* PhysXWorld::getDebugRenderer () {
|
||||
auto cameras = Root::getInstance()->getMainWindow()->getCameras();
|
||||
scene::Camera* camera = nullptr;
|
||||
for (int c = 0; c < cameras.size(); c++) {
|
||||
if (!cameras[c])
|
||||
continue;
|
||||
const bool defaultCamera = cameras[c]->getVisibility() & static_cast<uint32_t>(pipeline::LayerList::DEFAULT);
|
||||
if (defaultCamera) {
|
||||
camera = cameras[c];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (camera) {
|
||||
camera->initGeometryRenderer();
|
||||
return camera->getGeometryRenderer();
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void PhysXWorld::debugDraw () {
|
||||
pipeline::GeometryRenderer* debugRenderer = getDebugRenderer();
|
||||
if (!debugRenderer) return;
|
||||
_debugLineCount = 0;
|
||||
static Vec3 v0, v1;
|
||||
static gfx::Color c;
|
||||
auto& rb = _mScene->getRenderBuffer();
|
||||
// lines
|
||||
for (int i = 0; i < rb.getNbLines(); i++) {
|
||||
if (_debugLineCount < _MAX_DEBUG_LINE_COUNT){
|
||||
_debugLineCount++;
|
||||
const physx::PxDebugLine& line = rb.getLines()[i];
|
||||
pxSetColor(c, line.color0);
|
||||
pxSetVec3Ext(v0, line.pos0);
|
||||
pxSetVec3Ext(v1, line.pos1);
|
||||
debugRenderer->addLine(v0, v1, c);
|
||||
}
|
||||
}
|
||||
// triangles
|
||||
for (int i = 0; i < rb.getNbTriangles(); i++) {
|
||||
if (_debugLineCount < _MAX_DEBUG_LINE_COUNT - 3) {
|
||||
_debugLineCount = _debugLineCount + 3;
|
||||
const physx::PxDebugTriangle& triangle = rb.getTriangles()[i];
|
||||
pxSetColor(c, triangle.color0);
|
||||
pxSetVec3Ext(v0, triangle.pos0);
|
||||
pxSetVec3Ext(v1, triangle.pos1);
|
||||
debugRenderer->addLine(v0, v1, c);
|
||||
pxSetVec3Ext(v0, triangle.pos1);
|
||||
pxSetVec3Ext(v1, triangle.pos2);
|
||||
debugRenderer->addLine(v0, v1, c);
|
||||
pxSetVec3Ext(v0, triangle.pos2);
|
||||
pxSetVec3Ext(v1, triangle.pos0);
|
||||
debugRenderer->addLine(v0, v1, c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PhysXWorld::setDebugDrawMode() {
|
||||
if (uint32_t(_debugDrawFlags) & uint32_t(EPhysicsDrawFlags::WIRE_FRAME)) {
|
||||
_mScene->setVisualizationParameter(physx::PxVisualizationParameter::eCOLLISION_SHAPES, 1);
|
||||
} else {
|
||||
_mScene->setVisualizationParameter(physx::PxVisualizationParameter::eCOLLISION_SHAPES, 0);
|
||||
}
|
||||
|
||||
bool drawConstraint = bool(uint32_t(_debugDrawFlags) & uint32_t(EPhysicsDrawFlags::CONSTRAINT));
|
||||
float internalConstraintSize = drawConstraint ? _debugConstraintSize : 0;
|
||||
_mScene->setVisualizationParameter(physx::PxVisualizationParameter::eJOINT_LOCAL_FRAMES, internalConstraintSize);
|
||||
_mScene->setVisualizationParameter(physx::PxVisualizationParameter::eJOINT_LIMITS, internalConstraintSize);
|
||||
|
||||
if (uint32_t(_debugDrawFlags) & uint32_t(EPhysicsDrawFlags::AABB)) {
|
||||
_mScene->setVisualizationParameter(physx::PxVisualizationParameter::eCOLLISION_AABBS, 1);
|
||||
} else {
|
||||
_mScene->setVisualizationParameter(physx::PxVisualizationParameter::eCOLLISION_AABBS, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void PhysXWorld::setDebugDrawFlags(EPhysicsDrawFlags flags) {
|
||||
_debugDrawFlags = flags;
|
||||
setDebugDrawMode();
|
||||
}
|
||||
|
||||
EPhysicsDrawFlags PhysXWorld::getDebugDrawFlags() {
|
||||
return _debugDrawFlags;
|
||||
}
|
||||
|
||||
void PhysXWorld::setDebugDrawConstraintSize(float size) {
|
||||
_debugConstraintSize = size;
|
||||
setDebugDrawMode();
|
||||
}
|
||||
|
||||
float PhysXWorld::getDebugDrawConstraintSize() {
|
||||
return _debugConstraintSize;
|
||||
}
|
||||
#endif
|
||||
|
||||
void PhysXWorld::setGravity(float x, float y, float z) {
|
||||
_mScene->setGravity(physx::PxVec3(x, y, z));
|
||||
}
|
||||
|
||||
void PhysXWorld::destroy() {
|
||||
}
|
||||
|
||||
void PhysXWorld::setCollisionMatrix(uint32_t index, uint32_t mask) {
|
||||
if (index > 31) return;
|
||||
_mCollisionMatrix[index] = mask;
|
||||
}
|
||||
|
||||
uint32_t PhysXWorld::createConvex(ConvexDesc &desc) {
|
||||
physx::PxConvexMeshDesc convexDesc;
|
||||
convexDesc.points.count = desc.positionLength;
|
||||
convexDesc.points.stride = sizeof(physx::PxVec3);
|
||||
convexDesc.points.data = static_cast<physx::PxVec3 *>(desc.positions);
|
||||
convexDesc.flags = physx::PxConvexFlag::eCOMPUTE_CONVEX;
|
||||
physx::PxConvexMesh *convexMesh = getCooking().createConvexMesh(convexDesc, PxGetPhysics().getPhysicsInsertionCallback());
|
||||
uint32_t pxObjectID = addPXObject(reinterpret_cast<uintptr_t>(convexMesh));
|
||||
return pxObjectID;
|
||||
}
|
||||
|
||||
uint32_t PhysXWorld::createTrimesh(TrimeshDesc &desc) {
|
||||
physx::PxTriangleMeshDesc meshDesc;
|
||||
meshDesc.points.count = desc.positionLength;
|
||||
meshDesc.points.stride = sizeof(physx::PxVec3);
|
||||
meshDesc.points.data = static_cast<physx::PxVec3 *>(desc.positions);
|
||||
meshDesc.triangles.count = desc.triangleLength;
|
||||
if (desc.isU16) {
|
||||
meshDesc.triangles.stride = 3 * sizeof(physx::PxU16);
|
||||
meshDesc.triangles.data = static_cast<physx::PxU16 *>(desc.triangles);
|
||||
meshDesc.flags = physx::PxMeshFlag::e16_BIT_INDICES;
|
||||
} else {
|
||||
meshDesc.triangles.stride = 3 * sizeof(physx::PxU32);
|
||||
meshDesc.triangles.data = static_cast<physx::PxU32 *>(desc.triangles);
|
||||
}
|
||||
physx::PxTriangleMesh *triangleMesh = getCooking().createTriangleMesh(meshDesc, PxGetPhysics().getPhysicsInsertionCallback());
|
||||
uint32_t pxObjectID = addPXObject(reinterpret_cast<uintptr_t>(triangleMesh));
|
||||
return pxObjectID;
|
||||
}
|
||||
|
||||
uint32_t PhysXWorld::createHeightField(HeightFieldDesc &desc) {
|
||||
const auto rows = desc.rows;
|
||||
const auto columns = desc.columns;
|
||||
const physx::PxU32 counts = rows * columns;
|
||||
auto *samples = ccnew physx::PxHeightFieldSample[counts];
|
||||
for (physx::PxU32 r = 0; r < rows; r++) {
|
||||
for (physx::PxU32 c = 0; c < columns; c++) {
|
||||
const auto index = c + r * columns;
|
||||
auto v = (static_cast<int16_t *>(desc.samples))[index];
|
||||
samples[index].height = v;
|
||||
}
|
||||
}
|
||||
physx::PxHeightFieldDesc hfDesc;
|
||||
hfDesc.nbRows = rows;
|
||||
hfDesc.nbColumns = columns;
|
||||
hfDesc.samples.data = samples;
|
||||
hfDesc.samples.stride = sizeof(physx::PxHeightFieldSample);
|
||||
physx::PxHeightField *hf = getCooking().createHeightField(hfDesc, PxGetPhysics().getPhysicsInsertionCallback());
|
||||
delete[] samples;
|
||||
uint32_t pxObjectID = addPXObject(reinterpret_cast<uintptr_t>(hf));
|
||||
return pxObjectID;
|
||||
}
|
||||
|
||||
bool PhysXWorld::createMaterial(uint16_t id, float f, float df, float r,
|
||||
uint8_t m0, uint8_t m1) {
|
||||
physx::PxMaterial *mat;
|
||||
auto &m = getPxMaterialMap();
|
||||
if (m.find(id) == m.end()) {
|
||||
mat = PxGetPhysics().createMaterial(f, df, r);
|
||||
// add reference count avoid auto releasing by physx
|
||||
mat->acquireReference();
|
||||
m[id] = reinterpret_cast<uintptr_t>(mat);
|
||||
mat->setFrictionCombineMode(physx::PxCombineMode::Enum(m0));
|
||||
mat->setRestitutionCombineMode(physx::PxCombineMode::Enum(m1));
|
||||
} else {
|
||||
mat = reinterpret_cast<physx::PxMaterial *>(m[id]);
|
||||
mat->setStaticFriction(f);
|
||||
mat->setDynamicFriction(df);
|
||||
mat->setRestitution(r);
|
||||
mat->setFrictionCombineMode(physx::PxCombineMode::Enum(m0));
|
||||
mat->setRestitutionCombineMode(physx::PxCombineMode::Enum(m1));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
uintptr_t PhysXWorld::getPXMaterialPtrWithMaterialID(uint32_t materialID) {
|
||||
auto &m = getPxMaterialMap();
|
||||
auto const &it = m.find(materialID);
|
||||
if (it == m.end()) {
|
||||
return 0;
|
||||
} else {
|
||||
return it->second;
|
||||
}
|
||||
}
|
||||
|
||||
void PhysXWorld::emitEvents() {
|
||||
_mEventMgr->refreshPairs();
|
||||
}
|
||||
|
||||
void PhysXWorld::syncSceneToPhysics() {
|
||||
for (auto const &sb : _mSharedBodies) {
|
||||
sb->syncSceneToPhysics();
|
||||
}
|
||||
for (auto const &cct : _mCCTs) {
|
||||
cct->syncSceneToPhysics();
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t PhysXWorld::getMaskByIndex(uint32_t i) {
|
||||
if (i > 31) i = 0;
|
||||
return _mCollisionMatrix[i];
|
||||
}
|
||||
|
||||
void PhysXWorld::syncPhysicsToScene() {
|
||||
for (auto const &sb : _mSharedBodies) {
|
||||
sb->syncPhysicsToScene();
|
||||
}
|
||||
}
|
||||
|
||||
void PhysXWorld::syncSceneWithCheck() {
|
||||
for (auto const &sb : _mSharedBodies) {
|
||||
sb->syncSceneWithCheck();
|
||||
}
|
||||
}
|
||||
|
||||
void PhysXWorld::setAllowSleep(bool val) {
|
||||
}
|
||||
|
||||
void PhysXWorld::addActor(const PhysXSharedBody &sb) {
|
||||
auto beg = _mSharedBodies.begin();
|
||||
auto end = _mSharedBodies.end();
|
||||
auto iter = find(beg, end, &sb);
|
||||
if (iter == end) {
|
||||
_mScene->addActor(*(const_cast<PhysXSharedBody &>(sb).getImpl().rigidActor));
|
||||
_mSharedBodies.push_back(&const_cast<PhysXSharedBody &>(sb));
|
||||
}
|
||||
}
|
||||
|
||||
void PhysXWorld::removeActor(const PhysXSharedBody &sb) {
|
||||
auto beg = _mSharedBodies.begin();
|
||||
auto end = _mSharedBodies.end();
|
||||
auto iter = find(beg, end, &sb);
|
||||
if (iter != end) {
|
||||
_mScene->removeActor(*(const_cast<PhysXSharedBody &>(sb).getImpl().rigidActor), true);
|
||||
_mSharedBodies.erase(iter);
|
||||
}
|
||||
}
|
||||
|
||||
void PhysXWorld::addCCT (const PhysXCharacterController &cct) {
|
||||
auto beg = _mCCTs.begin();
|
||||
auto end = _mCCTs.end();
|
||||
auto iter = find(beg, end, &cct);
|
||||
if (iter == end) {
|
||||
_mCCTs.push_back(&const_cast<PhysXCharacterController &>(cct));
|
||||
}
|
||||
}
|
||||
|
||||
void PhysXWorld::removeCCT(const PhysXCharacterController&cct) {
|
||||
auto beg = _mCCTs.begin();
|
||||
auto end = _mCCTs.end();
|
||||
auto iter = find(beg, end, &cct);
|
||||
if (iter != end) {
|
||||
_mCCTs.erase(iter);
|
||||
}
|
||||
}
|
||||
|
||||
bool PhysXWorld::raycast(RaycastOptions &opt) {
|
||||
physx::PxQueryCache *cache = nullptr;
|
||||
const auto o = opt.origin;
|
||||
const auto ud = opt.unitDir;
|
||||
physx::PxVec3 origin{o.x, o.y, o.z};
|
||||
physx::PxVec3 unitDir{ud.x, ud.y, ud.z};
|
||||
unitDir.normalize();
|
||||
physx::PxHitFlags flags = physx::PxHitFlag::ePOSITION | physx::PxHitFlag::eNORMAL;
|
||||
physx::PxSceneQueryFilterData filterData;
|
||||
filterData.data.word0 = opt.mask;
|
||||
filterData.data.word3 = QUERY_FILTER | (opt.queryTrigger ? 0 : QUERY_CHECK_TRIGGER);
|
||||
filterData.flags = physx::PxQueryFlag::eSTATIC | physx::PxQueryFlag::eDYNAMIC | physx::PxQueryFlag::ePREFILTER;
|
||||
auto &hitBuffer = getPxRaycastHitBuffer();
|
||||
bool result = false;
|
||||
const auto nbTouches = physx::PxSceneQueryExt::raycastMultiple(
|
||||
getScene(), origin, unitDir, opt.distance, flags, hitBuffer.data(),
|
||||
static_cast<physx::PxU32>(hitBuffer.size()), result, filterData, &getQueryFilterShader(), cache);
|
||||
if (nbTouches == 0 || nbTouches == -1) return false;
|
||||
auto &r = raycastResult();
|
||||
r.resize(nbTouches);
|
||||
for (physx::PxI32 i = 0; i < nbTouches; i++) {
|
||||
const auto &shapeIter = getPxShapeMap().find(reinterpret_cast<uintptr_t>(hitBuffer[i].shape));
|
||||
if (shapeIter == getPxShapeMap().end()) return false;
|
||||
r[i].shape = shapeIter->second;
|
||||
r[i].distance = hitBuffer[i].distance;
|
||||
pxSetVec3Ext(r[i].hitNormal, hitBuffer[i].normal);
|
||||
pxSetVec3Ext(r[i].hitPoint, hitBuffer[i].position);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
ccstd::vector<RaycastResult> &PhysXWorld::raycastResult() {
|
||||
static ccstd::vector<RaycastResult> hits;
|
||||
return hits;
|
||||
}
|
||||
|
||||
bool PhysXWorld::raycastClosest(RaycastOptions &opt) {
|
||||
physx::PxRaycastHit hit;
|
||||
physx::PxQueryCache *cache = nullptr;
|
||||
const auto o = opt.origin;
|
||||
const auto ud = opt.unitDir;
|
||||
physx::PxVec3 origin{o.x, o.y, o.z};
|
||||
physx::PxVec3 unitDir{ud.x, ud.y, ud.z};
|
||||
unitDir.normalize();
|
||||
physx::PxHitFlags flags = physx::PxHitFlag::ePOSITION | physx::PxHitFlag::eNORMAL;
|
||||
physx::PxSceneQueryFilterData filterData;
|
||||
filterData.data.word0 = opt.mask;
|
||||
filterData.data.word3 = QUERY_FILTER | (opt.queryTrigger ? 0 : QUERY_CHECK_TRIGGER) | QUERY_SINGLE_HIT;
|
||||
filterData.flags = physx::PxQueryFlag::eSTATIC | physx::PxQueryFlag::eDYNAMIC | physx::PxQueryFlag::ePREFILTER;
|
||||
const auto result = physx::PxSceneQueryExt::raycastSingle(
|
||||
getScene(), origin, unitDir, opt.distance, flags,
|
||||
hit, filterData, &getQueryFilterShader(), cache);
|
||||
if (result) {
|
||||
auto &r = raycastClosestResult();
|
||||
const auto &shapeIter = getPxShapeMap().find(reinterpret_cast<uintptr_t>(hit.shape));
|
||||
if (shapeIter == getPxShapeMap().end()) return false;
|
||||
r.shape = shapeIter->second;
|
||||
r.distance = hit.distance;
|
||||
pxSetVec3Ext(r.hitPoint, hit.position);
|
||||
pxSetVec3Ext(r.hitNormal, hit.normal);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
RaycastResult &PhysXWorld::raycastClosestResult() {
|
||||
static RaycastResult hit;
|
||||
return hit;
|
||||
}
|
||||
|
||||
bool PhysXWorld::sweepBox(RaycastOptions &opt, float halfExtentX, float halfExtentY, float halfExtentZ,
|
||||
float orientationW, float orientationX, float orientationY, float orientationZ) {
|
||||
return sweep(opt, physx::PxBoxGeometry{ halfExtentX, halfExtentY, halfExtentZ},
|
||||
physx::PxQuat(orientationX, orientationY, orientationZ, orientationW));
|
||||
}
|
||||
|
||||
bool PhysXWorld::sweepBoxClosest(RaycastOptions &opt, float halfExtentX, float halfExtentY, float halfExtentZ,
|
||||
float orientationW, float orientationX, float orientationY, float orientationZ) {
|
||||
return sweepClosest(opt, physx::PxBoxGeometry{ halfExtentX, halfExtentY, halfExtentZ},
|
||||
physx::PxQuat(orientationX, orientationY, orientationZ, orientationW));
|
||||
}
|
||||
|
||||
bool PhysXWorld::sweepSphere(RaycastOptions &opt, float radius) {
|
||||
return sweep(opt, physx::PxSphereGeometry{ radius }, physx::PxQuat(0, 0, 0, 1));
|
||||
}
|
||||
|
||||
bool PhysXWorld::sweepSphereClosest(RaycastOptions &opt, float radius) {
|
||||
return sweepClosest(opt, physx::PxSphereGeometry{ radius }, physx::PxQuat(0, 0, 0, 1));
|
||||
}
|
||||
|
||||
bool PhysXWorld::sweepCapsule(RaycastOptions &opt, float radius, float height,
|
||||
float orientationW, float orientationX, float orientationY, float orientationZ) {
|
||||
//add an extra 90 degree rotation to PxCapsuleGeometry whose axis is originally along the X axis
|
||||
physx::PxQuat finalOrientation = physx::PxQuat(physx::PxPiDivTwo, physx::PxVec3{0.F, 0.F, 1.F});
|
||||
finalOrientation = physx::PxQuat(orientationX, orientationY, orientationZ, orientationW) * finalOrientation;
|
||||
return sweep(opt, physx::PxCapsuleGeometry{ radius, height/2.f }, finalOrientation);
|
||||
}
|
||||
|
||||
bool PhysXWorld::sweepCapsuleClosest(RaycastOptions &opt, float radius, float height,
|
||||
float orientationW, float orientationX, float orientationY, float orientationZ) {
|
||||
//add an extra 90 degree rotation to PxCapsuleGeometry whose axis is originally along the X axis
|
||||
physx::PxQuat finalOrientation = physx::PxQuat(physx::PxPiDivTwo, physx::PxVec3{0.F, 0.F, 1.F});
|
||||
finalOrientation = physx::PxQuat(orientationX, orientationY, orientationZ, orientationW) * finalOrientation;
|
||||
return sweepClosest(opt, physx::PxCapsuleGeometry{ radius, height/2.f }, finalOrientation);
|
||||
}
|
||||
|
||||
bool PhysXWorld::sweep(RaycastOptions &opt, const physx::PxGeometry &geometry, const physx::PxQuat &orientation) {
|
||||
physx::PxQueryCache *cache = nullptr;
|
||||
const auto o = opt.origin;
|
||||
const auto ud = opt.unitDir;
|
||||
physx::PxVec3 origin{o.x, o.y, o.z};
|
||||
physx::PxVec3 unitDir{ud.x, ud.y, ud.z};
|
||||
unitDir.normalize();
|
||||
physx::PxTransform pose{origin, orientation};
|
||||
physx::PxHitFlags flags = physx::PxHitFlag::ePOSITION | physx::PxHitFlag::eNORMAL;
|
||||
physx::PxSceneQueryFilterData filterData;
|
||||
filterData.data.word0 = opt.mask;
|
||||
filterData.data.word3 = QUERY_FILTER | (opt.queryTrigger ? 0 : QUERY_CHECK_TRIGGER);
|
||||
filterData.flags = physx::PxQueryFlag::eSTATIC | physx::PxQueryFlag::eDYNAMIC | physx::PxQueryFlag::ePREFILTER;
|
||||
auto &hitBuffer = getPxSweepHitBuffer();
|
||||
bool result = false;
|
||||
const auto nbTouches = physx::PxSceneQueryExt::sweepMultiple(
|
||||
getScene(), geometry, pose, unitDir, opt.distance, flags, hitBuffer.data(),
|
||||
static_cast<physx::PxU32>(hitBuffer.size()), result, filterData, &getQueryFilterShader(), cache);
|
||||
if (nbTouches == 0 || nbTouches == -1) return false;
|
||||
auto &r = sweepResult();
|
||||
r.resize(nbTouches);
|
||||
for (physx::PxI32 i = 0; i < nbTouches; i++) {
|
||||
const auto &shapeIter = getPxShapeMap().find(reinterpret_cast<uintptr_t>(hitBuffer[i].shape));
|
||||
if (shapeIter == getPxShapeMap().end()) return false;
|
||||
r[i].shape = shapeIter->second;
|
||||
r[i].distance = hitBuffer[i].distance;
|
||||
pxSetVec3Ext(r[i].hitNormal, hitBuffer[i].normal);
|
||||
pxSetVec3Ext(r[i].hitPoint, hitBuffer[i].position);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
ccstd::vector<RaycastResult> &PhysXWorld::sweepResult() {
|
||||
static ccstd::vector<RaycastResult> hits;
|
||||
return hits;
|
||||
}
|
||||
|
||||
bool PhysXWorld::sweepClosest(RaycastOptions &opt, const physx::PxGeometry &geometry, const physx::PxQuat &orientation) {
|
||||
physx::PxSweepHit hit;
|
||||
physx::PxQueryCache *cache = nullptr;
|
||||
const auto o = opt.origin;
|
||||
const auto ud = opt.unitDir;
|
||||
physx::PxVec3 origin{o.x, o.y, o.z};
|
||||
physx::PxVec3 unitDir{ud.x, ud.y, ud.z};
|
||||
unitDir.normalize();
|
||||
physx::PxTransform pose{origin, orientation};
|
||||
physx::PxHitFlags flags = physx::PxHitFlag::ePOSITION | physx::PxHitFlag::eNORMAL;
|
||||
physx::PxSceneQueryFilterData filterData;
|
||||
filterData.data.word0 = opt.mask;
|
||||
filterData.data.word3 = QUERY_FILTER | (opt.queryTrigger ? 0 : QUERY_CHECK_TRIGGER) | QUERY_SINGLE_HIT;
|
||||
filterData.flags = physx::PxQueryFlag::eSTATIC | physx::PxQueryFlag::eDYNAMIC | physx::PxQueryFlag::ePREFILTER;
|
||||
const auto result = physx::PxSceneQueryExt::sweepSingle(
|
||||
getScene(), geometry, pose, unitDir, opt.distance, flags,
|
||||
hit, filterData, &getQueryFilterShader(), cache, 0);
|
||||
if (result) {
|
||||
auto &r = sweepClosestResult();
|
||||
const auto &shapeIter = getPxShapeMap().find(reinterpret_cast<uintptr_t>(hit.shape));
|
||||
if (shapeIter == getPxShapeMap().end()) return false;
|
||||
r.shape = shapeIter->second;
|
||||
r.distance = hit.distance;
|
||||
pxSetVec3Ext(r.hitPoint, hit.position);
|
||||
pxSetVec3Ext(r.hitNormal, hit.normal);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
RaycastResult &PhysXWorld::sweepClosestResult() {
|
||||
static RaycastResult hit;
|
||||
return hit;
|
||||
}
|
||||
|
||||
uint32_t PhysXWorld::addPXObject(uintptr_t PXObjectPtr) {
|
||||
uint32_t pxObjectID = _msPXObjectID;
|
||||
_msPXObjectID++;
|
||||
assert(_msPXObjectID < 0xffffffff);
|
||||
|
||||
_mPXObjects[pxObjectID] = PXObjectPtr;
|
||||
return pxObjectID;
|
||||
};
|
||||
|
||||
void PhysXWorld::removePXObject(uint32_t pxObjectID) {
|
||||
_mPXObjects.erase(pxObjectID);
|
||||
}
|
||||
|
||||
uintptr_t PhysXWorld::getPXPtrWithPXObjectID(uint32_t pxObjectID) {
|
||||
auto const &iter = _mPXObjects.find(pxObjectID);
|
||||
if (iter == _mPXObjects.end()) {
|
||||
return 0;
|
||||
}
|
||||
return iter->second;
|
||||
};
|
||||
|
||||
uint32_t PhysXWorld::addWrapperObject(uintptr_t wrapperObjectPtr) {
|
||||
uint32_t wrapprtObjectID = _msWrapperObjectID;
|
||||
_msWrapperObjectID++;
|
||||
assert(_msWrapperObjectID < 0xffffffff);
|
||||
|
||||
_mWrapperObjects[wrapprtObjectID] = wrapperObjectPtr;
|
||||
return wrapprtObjectID;
|
||||
};
|
||||
|
||||
void PhysXWorld::removeWrapperObject(uint32_t wrapperObjectID) {
|
||||
_mWrapperObjects.erase(wrapperObjectID);
|
||||
}
|
||||
|
||||
uintptr_t PhysXWorld::getWrapperPtrWithObjectID(uint32_t wrapperObjectID) {
|
||||
if (wrapperObjectID == 0) {
|
||||
return 0;
|
||||
}
|
||||
auto const &iter = _mWrapperObjects.find(wrapperObjectID);
|
||||
if (iter == _mWrapperObjects.end())
|
||||
return 0;
|
||||
return iter->second;
|
||||
};
|
||||
|
||||
} // namespace physics
|
||||
} // namespace cc
|
||||
177
cocos/physics/physx/PhysXWorld.h
Normal file
177
cocos/physics/physx/PhysXWorld.h
Normal file
@@ -0,0 +1,177 @@
|
||||
/****************************************************************************
|
||||
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 <memory>
|
||||
#include "base/Macros.h"
|
||||
#include "base/std/container/vector.h"
|
||||
#include "core/scene-graph/Node.h"
|
||||
#include "physics/physx/PhysXEventManager.h"
|
||||
#include "physics/physx/PhysXFilterShader.h"
|
||||
#include "physics/physx/PhysXInc.h"
|
||||
#include "physics/physx/PhysXRigidBody.h"
|
||||
#include "physics/physx/PhysXSharedBody.h"
|
||||
#include "physics/physx/character-controllers/PhysXCharacterController.h"
|
||||
#include "physics/spec/IWorld.h"
|
||||
#include "renderer/pipeline/GeometryRenderer.h"
|
||||
|
||||
namespace cc {
|
||||
namespace physics {
|
||||
|
||||
class PhysXWorld final : virtual public IPhysicsWorld {
|
||||
public:
|
||||
static PhysXWorld &getInstance();
|
||||
static physx::PxFoundation &getFundation();
|
||||
static physx::PxCooking &getCooking();
|
||||
static physx::PxPhysics &getPhysics();
|
||||
static physx::PxControllerManager &getControllerManager();
|
||||
|
||||
PhysXWorld();
|
||||
~PhysXWorld() override;
|
||||
void step(float fixedTimeStep) override;
|
||||
void setGravity(float x, float y, float z) override;
|
||||
void setAllowSleep(bool v) override;
|
||||
void emitEvents() override;
|
||||
void setCollisionMatrix(uint32_t index, uint32_t mask) override;
|
||||
bool raycast(RaycastOptions &opt) override;
|
||||
bool raycastClosest(RaycastOptions &opt) override;
|
||||
ccstd::vector<RaycastResult> &raycastResult() override;
|
||||
RaycastResult &raycastClosestResult() override;
|
||||
|
||||
bool sweep(RaycastOptions &opt, const physx::PxGeometry &geometry, const physx::PxQuat &orientation);
|
||||
bool sweepClosest(RaycastOptions &opt, const physx::PxGeometry &geometry, const physx::PxQuat &orientation);
|
||||
bool sweepBox(RaycastOptions &opt, float halfExtentX, float halfExtentY, float halfExtentZ,
|
||||
float orientationW, float orientationX, float orientationY, float orientationZ) override;
|
||||
bool sweepBoxClosest(RaycastOptions &opt, float halfExtentX, float halfExtentY, float halfExtentZ,
|
||||
float orientationW, float orientationX, float orientationY, float orientationZ) override;
|
||||
bool sweepSphere(RaycastOptions &opt, float radius) override;
|
||||
bool sweepSphereClosest(RaycastOptions &opt, float radius) override;
|
||||
bool sweepCapsule(RaycastOptions &opt, float radius, float height,
|
||||
float orientationW, float orientationX, float orientationY, float orientationZ) override;
|
||||
bool sweepCapsuleClosest(RaycastOptions &opt, float radius, float height,
|
||||
float orientationW, float orientationX, float orientationY, float orientationZ) override;
|
||||
ccstd::vector<RaycastResult> &sweepResult() override;
|
||||
RaycastResult &sweepClosestResult() override;
|
||||
|
||||
uint32_t createConvex(ConvexDesc &desc) override;
|
||||
uint32_t createTrimesh(TrimeshDesc &desc) override;
|
||||
uint32_t createHeightField(HeightFieldDesc &desc) override;
|
||||
bool createMaterial(uint16_t id, float f, float df, float r,
|
||||
uint8_t m0, uint8_t m1) override;
|
||||
inline ccstd::vector<std::shared_ptr<TriggerEventPair>> &getTriggerEventPairs() override {
|
||||
return _mEventMgr->getTriggerPairs();
|
||||
}
|
||||
inline ccstd::vector<std::shared_ptr<ContactEventPair>> &getContactEventPairs() override {
|
||||
return _mEventMgr->getConatctPairs();
|
||||
}
|
||||
inline ccstd::vector<std::shared_ptr<CCTShapeEventPair>> &getCCTShapeEventPairs() override {
|
||||
return _mEventMgr->getCCTShapePairs();
|
||||
}
|
||||
inline ccstd::vector<std::shared_ptr<CCTTriggerEventPair>> &getCCTTriggerEventPairs() override {
|
||||
return _mEventMgr->getCCTTriggerPairs();
|
||||
}
|
||||
void syncSceneToPhysics() override;
|
||||
void syncSceneWithCheck() override;
|
||||
void destroy() override;
|
||||
|
||||
inline PhysXSharedBody *getSharedBody(
|
||||
const Node *node,
|
||||
PhysXRigidBody *const body = nullptr) {
|
||||
return PhysXSharedBody::getSharedBody(node, this, body);
|
||||
}
|
||||
|
||||
inline physx::PxScene &getScene() const { return *_mScene; }
|
||||
uint32_t getMaskByIndex(uint32_t i);
|
||||
void syncPhysicsToScene();
|
||||
void addActor(const PhysXSharedBody &sb);
|
||||
void removeActor(const PhysXSharedBody &sb);
|
||||
void addCCT(const PhysXCharacterController &cct);
|
||||
void removeCCT(const PhysXCharacterController &cct);
|
||||
|
||||
// Mapping PhysX Object ID and Pointer
|
||||
uint32_t addPXObject(uintptr_t PXObjectPtr);
|
||||
void removePXObject(uint32_t pxObjectID);
|
||||
uintptr_t getPXPtrWithPXObjectID(uint32_t pxObjectID);
|
||||
|
||||
// Mapping Wrapper PhysX Object ID and Pointer
|
||||
uint32_t addWrapperObject(uintptr_t wrapperObjectPtr);
|
||||
void removeWrapperObject(uint32_t wrapperObjectID);
|
||||
uintptr_t getWrapperPtrWithObjectID(uint32_t wrapperObjectID);
|
||||
|
||||
uintptr_t getPXMaterialPtrWithMaterialID(uint32_t materialID);
|
||||
|
||||
float getFixedTimeStep() const override { return _fixedTimeStep; }
|
||||
void setFixedTimeStep(float fixedTimeStep) override { _fixedTimeStep = fixedTimeStep; }
|
||||
|
||||
#if CC_USE_GEOMETRY_RENDERER
|
||||
void setDebugDrawFlags(EPhysicsDrawFlags flags) override;
|
||||
EPhysicsDrawFlags getDebugDrawFlags() override;
|
||||
|
||||
void setDebugDrawConstraintSize(float size) override;
|
||||
float getDebugDrawConstraintSize() override;
|
||||
|
||||
private:
|
||||
pipeline::GeometryRenderer *getDebugRenderer();
|
||||
void debugDraw();
|
||||
void setDebugDrawMode();
|
||||
#else
|
||||
void setDebugDrawFlags(EPhysicsDrawFlags flags) override{};
|
||||
EPhysicsDrawFlags getDebugDrawFlags() override { return EPhysicsDrawFlags::NONE; };
|
||||
|
||||
void setDebugDrawConstraintSize(float size) override{};
|
||||
float getDebugDrawConstraintSize() override { return 0.0; };
|
||||
#endif
|
||||
private:
|
||||
static PhysXWorld *instance;
|
||||
physx::PxFoundation *_mFoundation;
|
||||
physx::PxCooking *_mCooking;
|
||||
physx::PxPhysics *_mPhysics;
|
||||
physx::PxControllerManager *_mControllerManager = NULL;
|
||||
|
||||
#ifdef CC_DEBUG
|
||||
physx::PxPvd *_mPvd;
|
||||
#endif
|
||||
physx::PxDefaultCpuDispatcher *_mDispatcher;
|
||||
physx::PxScene *_mScene;
|
||||
PhysXEventManager *_mEventMgr;
|
||||
uint32_t _mCollisionMatrix[31];
|
||||
ccstd::vector<PhysXSharedBody *> _mSharedBodies;
|
||||
ccstd::vector<PhysXCharacterController *> _mCCTs;
|
||||
|
||||
static uint32_t _msWrapperObjectID;
|
||||
static uint32_t _msPXObjectID;
|
||||
ccstd::unordered_map<uint32_t, uintptr_t> _mPXObjects;
|
||||
ccstd::unordered_map<uint32_t, uintptr_t> _mWrapperObjects;
|
||||
|
||||
float _fixedTimeStep{1 / 60.0F};
|
||||
|
||||
uint32_t _debugLineCount = 0;
|
||||
uint32_t _MAX_DEBUG_LINE_COUNT = 16384;
|
||||
EPhysicsDrawFlags _debugDrawFlags = EPhysicsDrawFlags::NONE;
|
||||
float _debugConstraintSize = 0.3;
|
||||
};
|
||||
|
||||
} // namespace physics
|
||||
} // namespace cc
|
||||
@@ -0,0 +1,104 @@
|
||||
/****************************************************************************
|
||||
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/character-controllers/PhysXBoxCharacterController.h"
|
||||
#include "physics/physx/PhysXUtils.h"
|
||||
#include "physics/physx/PhysXWorld.h"
|
||||
#include "math/Utils.h"
|
||||
|
||||
namespace cc {
|
||||
namespace physics {
|
||||
PhysXBoxCharacterController::PhysXBoxCharacterController() :
|
||||
_mHalfHeight(0.5F), _mHalfSideExtent(0.5F), _mHalfForwardExtent(0.5F) {
|
||||
}
|
||||
|
||||
void PhysXBoxCharacterController::setHalfHeight(float v) {
|
||||
_mHalfHeight = v;
|
||||
updateScale();
|
||||
}
|
||||
|
||||
void PhysXBoxCharacterController::setHalfSideExtent(float v) {
|
||||
_mHalfSideExtent = v;
|
||||
updateScale();
|
||||
}
|
||||
|
||||
void PhysXBoxCharacterController::setHalfForwardExtent(float v) {
|
||||
_mHalfForwardExtent = v;
|
||||
updateScale();
|
||||
}
|
||||
|
||||
void PhysXBoxCharacterController::onComponentSet() {
|
||||
create();
|
||||
}
|
||||
|
||||
void PhysXBoxCharacterController::create() {
|
||||
release();
|
||||
|
||||
physx::PxControllerManager& controllerManager = PhysXWorld::getInstance().getControllerManager();
|
||||
auto pxMtl = reinterpret_cast<physx::PxMaterial *>(PhysXWorld::getInstance().getPXMaterialPtrWithMaterialID(0));
|
||||
|
||||
physx::PxBoxControllerDesc boxDesc;
|
||||
boxDesc.halfHeight = _mHalfSideExtent;
|
||||
boxDesc.halfSideExtent = _mHalfSideExtent;
|
||||
boxDesc.halfForwardExtent = _mHalfForwardExtent;
|
||||
boxDesc.density = 10.0;
|
||||
boxDesc.scaleCoeff = 0.8;
|
||||
boxDesc.volumeGrowth = 1.5;
|
||||
boxDesc.contactOffset = fmaxf(0.f, _mContactOffset);
|
||||
boxDesc.stepOffset = _mStepOffset;
|
||||
boxDesc.slopeLimit = cos(_mSlopeLimit * mathutils::D2R);
|
||||
boxDesc.upDirection = physx::PxVec3(0, 1, 0);
|
||||
//node is at capsule's center
|
||||
Vec3 worldPos = _mNode->getWorldPosition();
|
||||
worldPos += scaledCenter();
|
||||
boxDesc.position = physx::PxExtendedVec3(worldPos.x, worldPos.y, worldPos.z);
|
||||
boxDesc.material = pxMtl;
|
||||
boxDesc.userData = this;
|
||||
boxDesc.reportCallback = &report;
|
||||
_impl = static_cast<physx::PxBoxController*>(controllerManager.createController(boxDesc));
|
||||
|
||||
updateScale();
|
||||
insertToCCTMap();
|
||||
updateFilterData();
|
||||
}
|
||||
|
||||
void PhysXBoxCharacterController::updateScale(){
|
||||
updateGeometry();
|
||||
}
|
||||
|
||||
void PhysXBoxCharacterController::updateGeometry(){
|
||||
if(!_impl) return;
|
||||
|
||||
auto *node = _mNode;
|
||||
node->updateWorldTransform();
|
||||
float s = _mHalfSideExtent * physx::PxAbs(node->getWorldScale().x);
|
||||
float h = _mHalfHeight * physx::PxAbs(node->getWorldScale().y);
|
||||
float f = _mHalfForwardExtent * physx::PxAbs(node->getWorldScale().z);
|
||||
static_cast<physx::PxBoxController*>(_impl)->setHalfSideExtent(physx::PxMax(s, PX_NORMALIZATION_EPSILON));
|
||||
static_cast<physx::PxBoxController*>(_impl)->setHalfHeight(physx::PxMax(h, PX_NORMALIZATION_EPSILON));
|
||||
static_cast<physx::PxBoxController*>(_impl)->setHalfForwardExtent(physx::PxMax(f, PX_NORMALIZATION_EPSILON));
|
||||
}
|
||||
|
||||
} // namespace physics
|
||||
} // namespace cc
|
||||
@@ -0,0 +1,54 @@
|
||||
/****************************************************************************
|
||||
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/character-controllers/PhysXCharacterController.h"
|
||||
|
||||
namespace cc {
|
||||
namespace physics {
|
||||
|
||||
class PhysXBoxCharacterController final : public PhysXCharacterController, public IBoxCharacterController {
|
||||
public:
|
||||
PhysXBoxCharacterController();
|
||||
~PhysXBoxCharacterController() override = default;
|
||||
|
||||
// IBoxCharacterController
|
||||
void setHalfHeight(float v) override;
|
||||
void setHalfSideExtent(float v) override;
|
||||
void setHalfForwardExtent(float v) override;
|
||||
// IBoxCharacterController END
|
||||
|
||||
private:
|
||||
float _mHalfHeight;
|
||||
float _mHalfSideExtent;
|
||||
float _mHalfForwardExtent;
|
||||
void create() override;
|
||||
void onComponentSet() override;
|
||||
void updateScale() override;
|
||||
void updateGeometry();
|
||||
};
|
||||
|
||||
} // namespace physics
|
||||
} // namespace cc
|
||||
@@ -0,0 +1,97 @@
|
||||
/****************************************************************************
|
||||
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/character-controllers/PhysXCapsuleCharacterController.h"
|
||||
#include "physics/physx/PhysXUtils.h"
|
||||
#include "physics/physx/PhysXWorld.h"
|
||||
#include "math/Utils.h"
|
||||
|
||||
namespace cc {
|
||||
namespace physics {
|
||||
PhysXCapsuleCharacterController::PhysXCapsuleCharacterController() :
|
||||
_mRadius(0.5F), _mHeight(1.0F) {
|
||||
}
|
||||
|
||||
void PhysXCapsuleCharacterController::setRadius(float v) {
|
||||
_mRadius = v;
|
||||
updateScale();
|
||||
}
|
||||
|
||||
void PhysXCapsuleCharacterController::setHeight(float v) {
|
||||
_mHeight = v;
|
||||
updateScale();
|
||||
}
|
||||
|
||||
void PhysXCapsuleCharacterController::onComponentSet() {
|
||||
create();
|
||||
}
|
||||
|
||||
void PhysXCapsuleCharacterController::create() {
|
||||
release();
|
||||
|
||||
physx::PxControllerManager& controllerManager = PhysXWorld::getInstance().getControllerManager();
|
||||
auto pxMtl = reinterpret_cast<physx::PxMaterial *>(PhysXWorld::getInstance().getPXMaterialPtrWithMaterialID(0));
|
||||
|
||||
physx::PxCapsuleControllerDesc capsuleDesc;
|
||||
capsuleDesc.height = _mHeight;
|
||||
capsuleDesc.radius = _mRadius;
|
||||
capsuleDesc.climbingMode = physx::PxCapsuleClimbingMode::eCONSTRAINED;
|
||||
capsuleDesc.density = 10.0;
|
||||
capsuleDesc.scaleCoeff = 0.8;
|
||||
capsuleDesc.volumeGrowth = 1.5;
|
||||
capsuleDesc.contactOffset = fmaxf(0.f, _mContactOffset);
|
||||
capsuleDesc.stepOffset = _mStepOffset;
|
||||
capsuleDesc.slopeLimit = cos(_mSlopeLimit * mathutils::D2R);
|
||||
capsuleDesc.upDirection = physx::PxVec3(0, 1, 0);
|
||||
//node is at capsule's center
|
||||
Vec3 worldPos = _mNode->getWorldPosition();
|
||||
worldPos += scaledCenter();
|
||||
capsuleDesc.position = physx::PxExtendedVec3(worldPos.x, worldPos.y, worldPos.z);
|
||||
capsuleDesc.material = pxMtl;
|
||||
capsuleDesc.userData = this;
|
||||
capsuleDesc.reportCallback = &report;
|
||||
_impl = static_cast<physx::PxCapsuleController*>(controllerManager.createController(capsuleDesc));
|
||||
|
||||
updateScale();
|
||||
insertToCCTMap();
|
||||
updateFilterData();
|
||||
}
|
||||
|
||||
void PhysXCapsuleCharacterController::updateScale(){
|
||||
updateGeometry();
|
||||
}
|
||||
|
||||
void PhysXCapsuleCharacterController::updateGeometry() {
|
||||
if(!_impl) return;
|
||||
|
||||
auto *node = _mNode;
|
||||
node->updateWorldTransform();
|
||||
float r = _mRadius * pxAbsMax(node->getWorldScale().x, node->getWorldScale().z);
|
||||
float h = _mHeight * physx::PxAbs(node->getWorldScale().y);
|
||||
static_cast<physx::PxCapsuleController*>(_impl)->setRadius(physx::PxMax(r, PX_NORMALIZATION_EPSILON));
|
||||
static_cast<physx::PxCapsuleController*>(_impl)->setHeight(physx::PxMax(h, PX_NORMALIZATION_EPSILON));
|
||||
}
|
||||
|
||||
} // namespace physics
|
||||
} // namespace cc
|
||||
@@ -0,0 +1,52 @@
|
||||
/****************************************************************************
|
||||
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/character-controllers/PhysXCharacterController.h"
|
||||
|
||||
namespace cc {
|
||||
namespace physics {
|
||||
|
||||
class PhysXCapsuleCharacterController final : public PhysXCharacterController, public ICapsuleCharacterController {
|
||||
public:
|
||||
PhysXCapsuleCharacterController();
|
||||
~PhysXCapsuleCharacterController() override = default;
|
||||
|
||||
// ICapsuleCharacterController
|
||||
void setRadius(float v) override;
|
||||
void setHeight(float v) override;
|
||||
// ICapsuleCharacterController END
|
||||
|
||||
private:
|
||||
float _mRadius;
|
||||
float _mHeight;
|
||||
void create() override;
|
||||
void onComponentSet() override;
|
||||
void updateScale() override;
|
||||
void updateGeometry();
|
||||
};
|
||||
|
||||
} // namespace physics
|
||||
} // namespace cc
|
||||
@@ -0,0 +1,288 @@
|
||||
/****************************************************************************
|
||||
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/character-controllers/PhysXCharacterController.h"
|
||||
#include "base/std/container/unordered_map.h"
|
||||
#include "physics/physx/shapes/PhysXShape.h"
|
||||
#include "physics/physx/PhysXUtils.h"
|
||||
#include "physics/physx/PhysXWorld.h"
|
||||
|
||||
namespace cc {
|
||||
namespace physics {
|
||||
|
||||
//PxShape --> PhysXShape
|
||||
static PhysXShape* convertPxShape2PhysXShape(physx::PxShape* shape) {
|
||||
//PxShape --> PhysXShape ID
|
||||
const auto& hitShape = getPxShapeMap().find(reinterpret_cast<uintptr_t>(shape));
|
||||
if (hitShape == getPxShapeMap().end()) {
|
||||
return nullptr;
|
||||
}
|
||||
//PhysXShape ID --> PhysXShape pointer
|
||||
uintptr_t wrapperPtrShape = PhysXWorld::getInstance().getWrapperPtrWithObjectID(hitShape->second);
|
||||
if (wrapperPtrShape == 0) {
|
||||
return nullptr;
|
||||
}
|
||||
return reinterpret_cast<PhysXShape*>(wrapperPtrShape);
|
||||
}
|
||||
|
||||
void ControllerHitReport::onShapeHit(const physx::PxControllerShapeHit& hit) {
|
||||
const auto& hitShape = getPxShapeMap().find(reinterpret_cast<uintptr_t>(hit.shape));
|
||||
assert(hitShape!= getPxShapeMap().end());
|
||||
uint32_t shapeObjectID = hitShape->second;
|
||||
|
||||
const auto& cct = getPxCCTMap().find(reinterpret_cast<uintptr_t>(hit.controller));
|
||||
assert(cct != getPxCCTMap().end());
|
||||
uint32_t cctObjectID = cct->second;
|
||||
|
||||
CharacterControllerContact contact;
|
||||
contact.worldPosition = cc::Vec3(hit.worldPos.x, hit.worldPos.y, hit.worldPos.z);
|
||||
contact.worldNormal = cc::Vec3(hit.worldNormal.x, hit.worldNormal.y, hit.worldNormal.z);
|
||||
contact.motionDirection = cc::Vec3(hit.dir.x, hit.dir.y, hit.dir.z);
|
||||
contact.motionLength = hit.length;
|
||||
|
||||
std::shared_ptr<CCTShapeEventPair> pair = std::make_shared<CCTShapeEventPair>(cctObjectID, shapeObjectID);
|
||||
pair->contacts.push_back(contact);
|
||||
|
||||
auto& pairs = PhysXWorld::getInstance().getCCTShapeEventPairs();
|
||||
pairs.push_back(pair);
|
||||
}
|
||||
|
||||
void ControllerHitReport::onControllerHit(const physx::PxControllersHit& hit) {
|
||||
}
|
||||
|
||||
void ControllerHitReport::onObstacleHit(const physx::PxControllerObstacleHit& hit) {
|
||||
}
|
||||
|
||||
physx::PxQueryHitType::Enum QueryFilterCallback::preFilter(const physx::PxFilterData& filterData,
|
||||
const physx::PxShape* shape, const physx::PxRigidActor* actor, physx::PxHitFlags& queryFlags) {
|
||||
//PxShape --> PhysXShape ID
|
||||
const auto &hitShape = getPxShapeMap().find(reinterpret_cast<uintptr_t>(shape));
|
||||
if (hitShape == getPxShapeMap().end()) {
|
||||
return physx::PxQueryHitType::eNONE;
|
||||
}
|
||||
//PhysXShape ID --> PhysXShape pointer
|
||||
uintptr_t wrapperPtrShape = PhysXWorld::getInstance().getWrapperPtrWithObjectID(hitShape->second);
|
||||
if(wrapperPtrShape == 0){
|
||||
return physx::PxQueryHitType::eNONE;
|
||||
}
|
||||
PhysXShape* wrapperShape = reinterpret_cast<PhysXShape*>(wrapperPtrShape);
|
||||
if (!(filterData.word0 & wrapperShape->getMask()) || !(filterData.word1 & wrapperShape->getGroup())) {
|
||||
return physx::PxQueryHitType::eNONE;
|
||||
}
|
||||
return physx::PxQueryHitType::eBLOCK;
|
||||
}
|
||||
|
||||
physx::PxQueryHitType::Enum QueryFilterCallback::postFilter(const physx::PxFilterData& filterData, const physx::PxQueryHit& hit){
|
||||
PX_UNUSED(filterData);
|
||||
PX_UNUSED(hit);
|
||||
return physx::PxQueryHitType::eNONE;
|
||||
}
|
||||
|
||||
PhysXCharacterController::PhysXCharacterController() {
|
||||
_mObjectID = PhysXWorld::getInstance().addWrapperObject(reinterpret_cast<uintptr_t>(this));
|
||||
_mFilterData = physx::PxFilterData(1, 1, 1, 0 );
|
||||
};
|
||||
|
||||
void PhysXCharacterController::release() {
|
||||
eraseFromCCTMap();
|
||||
if(_impl){
|
||||
_impl->release();
|
||||
_impl = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
bool PhysXCharacterController::initialize(Node *node) {
|
||||
_mNode = node;
|
||||
onComponentSet();
|
||||
|
||||
if (_impl == nullptr) {
|
||||
return false;
|
||||
} else {
|
||||
PhysXWorld::getInstance().addCCT(*this);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void PhysXCharacterController::onEnable() {
|
||||
_mEnabled = true;
|
||||
}
|
||||
|
||||
void PhysXCharacterController::onDisable() {
|
||||
_mEnabled = false;
|
||||
}
|
||||
|
||||
void PhysXCharacterController::onDestroy() {
|
||||
release();
|
||||
PhysXWorld::getInstance().removeCCT(*this);
|
||||
PhysXWorld::getInstance().removeWrapperObject(_mObjectID);
|
||||
}
|
||||
|
||||
cc::Vec3 PhysXCharacterController::getPosition() {
|
||||
const physx::PxExtendedVec3& pos = _impl->getPosition();
|
||||
cc::Vec3 cv(pos.x, pos.y, pos.z);
|
||||
return cv;
|
||||
}
|
||||
|
||||
void PhysXCharacterController::setPosition(float x, float y, float z) {
|
||||
_impl->setPosition(physx::PxExtendedVec3{x, y, z});
|
||||
}
|
||||
|
||||
bool PhysXCharacterController::onGround() {
|
||||
return (_pxCollisionFlags & physx::PxControllerCollisionFlag::Enum::eCOLLISION_DOWN);
|
||||
}
|
||||
|
||||
void PhysXCharacterController::syncSceneToPhysics() {
|
||||
uint32_t getChangedFlags = _mNode->getChangedFlags();
|
||||
if (getChangedFlags & static_cast<uint32_t>(TransformBit::SCALE)) syncScale();
|
||||
//teleport
|
||||
if (getChangedFlags & static_cast<uint32_t>(TransformBit::POSITION)) {
|
||||
const auto & cctPos = _mNode->getWorldPosition() + scaledCenter();
|
||||
setPosition(cctPos.x, cctPos.y, cctPos.z);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void PhysXCharacterController::syncScale () {
|
||||
updateScale();
|
||||
}
|
||||
|
||||
//move
|
||||
void PhysXCharacterController::move(float x, float y, float z, float minDist, float elapsedTime) {
|
||||
physx::PxVec3 disp{x, y, z};
|
||||
controllerFilter.mFilterData = &_mFilterData;
|
||||
controllerFilter.mFilterCallback = &_mFilterCallback;
|
||||
PhysXWorld::getInstance().getControllerManager().setOverlapRecoveryModule(_mOverlapRecovery);
|
||||
_pxCollisionFlags = _impl->move(disp, minDist, elapsedTime, controllerFilter);
|
||||
}
|
||||
|
||||
void PhysXCharacterController::setStepOffset(float v) {
|
||||
_mStepOffset = v;
|
||||
_impl->setStepOffset(v);
|
||||
}
|
||||
|
||||
float PhysXCharacterController::getStepOffset() {
|
||||
return _mStepOffset;
|
||||
}
|
||||
|
||||
void PhysXCharacterController::setSlopeLimit(float v) {
|
||||
_mSlopeLimit = v;
|
||||
_impl->setSlopeLimit(cos(_mSlopeLimit * mathutils::D2R));
|
||||
}
|
||||
|
||||
float PhysXCharacterController::getSlopeLimit() {
|
||||
return _mSlopeLimit;
|
||||
}
|
||||
|
||||
void PhysXCharacterController::setContactOffset(float v) {
|
||||
_mContactOffset = v;
|
||||
_impl->setContactOffset(v);
|
||||
}
|
||||
|
||||
float PhysXCharacterController::getContactOffset() {
|
||||
return _mContactOffset;
|
||||
}
|
||||
|
||||
void PhysXCharacterController::setDetectCollisions(bool v) {
|
||||
physx::PxRigidDynamic* actor = _impl->getActor();
|
||||
physx::PxShape* shape;
|
||||
actor->getShapes(&shape, 1);
|
||||
shape->setFlag(physx::PxShapeFlag::eSIMULATION_SHAPE, v);
|
||||
}
|
||||
|
||||
void PhysXCharacterController::setOverlapRecovery(bool v) {
|
||||
_mOverlapRecovery = v;
|
||||
}
|
||||
|
||||
void PhysXCharacterController::setCenter(float x, float y, float z){
|
||||
_mCenter = Vec3(x, y, z);
|
||||
}
|
||||
|
||||
uint32_t PhysXCharacterController::getGroup() {
|
||||
return _mFilterData.word0;
|
||||
}
|
||||
|
||||
void PhysXCharacterController::setGroup(uint32_t g) {
|
||||
_mFilterData.word0 = g;
|
||||
updateFilterData();
|
||||
}
|
||||
|
||||
uint32_t PhysXCharacterController::getMask() {
|
||||
return _mFilterData.word1;
|
||||
}
|
||||
|
||||
void PhysXCharacterController::setMask(uint32_t m) {
|
||||
_mFilterData.word1 = m;
|
||||
updateFilterData();
|
||||
}
|
||||
|
||||
void PhysXCharacterController::updateEventListener(EShapeFilterFlag flag) {
|
||||
_mFilterData.word3 |= physx::PxU32(flag);
|
||||
updateFilterData();
|
||||
}
|
||||
|
||||
void PhysXCharacterController::updateFilterData() {
|
||||
setSimulationFilterData(_mFilterData);
|
||||
}
|
||||
|
||||
void PhysXCharacterController::setSimulationFilterData(physx::PxFilterData filterData) {
|
||||
physx::PxRigidDynamic* actor = _impl->getActor();
|
||||
physx::PxShape* shape;
|
||||
actor->getShapes(&shape, 1);
|
||||
shape->setSimulationFilterData(filterData);
|
||||
}
|
||||
|
||||
void PhysXCharacterController::syncPhysicsToScene() {
|
||||
_mNode->setWorldPosition(getPosition() - scaledCenter());
|
||||
}
|
||||
|
||||
void PhysXCharacterController::insertToCCTMap() {
|
||||
if (_impl) {
|
||||
getPxCCTMap().insert(std::pair<uintptr_t, uint32_t>(reinterpret_cast<uintptr_t>(_impl), getObjectID()));
|
||||
getPxCCTMap().insert(std::pair<uintptr_t, uint32_t>(reinterpret_cast<uintptr_t>(getShape()), getObjectID()));
|
||||
}
|
||||
}
|
||||
|
||||
void PhysXCharacterController::eraseFromCCTMap() {
|
||||
if (_impl) {
|
||||
getPxCCTMap().erase(reinterpret_cast<uintptr_t>(_impl));
|
||||
getPxCCTMap().erase(reinterpret_cast<uintptr_t>(getShape()));
|
||||
}
|
||||
}
|
||||
|
||||
cc::Vec3 PhysXCharacterController::scaledCenter() {
|
||||
return _mNode->getWorldScale() * _mCenter;
|
||||
}
|
||||
|
||||
physx::PxShape* PhysXCharacterController::getShape() {
|
||||
if (_impl) {
|
||||
//cct's shape
|
||||
physx::PxRigidDynamic* actor = _impl->getActor();
|
||||
physx::PxShape* shape;
|
||||
actor->getShapes(&shape, 1);
|
||||
return shape;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
} // namespace physics
|
||||
} // namespace cc
|
||||
@@ -0,0 +1,123 @@
|
||||
/****************************************************************************
|
||||
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 "base/Macros.h"
|
||||
#include "core/scene-graph/Node.h"
|
||||
#include "physics/physx/PhysXInc.h"
|
||||
#include "physics/spec/ICharacterController.h"
|
||||
|
||||
namespace cc {
|
||||
namespace physics {
|
||||
|
||||
class ControllerHitReport : public physx::PxUserControllerHitReport {
|
||||
public:
|
||||
virtual void onShapeHit(const physx::PxControllerShapeHit& hit) override;
|
||||
virtual void onControllerHit(const physx::PxControllersHit& hit) override;
|
||||
virtual void onObstacleHit(const physx::PxControllerObstacleHit& hit) override;
|
||||
};
|
||||
|
||||
class QueryFilterCallback : public physx::PxQueryFilterCallback {
|
||||
public:
|
||||
virtual physx::PxQueryHitType::Enum preFilter(const physx::PxFilterData& filterData, const physx::PxShape* shape,
|
||||
const physx::PxRigidActor* actor, physx::PxHitFlags& queryFlags) override;
|
||||
|
||||
virtual physx::PxQueryHitType::Enum postFilter(const physx::PxFilterData& filterData, const physx::PxQueryHit& hit) override;
|
||||
};
|
||||
|
||||
class PhysXCharacterController : virtual public IBaseCharacterController {
|
||||
PX_NOCOPY(PhysXCharacterController)
|
||||
PhysXCharacterController();
|
||||
|
||||
public:
|
||||
~PhysXCharacterController() override = default;
|
||||
|
||||
void syncScale();
|
||||
void syncSceneToPhysics();
|
||||
virtual void syncPhysicsToScene() override;
|
||||
|
||||
//ILifecycle
|
||||
void onEnable() override;
|
||||
void onDisable() override;
|
||||
void onDestroy() override;
|
||||
//ILifecycle END
|
||||
|
||||
//ICharacterController
|
||||
bool initialize(Node* node) override;
|
||||
virtual cc::Vec3 getPosition() override;
|
||||
virtual void setPosition(float x, float y, float z) override;
|
||||
virtual bool onGround() override;
|
||||
virtual void move(float x, float y, float z, float minDist, float elapsedTime) override;
|
||||
virtual void setStepOffset(float v) override;
|
||||
virtual float getStepOffset() override;
|
||||
virtual void setSlopeLimit(float v) override;
|
||||
virtual float getSlopeLimit() override;
|
||||
virtual void setContactOffset(float v) override;
|
||||
virtual float getContactOffset() override;
|
||||
virtual void setDetectCollisions(bool v) override;
|
||||
virtual void setOverlapRecovery(bool v) override;
|
||||
virtual void setCenter(float x, float y, float z) override;
|
||||
|
||||
uint32_t getGroup() override;
|
||||
void setGroup(uint32_t g) override;
|
||||
uint32_t getMask() override;
|
||||
void setMask(uint32_t m) override;
|
||||
void updateEventListener(EShapeFilterFlag flag) override;
|
||||
uint32_t getObjectID() const override { return _mObjectID; };
|
||||
//ICharacterController END
|
||||
|
||||
inline physx::PxController& getCCT() { return *_impl; };
|
||||
|
||||
protected:
|
||||
physx::PxController* _impl{ nullptr };
|
||||
uint8_t _mFlag{ 0 };
|
||||
bool _mEnabled{ false };
|
||||
uint32_t _mObjectID{ 0 };
|
||||
Node* _mNode{ nullptr };
|
||||
physx::PxFilterData _mFilterData;
|
||||
ControllerHitReport report;
|
||||
QueryFilterCallback _mFilterCallback;
|
||||
physx::PxControllerFilters controllerFilter;
|
||||
physx::PxControllerCollisionFlags _pxCollisionFlags;
|
||||
bool _mOverlapRecovery{ true };
|
||||
float _mContactOffset{ 0.01f };
|
||||
float _mStepOffset{ 1.f };
|
||||
float _mSlopeLimit{ 45.f };
|
||||
cc::Vec3 _mCenter{ 0.f, 0.f, 0.f };
|
||||
|
||||
void release();
|
||||
void updateFilterData();
|
||||
void setSimulationFilterData(physx::PxFilterData filterData);
|
||||
virtual void create() = 0;
|
||||
virtual void onComponentSet() = 0;
|
||||
virtual void updateScale() = 0;
|
||||
void insertToCCTMap();
|
||||
void eraseFromCCTMap();
|
||||
cc::Vec3 scaledCenter();
|
||||
physx::PxShape* getShape();
|
||||
};
|
||||
|
||||
} // namespace physics
|
||||
} // namespace cc
|
||||
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
|
||||
65
cocos/physics/physx/shapes/PhysXBox.cpp
Normal file
65
cocos/physics/physx/shapes/PhysXBox.cpp
Normal file
@@ -0,0 +1,65 @@
|
||||
/****************************************************************************
|
||||
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/shapes/PhysXBox.h"
|
||||
#include "physics/physx/PhysXUtils.h"
|
||||
#include "physics/physx/PhysXWorld.h"
|
||||
#include "physics/physx/shapes/PhysXShape.h"
|
||||
|
||||
namespace cc {
|
||||
namespace physics {
|
||||
|
||||
PhysXBox::PhysXBox() : _mHalfExtents(0.5){};
|
||||
|
||||
void PhysXBox::setSize(float x, float y, float z) {
|
||||
_mHalfExtents = physx::PxVec3{x / 2, y / 2, z / 2};
|
||||
updateGeometry();
|
||||
getShape().setGeometry(getPxGeometry<physx::PxBoxGeometry>());
|
||||
}
|
||||
|
||||
void PhysXBox::onComponentSet() {
|
||||
updateGeometry();
|
||||
_mShape = PxGetPhysics().createShape(getPxGeometry<physx::PxBoxGeometry>(), getDefaultMaterial(), true);
|
||||
}
|
||||
|
||||
void PhysXBox::updateScale() {
|
||||
updateGeometry();
|
||||
getShape().setGeometry(getPxGeometry<physx::PxBoxGeometry>());
|
||||
updateCenter();
|
||||
}
|
||||
|
||||
void PhysXBox::updateGeometry() {
|
||||
auto *node = getSharedBody().getNode();
|
||||
auto &geo = getPxGeometry<physx::PxBoxGeometry>();
|
||||
geo.halfExtents = _mHalfExtents;
|
||||
node->updateWorldTransform();
|
||||
geo.halfExtents *= node->getWorldScale();
|
||||
geo.halfExtents = geo.halfExtents.abs();
|
||||
if (geo.halfExtents.minElement() <= 0.0) {
|
||||
geo.halfExtents = geo.halfExtents.maximum(physx::PxVec3{PX_NORMALIZATION_EPSILON});
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace physics
|
||||
} // namespace cc
|
||||
46
cocos/physics/physx/shapes/PhysXBox.h
Normal file
46
cocos/physics/physx/shapes/PhysXBox.h
Normal file
@@ -0,0 +1,46 @@
|
||||
/****************************************************************************
|
||||
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/shapes/PhysXShape.h"
|
||||
|
||||
namespace cc {
|
||||
namespace physics {
|
||||
|
||||
class PhysXBox final : public PhysXShape, public IBoxShape {
|
||||
public:
|
||||
PhysXBox();
|
||||
~PhysXBox() override = default;
|
||||
void setSize(float x, float y, float z) override;
|
||||
void updateScale() override;
|
||||
|
||||
private:
|
||||
physx::PxVec3 _mHalfExtents;
|
||||
void updateGeometry();
|
||||
void onComponentSet() override;
|
||||
};
|
||||
|
||||
} // namespace physics
|
||||
} // namespace cc
|
||||
95
cocos/physics/physx/shapes/PhysXCapsule.cpp
Normal file
95
cocos/physics/physx/shapes/PhysXCapsule.cpp
Normal file
@@ -0,0 +1,95 @@
|
||||
/****************************************************************************
|
||||
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/shapes/PhysXCapsule.h"
|
||||
#include "physics/physx/PhysXUtils.h"
|
||||
#include "physics/physx/PhysXWorld.h"
|
||||
#include "physics/physx/shapes/PhysXShape.h"
|
||||
|
||||
namespace cc {
|
||||
namespace physics {
|
||||
|
||||
PhysXCapsule::PhysXCapsule() : _mRadius(0.5F),
|
||||
_mCylinderHeight(1.0F),
|
||||
_mDirection(EAxisDirection::Y_AXIS){};
|
||||
|
||||
void PhysXCapsule::setRadius(float r) {
|
||||
_mRadius = r;
|
||||
updateGeometry();
|
||||
getShape().setGeometry(getPxGeometry<physx::PxCapsuleGeometry>());
|
||||
}
|
||||
|
||||
void PhysXCapsule::setCylinderHeight(float v) {
|
||||
_mCylinderHeight = v;
|
||||
updateGeometry();
|
||||
getShape().setGeometry(getPxGeometry<physx::PxCapsuleGeometry>());
|
||||
}
|
||||
|
||||
void PhysXCapsule::setDirection(EAxisDirection v) {
|
||||
_mDirection = v;
|
||||
updateGeometry();
|
||||
getShape().setGeometry(getPxGeometry<physx::PxCapsuleGeometry>());
|
||||
}
|
||||
|
||||
void PhysXCapsule::onComponentSet() {
|
||||
updateGeometry();
|
||||
_mShape = PxGetPhysics().createShape(getPxGeometry<physx::PxCapsuleGeometry>(), getDefaultMaterial(), true);
|
||||
}
|
||||
|
||||
void PhysXCapsule::updateScale() {
|
||||
updateGeometry();
|
||||
getShape().setGeometry(getPxGeometry<physx::PxCapsuleGeometry>());
|
||||
updateCenter();
|
||||
}
|
||||
|
||||
void PhysXCapsule::updateGeometry() {
|
||||
auto *node = getSharedBody().getNode();
|
||||
auto &geo = getPxGeometry<physx::PxCapsuleGeometry>();
|
||||
float rs = 1.F;
|
||||
float hs = 1.F;
|
||||
node->updateWorldTransform();
|
||||
switch (_mDirection) {
|
||||
case EAxisDirection::X_AXIS:
|
||||
hs = physx::PxAbs(node->getWorldScale().x);
|
||||
rs = pxAbsMax(node->getWorldScale().y, node->getWorldScale().z);
|
||||
_mRotation = physx::PxQuat{physx::PxIdentity};
|
||||
break;
|
||||
case EAxisDirection::Z_AXIS:
|
||||
hs = physx::PxAbs(node->getWorldScale().z);
|
||||
rs = pxAbsMax(node->getWorldScale().x, node->getWorldScale().y);
|
||||
_mRotation = physx::PxQuat(physx::PxPiDivTwo, physx::PxVec3{0.F, 1.F, 0.F});
|
||||
break;
|
||||
case EAxisDirection::Y_AXIS:
|
||||
default:
|
||||
hs = physx::PxAbs(node->getWorldScale().y);
|
||||
rs = pxAbsMax(node->getWorldScale().x, node->getWorldScale().z);
|
||||
_mRotation = physx::PxQuat(physx::PxPiDivTwo, physx::PxVec3{0.F, 0.F, 1.F});
|
||||
break;
|
||||
}
|
||||
geo.radius = physx::PxMax(physx::PxAbs(_mRadius * rs), PX_NORMALIZATION_EPSILON);
|
||||
geo.halfHeight = physx::PxMax(physx::PxAbs(_mCylinderHeight / 2 * hs), PX_NORMALIZATION_EPSILON);
|
||||
}
|
||||
|
||||
} // namespace physics
|
||||
} // namespace cc
|
||||
50
cocos/physics/physx/shapes/PhysXCapsule.h
Normal file
50
cocos/physics/physx/shapes/PhysXCapsule.h
Normal file
@@ -0,0 +1,50 @@
|
||||
/****************************************************************************
|
||||
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/shapes/PhysXShape.h"
|
||||
|
||||
namespace cc {
|
||||
namespace physics {
|
||||
|
||||
class PhysXCapsule final : public PhysXShape, public ICapsuleShape {
|
||||
public:
|
||||
PhysXCapsule();
|
||||
~PhysXCapsule() override = default;
|
||||
void setRadius(float r) override;
|
||||
void setCylinderHeight(float v) override;
|
||||
void setDirection(EAxisDirection v) override;
|
||||
void updateScale() override;
|
||||
|
||||
private:
|
||||
float _mRadius;
|
||||
float _mCylinderHeight;
|
||||
EAxisDirection _mDirection;
|
||||
void updateGeometry();
|
||||
void onComponentSet() override;
|
||||
};
|
||||
|
||||
} // namespace physics
|
||||
} // namespace cc
|
||||
102
cocos/physics/physx/shapes/PhysXCone.cpp
Normal file
102
cocos/physics/physx/shapes/PhysXCone.cpp
Normal file
@@ -0,0 +1,102 @@
|
||||
/****************************************************************************
|
||||
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/shapes/PhysXCone.h"
|
||||
#include <algorithm>
|
||||
#include "math/Quaternion.h"
|
||||
#include "physics/physx/PhysXUtils.h"
|
||||
#include "physics/physx/PhysXWorld.h"
|
||||
#include "physics/physx/shapes/PhysXShape.h"
|
||||
|
||||
namespace cc {
|
||||
namespace physics {
|
||||
|
||||
PhysXCone::PhysXCone() : _mMesh(nullptr){};
|
||||
|
||||
void PhysXCone::setConvex(uint32_t objectID) {
|
||||
uintptr_t handle = PhysXWorld::getInstance().getPXPtrWithPXObjectID(objectID);
|
||||
if (handle == 0) return;
|
||||
if (reinterpret_cast<uintptr_t>(_mMesh) == handle) return;
|
||||
_mMesh = reinterpret_cast<physx::PxConvexMesh *>(handle);
|
||||
if (_mShape) {
|
||||
}
|
||||
}
|
||||
|
||||
void PhysXCone::onComponentSet() {
|
||||
if (_mMesh) {
|
||||
physx::PxConvexMeshGeometry geom;
|
||||
geom.convexMesh = _mMesh;
|
||||
// geom.meshFlags = PxConvexMeshGeometryFlags::eTIGHT_BOUNDS;
|
||||
_mShape = PxGetPhysics().createShape(geom, getDefaultMaterial(), true);
|
||||
updateGeometry();
|
||||
}
|
||||
}
|
||||
|
||||
void PhysXCone::setCone(float r, float h, EAxisDirection d) {
|
||||
_mData.radius = r;
|
||||
_mData.height = h;
|
||||
_mData.direction = d;
|
||||
updateGeometry();
|
||||
}
|
||||
|
||||
void PhysXCone::updateGeometry() {
|
||||
if (!_mShape) return;
|
||||
static physx::PxMeshScale scale;
|
||||
auto *node = getSharedBody().getNode();
|
||||
node->updateWorldTransform();
|
||||
pxSetVec3Ext(scale.scale, node->getWorldScale());
|
||||
scale.scale.y *= std::max(0.0001F, _mData.height / 2);
|
||||
const auto radius = std::max(0.0001F, _mData.radius * 2);
|
||||
const auto xzMaxNorm = std::max(scale.scale.x, scale.scale.z);
|
||||
scale.scale.x = scale.scale.z = radius * xzMaxNorm;
|
||||
Quaternion quat;
|
||||
switch (_mData.direction) {
|
||||
case EAxisDirection::X_AXIS:
|
||||
quat.set(Vec3::UNIT_Z, physx::PxPiDivTwo);
|
||||
pxSetQuatExt(scale.rotation, quat);
|
||||
break;
|
||||
case EAxisDirection::Y_AXIS:
|
||||
default:
|
||||
scale.rotation = physx::PxQuat{physx::PxIdentity};
|
||||
break;
|
||||
case EAxisDirection::Z_AXIS:
|
||||
quat.set(Vec3::UNIT_X, physx::PxPiDivTwo);
|
||||
pxSetQuatExt(scale.rotation, quat);
|
||||
break;
|
||||
}
|
||||
physx::PxConvexMeshGeometry geom;
|
||||
if (getShape().getConvexMeshGeometry(geom)) {
|
||||
geom.scale = scale;
|
||||
getShape().setGeometry(geom);
|
||||
}
|
||||
pxSetQuatExt(_mRotation, quat);
|
||||
}
|
||||
|
||||
void PhysXCone::updateScale() {
|
||||
updateGeometry();
|
||||
updateCenter();
|
||||
}
|
||||
|
||||
} // namespace physics
|
||||
} // namespace cc
|
||||
54
cocos/physics/physx/shapes/PhysXCone.h
Normal file
54
cocos/physics/physx/shapes/PhysXCone.h
Normal file
@@ -0,0 +1,54 @@
|
||||
/****************************************************************************
|
||||
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/shapes/PhysXShape.h"
|
||||
|
||||
namespace cc {
|
||||
namespace physics {
|
||||
|
||||
class PhysXCone final : public PhysXShape, public IConeShape {
|
||||
public:
|
||||
PhysXCone();
|
||||
~PhysXCone() override = default;
|
||||
void setConvex(uint32_t objectID) override;
|
||||
void setCone(float r, float h, EAxisDirection d) override;
|
||||
void updateScale() override;
|
||||
|
||||
struct Cone {
|
||||
float radius;
|
||||
float height;
|
||||
EAxisDirection direction;
|
||||
};
|
||||
|
||||
private:
|
||||
physx::PxConvexMesh *_mMesh;
|
||||
Cone _mData;
|
||||
void updateGeometry();
|
||||
void onComponentSet() override;
|
||||
};
|
||||
|
||||
} // namespace physics
|
||||
} // namespace cc
|
||||
103
cocos/physics/physx/shapes/PhysXCylinder.cpp
Normal file
103
cocos/physics/physx/shapes/PhysXCylinder.cpp
Normal file
@@ -0,0 +1,103 @@
|
||||
/****************************************************************************
|
||||
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/shapes/PhysXCylinder.h"
|
||||
#include <algorithm>
|
||||
#include "math/Quaternion.h"
|
||||
#include "physics/physx/PhysXUtils.h"
|
||||
#include "physics/physx/PhysXWorld.h"
|
||||
#include "physics/physx/shapes/PhysXShape.h"
|
||||
|
||||
namespace cc {
|
||||
namespace physics {
|
||||
|
||||
PhysXCylinder::PhysXCylinder() : _mMesh(nullptr){};
|
||||
|
||||
void PhysXCylinder::setConvex(uint32_t objectID) {
|
||||
uintptr_t handle = PhysXWorld::getInstance().getPXPtrWithPXObjectID(objectID);
|
||||
if (handle == 0) return;
|
||||
if (reinterpret_cast<uintptr_t>(_mMesh) == handle) return;
|
||||
_mMesh = reinterpret_cast<physx::PxConvexMesh *>(handle);
|
||||
if (_mShape) {
|
||||
// TODO(Administrator): ...
|
||||
}
|
||||
}
|
||||
|
||||
void PhysXCylinder::onComponentSet() {
|
||||
if (_mMesh) {
|
||||
physx::PxConvexMeshGeometry geom;
|
||||
geom.convexMesh = _mMesh;
|
||||
// geom.meshFlags = PxConvexMeshGeometryFlags::eTIGHT_BOUNDS;
|
||||
_mShape = PxGetPhysics().createShape(geom, getDefaultMaterial(), true);
|
||||
updateGeometry();
|
||||
}
|
||||
}
|
||||
|
||||
void PhysXCylinder::setCylinder(float r, float h, EAxisDirection d) {
|
||||
_mData.radius = r;
|
||||
_mData.height = h;
|
||||
_mData.direction = d;
|
||||
updateGeometry();
|
||||
}
|
||||
|
||||
void PhysXCylinder::updateGeometry() {
|
||||
if (!_mShape) return;
|
||||
static physx::PxMeshScale scale;
|
||||
auto *node = getSharedBody().getNode();
|
||||
node->updateWorldTransform();
|
||||
pxSetVec3Ext(scale.scale, node->getWorldScale());
|
||||
scale.scale.y *= std::max(0.0001F, _mData.height / 2);
|
||||
const auto radius = std::max(0.0001F, _mData.radius * 2);
|
||||
const auto xzMaxNorm = std::max(scale.scale.x, scale.scale.z);
|
||||
scale.scale.x = scale.scale.z = radius * xzMaxNorm;
|
||||
Quaternion quat;
|
||||
switch (_mData.direction) {
|
||||
case EAxisDirection::X_AXIS:
|
||||
quat.set(Vec3::UNIT_Z, physx::PxPiDivTwo);
|
||||
pxSetQuatExt(scale.rotation, quat);
|
||||
break;
|
||||
case EAxisDirection::Y_AXIS:
|
||||
default:
|
||||
scale.rotation = physx::PxQuat{physx::PxIdentity};
|
||||
break;
|
||||
case EAxisDirection::Z_AXIS:
|
||||
quat.set(Vec3::UNIT_X, physx::PxPiDivTwo);
|
||||
pxSetQuatExt(scale.rotation, quat);
|
||||
break;
|
||||
}
|
||||
physx::PxConvexMeshGeometry geom;
|
||||
if (getShape().getConvexMeshGeometry(geom)) {
|
||||
geom.scale = scale;
|
||||
getShape().setGeometry(geom);
|
||||
}
|
||||
pxSetQuatExt(_mRotation, quat);
|
||||
}
|
||||
|
||||
void PhysXCylinder::updateScale() {
|
||||
updateGeometry();
|
||||
updateCenter();
|
||||
}
|
||||
|
||||
} // namespace physics
|
||||
} // namespace cc
|
||||
54
cocos/physics/physx/shapes/PhysXCylinder.h
Normal file
54
cocos/physics/physx/shapes/PhysXCylinder.h
Normal file
@@ -0,0 +1,54 @@
|
||||
/****************************************************************************
|
||||
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/shapes/PhysXShape.h"
|
||||
|
||||
namespace cc {
|
||||
namespace physics {
|
||||
|
||||
class PhysXCylinder final : public PhysXShape, public ICylinderShape {
|
||||
public:
|
||||
PhysXCylinder();
|
||||
~PhysXCylinder() override = default;
|
||||
void setConvex(uint32_t objectID) override;
|
||||
void setCylinder(float r, float h, EAxisDirection d) override;
|
||||
void updateScale() override;
|
||||
|
||||
struct Cylinder {
|
||||
float radius;
|
||||
float height;
|
||||
EAxisDirection direction;
|
||||
};
|
||||
|
||||
private:
|
||||
physx::PxConvexMesh *_mMesh;
|
||||
Cylinder _mData;
|
||||
void updateGeometry();
|
||||
void onComponentSet() override;
|
||||
};
|
||||
|
||||
} // namespace physics
|
||||
} // namespace cc
|
||||
65
cocos/physics/physx/shapes/PhysXPlane.cpp
Normal file
65
cocos/physics/physx/shapes/PhysXPlane.cpp
Normal file
@@ -0,0 +1,65 @@
|
||||
/****************************************************************************
|
||||
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/shapes/PhysXPlane.h"
|
||||
#include "physics/physx/PhysXUtils.h"
|
||||
#include "physics/physx/PhysXWorld.h"
|
||||
#include "physics/physx/shapes/PhysXShape.h"
|
||||
|
||||
namespace cc {
|
||||
namespace physics {
|
||||
|
||||
PhysXPlane::PhysXPlane() : _mConstant(0.F),
|
||||
_mNormal(0.F, 1.F, 0.F){};
|
||||
|
||||
void PhysXPlane::setConstant(float x) {
|
||||
_mConstant = x;
|
||||
updateCenter();
|
||||
}
|
||||
|
||||
void PhysXPlane::setNormal(float x, float y, float z) {
|
||||
_mNormal = physx::PxVec3{x, y, z};
|
||||
updateCenter();
|
||||
}
|
||||
|
||||
void PhysXPlane::onComponentSet() {
|
||||
_mShape = PxGetPhysics().createShape(getPxGeometry<physx::PxPlaneGeometry>(), getDefaultMaterial(), true);
|
||||
updateCenter();
|
||||
}
|
||||
|
||||
void PhysXPlane::updateScale() {
|
||||
updateCenter();
|
||||
}
|
||||
|
||||
void PhysXPlane::updateCenter() {
|
||||
auto* node = getSharedBody().getNode();
|
||||
auto& geo = getPxGeometry<physx::PxPlaneGeometry>();
|
||||
physx::PxTransform local;
|
||||
pxSetFromTwoVectors(local.q, physx::PxVec3{1.F, 0.F, 0.F}, _mNormal);
|
||||
local.p = _mNormal * _mConstant + _mCenter;
|
||||
getShape().setLocalPose(local);
|
||||
}
|
||||
|
||||
} // namespace physics
|
||||
} // namespace cc
|
||||
48
cocos/physics/physx/shapes/PhysXPlane.h
Normal file
48
cocos/physics/physx/shapes/PhysXPlane.h
Normal file
@@ -0,0 +1,48 @@
|
||||
/****************************************************************************
|
||||
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/shapes/PhysXShape.h"
|
||||
|
||||
namespace cc {
|
||||
namespace physics {
|
||||
|
||||
class PhysXPlane final : public PhysXShape, public IPlaneShape {
|
||||
public:
|
||||
PhysXPlane();
|
||||
~PhysXPlane() override = default;
|
||||
void setConstant(float x) override;
|
||||
void setNormal(float x, float y, float z) override;
|
||||
void updateScale() override;
|
||||
|
||||
private:
|
||||
physx::PxVec3 _mNormal;
|
||||
physx::PxReal _mConstant;
|
||||
void updateCenter() override;
|
||||
void onComponentSet() override;
|
||||
};
|
||||
|
||||
} // namespace physics
|
||||
} // namespace cc
|
||||
157
cocos/physics/physx/shapes/PhysXShape.cpp
Normal file
157
cocos/physics/physx/shapes/PhysXShape.cpp
Normal file
@@ -0,0 +1,157 @@
|
||||
/****************************************************************************
|
||||
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/shapes/PhysXShape.h"
|
||||
#include "base/std/container/unordered_map.h"
|
||||
#include "physics/physx/PhysXSharedBody.h"
|
||||
#include "physics/physx/PhysXUtils.h"
|
||||
#include "physics/physx/PhysXWorld.h"
|
||||
|
||||
namespace cc {
|
||||
namespace physics {
|
||||
|
||||
PhysXShape::PhysXShape() : _mCenter(physx::PxIdentity), _mRotation(physx::PxIdentity) {
|
||||
_mObjectID = PhysXWorld::getInstance().addWrapperObject(reinterpret_cast<uintptr_t>(this));
|
||||
};
|
||||
|
||||
void PhysXShape::initialize(Node *node) {
|
||||
PhysXWorld &ins = PhysXWorld::getInstance();
|
||||
_mSharedBody = ins.getSharedBody(node);
|
||||
getSharedBody().reference(true);
|
||||
onComponentSet();
|
||||
insertToShapeMap();
|
||||
}
|
||||
|
||||
void PhysXShape::onEnable() {
|
||||
_mEnabled = true;
|
||||
if (_mShape) getSharedBody().addShape(*this);
|
||||
getSharedBody().enabled(true);
|
||||
}
|
||||
|
||||
void PhysXShape::onDisable() {
|
||||
_mEnabled = false;
|
||||
if (_mShape) getSharedBody().removeShape(*this);
|
||||
getSharedBody().enabled(false);
|
||||
}
|
||||
|
||||
void PhysXShape::onDestroy() {
|
||||
getSharedBody().reference(false);
|
||||
eraseFromShapeMap();
|
||||
PhysXWorld::getInstance().removeWrapperObject(_mObjectID);
|
||||
}
|
||||
|
||||
void PhysXShape::setMaterial(uint16_t id, float f, float df, float r,
|
||||
uint8_t m0, uint8_t m1) {
|
||||
if (!_mShape) return;
|
||||
PhysXWorld::getInstance().createMaterial(id, f, df, r, m0, m1);
|
||||
auto *mat = reinterpret_cast<physx::PxMaterial *>(PhysXWorld::getInstance().getPXMaterialPtrWithMaterialID(id));
|
||||
getShape().setMaterials(&mat, 1);
|
||||
}
|
||||
|
||||
void PhysXShape::setAsTrigger(bool v) {
|
||||
if (v) {
|
||||
getShape().setFlag(physx::PxShapeFlag::eSIMULATION_SHAPE, !v);
|
||||
getShape().setFlag(physx::PxShapeFlag::eTRIGGER_SHAPE, v);
|
||||
} else {
|
||||
getShape().setFlag(physx::PxShapeFlag::eTRIGGER_SHAPE, v);
|
||||
getShape().setFlag(physx::PxShapeFlag::eSIMULATION_SHAPE, !v);
|
||||
}
|
||||
if (_mEnabled) {
|
||||
getSharedBody().removeShape(*this);
|
||||
getSharedBody().addShape(*this);
|
||||
}
|
||||
}
|
||||
|
||||
void PhysXShape::setCenter(float x, float y, float z) {
|
||||
_mCenter = physx::PxVec3{x, y, z};
|
||||
updateCenter();
|
||||
}
|
||||
|
||||
uint32_t PhysXShape::getGroup() {
|
||||
return getSharedBody().getGroup();
|
||||
}
|
||||
|
||||
void PhysXShape::setGroup(uint32_t g) {
|
||||
getSharedBody().setGroup(g);
|
||||
}
|
||||
|
||||
uint32_t PhysXShape::getMask() {
|
||||
return getSharedBody().getMask();
|
||||
}
|
||||
|
||||
void PhysXShape::setMask(uint32_t m) {
|
||||
getSharedBody().setMask(m);
|
||||
}
|
||||
|
||||
void PhysXShape::updateEventListener(EShapeFilterFlag flag) {
|
||||
}
|
||||
|
||||
geometry::AABB &PhysXShape::getAABB() {
|
||||
static IntrusivePtr<geometry::AABB> aabb; // this variable is shared with JS with refcounter
|
||||
if (!aabb) {
|
||||
aabb = new geometry::AABB;
|
||||
}
|
||||
if (_mShape) {
|
||||
auto bounds = physx::PxShapeExt::getWorldBounds(getShape(), *getSharedBody().getImpl().rigidActor);
|
||||
pxSetVec3Ext(aabb->center, (bounds.maximum + bounds.minimum) / 2);
|
||||
pxSetVec3Ext(aabb->halfExtents, (bounds.maximum - bounds.minimum) / 2);
|
||||
}
|
||||
return *aabb;
|
||||
}
|
||||
|
||||
geometry::Sphere &PhysXShape::getBoundingSphere() {
|
||||
static IntrusivePtr<geometry::Sphere> sphere; // this variable is shared with JS with refcounter
|
||||
if (!sphere) {
|
||||
sphere = new geometry::Sphere;
|
||||
}
|
||||
if (_mShape) sphere->define(getAABB());
|
||||
return *sphere;
|
||||
}
|
||||
|
||||
void PhysXShape::updateFilterData(const physx::PxFilterData &data) {
|
||||
}
|
||||
|
||||
void PhysXShape::updateCenter() {
|
||||
if (!_mShape) return;
|
||||
auto &sb = getSharedBody();
|
||||
auto *node = sb.getNode();
|
||||
node->updateWorldTransform();
|
||||
physx::PxTransform local{_mCenter * node->getWorldScale(), _mRotation};
|
||||
getShape().setLocalPose(local);
|
||||
}
|
||||
|
||||
void PhysXShape::insertToShapeMap() {
|
||||
if (_mShape) {
|
||||
getPxShapeMap().insert(std::pair<uintptr_t, uint32_t>(reinterpret_cast<uintptr_t>(&getShape()), getObjectID()));
|
||||
}
|
||||
}
|
||||
|
||||
void PhysXShape::eraseFromShapeMap() {
|
||||
if (_mShape) {
|
||||
getPxShapeMap().erase(reinterpret_cast<uintptr_t>(&getShape()));
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace physics
|
||||
} // namespace cc
|
||||
89
cocos/physics/physx/shapes/PhysXShape.h
Normal file
89
cocos/physics/physx/shapes/PhysXShape.h
Normal file
@@ -0,0 +1,89 @@
|
||||
/****************************************************************************
|
||||
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/IShape.h"
|
||||
|
||||
namespace cc {
|
||||
namespace physics {
|
||||
class PhysXSharedBody;
|
||||
|
||||
template <typename T>
|
||||
inline T &getPxGeometry() {
|
||||
static T geo;
|
||||
return geo;
|
||||
}
|
||||
|
||||
class PhysXShape : virtual public IBaseShape {
|
||||
PX_NOCOPY(PhysXShape)
|
||||
PhysXShape();
|
||||
|
||||
public:
|
||||
~PhysXShape() override = default;
|
||||
void initialize(Node *node) override;
|
||||
void onEnable() override;
|
||||
void onDisable() override;
|
||||
void onDestroy() override;
|
||||
void setMaterial(uint16_t id, float f, float df, float r,
|
||||
uint8_t m0, uint8_t m1) override;
|
||||
void setAsTrigger(bool v) override;
|
||||
void setCenter(float x, float y, float z) override;
|
||||
geometry::AABB &getAABB() override;
|
||||
geometry::Sphere &getBoundingSphere() override;
|
||||
void updateEventListener(EShapeFilterFlag flag) override;
|
||||
uint32_t getGroup() override;
|
||||
void setGroup(uint32_t g) override;
|
||||
uint32_t getMask() override;
|
||||
void setMask(uint32_t m) override;
|
||||
virtual void updateScale() = 0;
|
||||
inline physx::PxVec3 &getCenter() { return _mCenter; }
|
||||
inline physx::PxShape &getShape() const { return *_mShape; }
|
||||
inline PhysXSharedBody &getSharedBody() const { return *_mSharedBody; }
|
||||
inline bool isTrigger() const {
|
||||
return getShape().getFlags().isSet(physx::PxShapeFlag::eTRIGGER_SHAPE);
|
||||
}
|
||||
void updateFilterData(const physx::PxFilterData &data);
|
||||
uint32_t getObjectID() const override { return _mObjectID; };
|
||||
|
||||
protected:
|
||||
PhysXSharedBody *_mSharedBody{nullptr};
|
||||
physx::PxShape *_mShape{nullptr};
|
||||
physx::PxVec3 _mCenter;
|
||||
physx::PxQuat _mRotation;
|
||||
uint8_t _mFlag{0};
|
||||
bool _mEnabled{false};
|
||||
uint32_t _mObjectID{0};
|
||||
|
||||
virtual void updateCenter();
|
||||
virtual void onComponentSet() = 0;
|
||||
virtual void insertToShapeMap();
|
||||
virtual void eraseFromShapeMap();
|
||||
};
|
||||
|
||||
} // namespace physics
|
||||
} // namespace cc
|
||||
62
cocos/physics/physx/shapes/PhysXSphere.cpp
Normal file
62
cocos/physics/physx/shapes/PhysXSphere.cpp
Normal file
@@ -0,0 +1,62 @@
|
||||
/****************************************************************************
|
||||
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/shapes/PhysXSphere.h"
|
||||
#include "physics/physx/PhysXUtils.h"
|
||||
#include "physics/physx/PhysXWorld.h"
|
||||
#include "physics/physx/shapes/PhysXShape.h"
|
||||
|
||||
namespace cc {
|
||||
namespace physics {
|
||||
|
||||
PhysXSphere::PhysXSphere() : _mRadius(0.5F) {}
|
||||
|
||||
void PhysXSphere::setRadius(float r) {
|
||||
_mRadius = r;
|
||||
updateGeometry();
|
||||
getShape().setGeometry(getPxGeometry<physx::PxSphereGeometry>());
|
||||
}
|
||||
|
||||
void PhysXSphere::onComponentSet() {
|
||||
updateGeometry();
|
||||
_mShape = PxGetPhysics().createShape(getPxGeometry<physx::PxSphereGeometry>(), getDefaultMaterial(), true);
|
||||
}
|
||||
|
||||
void PhysXSphere::updateScale() {
|
||||
updateGeometry();
|
||||
getShape().setGeometry(getPxGeometry<physx::PxSphereGeometry>());
|
||||
updateCenter();
|
||||
}
|
||||
|
||||
void PhysXSphere::updateGeometry() {
|
||||
physx::PxVec3 scale;
|
||||
auto *node = getSharedBody().getNode();
|
||||
node->updateWorldTransform();
|
||||
pxSetVec3Ext(scale, node->getWorldScale());
|
||||
auto &geo = getPxGeometry<physx::PxSphereGeometry>();
|
||||
geo.radius = physx::PxMax(_mRadius * scale.abs().maxElement(), PX_NORMALIZATION_EPSILON);
|
||||
}
|
||||
|
||||
} // namespace physics
|
||||
} // namespace cc
|
||||
46
cocos/physics/physx/shapes/PhysXSphere.h
Normal file
46
cocos/physics/physx/shapes/PhysXSphere.h
Normal file
@@ -0,0 +1,46 @@
|
||||
/****************************************************************************
|
||||
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/shapes/PhysXShape.h"
|
||||
|
||||
namespace cc {
|
||||
namespace physics {
|
||||
|
||||
class PhysXSphere final : public PhysXShape, public ISphereShape {
|
||||
public:
|
||||
PhysXSphere();
|
||||
~PhysXSphere() override = default;
|
||||
void setRadius(float r) override;
|
||||
void updateScale() override;
|
||||
|
||||
private:
|
||||
float _mRadius;
|
||||
void updateGeometry();
|
||||
void onComponentSet() override;
|
||||
};
|
||||
|
||||
} // namespace physics
|
||||
} // namespace cc
|
||||
85
cocos/physics/physx/shapes/PhysXTerrain.cpp
Normal file
85
cocos/physics/physx/shapes/PhysXTerrain.cpp
Normal file
@@ -0,0 +1,85 @@
|
||||
/****************************************************************************
|
||||
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/shapes/PhysXTerrain.h"
|
||||
#include "physics/physx/PhysXUtils.h"
|
||||
#include "physics/physx/PhysXWorld.h"
|
||||
#include "physics/physx/shapes/PhysXShape.h"
|
||||
|
||||
namespace cc {
|
||||
namespace physics {
|
||||
|
||||
PhysXTerrain::PhysXTerrain() : _mTerrain(nullptr),
|
||||
_mRowScale(1.F),
|
||||
_mColScale(1.F),
|
||||
_mHeightScale(1.F),
|
||||
_mIsTrigger(false){};
|
||||
|
||||
void PhysXTerrain::setTerrain(uint32_t objectID, float rs, float cs, float hs) {
|
||||
uintptr_t handle = PhysXWorld::getInstance().getPXPtrWithPXObjectID(objectID);
|
||||
if (handle == 0) return;
|
||||
if (_mShape) return;
|
||||
if (reinterpret_cast<uintptr_t>(_mTerrain) == handle) return;
|
||||
_mTerrain = reinterpret_cast<physx::PxHeightField *>(handle);
|
||||
_mRowScale = rs;
|
||||
_mColScale = cs;
|
||||
_mHeightScale = hs;
|
||||
if (_mSharedBody && _mTerrain) {
|
||||
onComponentSet();
|
||||
insertToShapeMap();
|
||||
if (_mEnabled) getSharedBody().addShape(*this);
|
||||
setAsTrigger(_mIsTrigger);
|
||||
updateCenter();
|
||||
}
|
||||
}
|
||||
|
||||
void PhysXTerrain::onComponentSet() {
|
||||
if (_mTerrain) {
|
||||
physx::PxHeightFieldGeometry geom;
|
||||
geom.rowScale = _mRowScale;
|
||||
geom.columnScale = _mColScale;
|
||||
geom.heightScale = _mHeightScale;
|
||||
geom.heightField = _mTerrain;
|
||||
_mShape = PxGetPhysics().createShape(geom, getDefaultMaterial(), true);
|
||||
}
|
||||
}
|
||||
|
||||
void PhysXTerrain::updateScale() {
|
||||
// updateCenter(); needed?
|
||||
}
|
||||
|
||||
void PhysXTerrain::updateCenter() {
|
||||
if (!_mShape) return;
|
||||
getShape().setLocalPose(physx::PxTransform{_mCenter, _mRotation});
|
||||
}
|
||||
|
||||
void PhysXTerrain::setAsTrigger(bool v) {
|
||||
_mIsTrigger = v;
|
||||
if (_mShape) {
|
||||
PhysXShape::setAsTrigger(v);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace physics
|
||||
} // namespace cc
|
||||
51
cocos/physics/physx/shapes/PhysXTerrain.h
Normal file
51
cocos/physics/physx/shapes/PhysXTerrain.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/shapes/PhysXShape.h"
|
||||
|
||||
namespace cc {
|
||||
namespace physics {
|
||||
|
||||
class PhysXTerrain final : public PhysXShape, public ITerrainShape {
|
||||
public:
|
||||
PhysXTerrain();
|
||||
~PhysXTerrain() override = default;
|
||||
void setTerrain(uint32_t objectID, float rs, float cs, float hs) override;
|
||||
void updateScale() override;
|
||||
void updateCenter() override;
|
||||
void setAsTrigger(bool v) override;
|
||||
|
||||
private:
|
||||
physx::PxHeightField *_mTerrain;
|
||||
float _mRowScale;
|
||||
float _mColScale;
|
||||
float _mHeightScale;
|
||||
bool _mIsTrigger;
|
||||
void onComponentSet() override;
|
||||
};
|
||||
|
||||
} // namespace physics
|
||||
} // namespace cc
|
||||
114
cocos/physics/physx/shapes/PhysXTrimesh.cpp
Normal file
114
cocos/physics/physx/shapes/PhysXTrimesh.cpp
Normal file
@@ -0,0 +1,114 @@
|
||||
/****************************************************************************
|
||||
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/shapes/PhysXTrimesh.h"
|
||||
#include "physics/physx/PhysXUtils.h"
|
||||
#include "physics/physx/PhysXWorld.h"
|
||||
#include "physics/physx/shapes/PhysXShape.h"
|
||||
|
||||
namespace cc {
|
||||
namespace physics {
|
||||
|
||||
PhysXTrimesh::PhysXTrimesh() : _mMeshHandle(0),
|
||||
_mConvex(false),
|
||||
_mIsTrigger(false){};
|
||||
|
||||
void PhysXTrimesh::setMesh(uint32_t objectID) {
|
||||
uintptr_t handle = PhysXWorld::getInstance().getPXPtrWithPXObjectID(objectID);
|
||||
if (handle == 0) return;
|
||||
if (_mShape) {
|
||||
getSharedBody().removeShape(*this);
|
||||
eraseFromShapeMap();
|
||||
_mShape->release();
|
||||
_mShape = nullptr;
|
||||
}
|
||||
if (_mMeshHandle == handle) return;
|
||||
_mMeshHandle = handle;
|
||||
if (_mSharedBody && _mMeshHandle) {
|
||||
onComponentSet();
|
||||
insertToShapeMap();
|
||||
if (_mEnabled) getSharedBody().addShape(*this);
|
||||
setAsTrigger(_mIsTrigger);
|
||||
updateCenter();
|
||||
}
|
||||
}
|
||||
|
||||
void PhysXTrimesh::useConvex(bool v) {
|
||||
_mConvex = v;
|
||||
}
|
||||
|
||||
void PhysXTrimesh::onComponentSet() {
|
||||
if (_mMeshHandle) {
|
||||
const auto &mat = getDefaultMaterial();
|
||||
if (_mConvex) {
|
||||
physx::PxConvexMeshGeometry geom;
|
||||
geom.convexMesh = reinterpret_cast<physx::PxConvexMesh *>(_mMeshHandle);
|
||||
// geom.meshFlags = PxConvexMeshGeometryFlags::eTIGHT_BOUNDS;
|
||||
_mShape = PxGetPhysics().createShape(geom, mat, true);
|
||||
} else {
|
||||
physx::PxTriangleMeshGeometry geom;
|
||||
geom.triangleMesh = reinterpret_cast<physx::PxTriangleMesh *>(_mMeshHandle);
|
||||
// geom.meshFlags = PxMeshGeometryFlag::eDOUBLE_SIDED;
|
||||
_mShape = PxGetPhysics().createShape(geom, mat, true);
|
||||
}
|
||||
updateGeometry();
|
||||
}
|
||||
}
|
||||
|
||||
void PhysXTrimesh::updateScale() {
|
||||
updateGeometry();
|
||||
updateCenter();
|
||||
}
|
||||
|
||||
void PhysXTrimesh::updateGeometry() {
|
||||
static physx::PxMeshScale scale;
|
||||
scale.rotation = physx::PxQuat{physx::PxIdentity};
|
||||
auto *node = getSharedBody().getNode();
|
||||
node->updateWorldTransform();
|
||||
pxSetVec3Ext(scale.scale, node->getWorldScale());
|
||||
const auto &type = _mShape->getGeometryType();
|
||||
if (type == physx::PxGeometryType::eCONVEXMESH) {
|
||||
physx::PxConvexMeshGeometry geom;
|
||||
if (getShape().getConvexMeshGeometry(geom)) {
|
||||
geom.scale = scale;
|
||||
getShape().setGeometry(geom);
|
||||
}
|
||||
} else if (type == physx::PxGeometryType::eTRIANGLEMESH) {
|
||||
physx::PxTriangleMeshGeometry geom;
|
||||
if (getShape().getTriangleMeshGeometry(geom)) {
|
||||
geom.scale = scale;
|
||||
getShape().setGeometry(geom);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PhysXTrimesh::setAsTrigger(bool v) {
|
||||
_mIsTrigger = v;
|
||||
if (_mShape) {
|
||||
PhysXShape::setAsTrigger(v);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace physics
|
||||
} // namespace cc
|
||||
50
cocos/physics/physx/shapes/PhysXTrimesh.h
Normal file
50
cocos/physics/physx/shapes/PhysXTrimesh.h
Normal file
@@ -0,0 +1,50 @@
|
||||
/****************************************************************************
|
||||
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/shapes/PhysXShape.h"
|
||||
|
||||
namespace cc {
|
||||
namespace physics {
|
||||
|
||||
class PhysXTrimesh final : public PhysXShape, public ITrimeshShape {
|
||||
public:
|
||||
PhysXTrimesh();
|
||||
~PhysXTrimesh() override = default;
|
||||
void setMesh(uint32_t objectID) override;
|
||||
void useConvex(bool v) override;
|
||||
void updateScale() override;
|
||||
void setAsTrigger(bool v) override;
|
||||
|
||||
private:
|
||||
bool _mConvex;
|
||||
uintptr_t _mMeshHandle;
|
||||
bool _mIsTrigger;
|
||||
void updateGeometry();
|
||||
void onComponentSet() override;
|
||||
};
|
||||
|
||||
} // namespace physics
|
||||
} // namespace cc
|
||||
161
cocos/physics/sdk/CharacterController.cpp
Normal file
161
cocos/physics/sdk/CharacterController.cpp
Normal file
@@ -0,0 +1,161 @@
|
||||
/****************************************************************************
|
||||
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/sdk/CharacterController.h"
|
||||
#include <memory>
|
||||
#include "physics/PhysicsSelector.h"
|
||||
|
||||
#define CC_PHYSICS_CCT_DEFINITION(CLASS, WRAPPED) \
|
||||
\
|
||||
CLASS::CLASS() { \
|
||||
_impl.reset(ccnew WRAPPED()); \
|
||||
} \
|
||||
\
|
||||
CLASS::~CLASS() { \
|
||||
_impl.reset(nullptr); \
|
||||
} \
|
||||
\
|
||||
bool CLASS::initialize(Node *node) { \
|
||||
return _impl->initialize(node); \
|
||||
} \
|
||||
\
|
||||
void CLASS::onEnable() { \
|
||||
_impl->onEnable(); \
|
||||
} \
|
||||
\
|
||||
void CLASS::onDisable() { \
|
||||
_impl->onDisable(); \
|
||||
} \
|
||||
\
|
||||
void CLASS::onDestroy() { \
|
||||
_impl->onDestroy(); \
|
||||
} \
|
||||
\
|
||||
cc::Vec3 CLASS::getPosition() { \
|
||||
return _impl->getPosition(); \
|
||||
} \
|
||||
\
|
||||
void CLASS::setPosition(float x, float y, float z) { \
|
||||
_impl->setPosition(x, y, z); \
|
||||
} \
|
||||
\
|
||||
bool CLASS::onGround() { \
|
||||
return _impl->onGround(); \
|
||||
} \
|
||||
\
|
||||
void CLASS::move(float x, float y, float z, float minDist, float elapsedTime) { \
|
||||
_impl->move(x, y, z, minDist, elapsedTime); \
|
||||
} \
|
||||
\
|
||||
void CLASS::syncPhysicsToScene() { \
|
||||
_impl->syncPhysicsToScene(); \
|
||||
} \
|
||||
\
|
||||
void CLASS::setStepOffset(float v) { \
|
||||
_impl->setStepOffset(v); \
|
||||
} \
|
||||
\
|
||||
float CLASS::getStepOffset() { \
|
||||
return _impl->getStepOffset(); \
|
||||
} \
|
||||
\
|
||||
void CLASS::setSlopeLimit(float v) { \
|
||||
_impl->setSlopeLimit(v); \
|
||||
} \
|
||||
\
|
||||
float CLASS::getSlopeLimit() { \
|
||||
return _impl->getSlopeLimit(); \
|
||||
} \
|
||||
\
|
||||
void CLASS::setContactOffset(float v) { \
|
||||
_impl->setContactOffset(v); \
|
||||
} \
|
||||
\
|
||||
float CLASS::getContactOffset() { \
|
||||
return _impl->getContactOffset(); \
|
||||
} \
|
||||
\
|
||||
void CLASS::setDetectCollisions(bool v) { \
|
||||
_impl->setDetectCollisions(v); \
|
||||
} \
|
||||
void CLASS::setOverlapRecovery(bool v) { \
|
||||
_impl->setOverlapRecovery(v); \
|
||||
} \
|
||||
void CLASS::setCenter(float x, float y, float z) { \
|
||||
_impl->setCenter(x, y, z); \
|
||||
} \
|
||||
uint32_t CLASS::getGroup() { \
|
||||
return _impl->getGroup(); \
|
||||
} \
|
||||
\
|
||||
void CLASS::setGroup(uint32_t g) { \
|
||||
_impl->setGroup(g); \
|
||||
} \
|
||||
\
|
||||
uint32_t CLASS::getMask() { \
|
||||
return _impl->getMask(); \
|
||||
} \
|
||||
\
|
||||
void CLASS::setMask(uint32_t m) { \
|
||||
_impl->setMask(m); \
|
||||
} \
|
||||
void CLASS::updateEventListener(EShapeFilterFlag flag) { \
|
||||
_impl->updateEventListener(flag); \
|
||||
} \
|
||||
uint32_t CLASS::getObjectID()const { \
|
||||
return _impl->getObjectID(); \
|
||||
} \
|
||||
\
|
||||
|
||||
namespace cc {
|
||||
namespace physics {
|
||||
|
||||
/// COMMON ///
|
||||
CC_PHYSICS_CCT_DEFINITION(CapsuleCharacterController, WrappedCapsuleCharacterController)
|
||||
CC_PHYSICS_CCT_DEFINITION(BoxCharacterController, WrappedBoxCharacterController)
|
||||
|
||||
/// EXTRAS ///
|
||||
|
||||
void CapsuleCharacterController::setRadius(float v) {
|
||||
_impl->setRadius(v);
|
||||
}
|
||||
|
||||
void CapsuleCharacterController::setHeight(float v) {
|
||||
_impl->setHeight(v);
|
||||
}
|
||||
|
||||
void BoxCharacterController::setHalfHeight(float v) {
|
||||
_impl->setHalfHeight(v);
|
||||
}
|
||||
|
||||
void BoxCharacterController::setHalfSideExtent(float v) {
|
||||
_impl->setHalfSideExtent(v);
|
||||
}
|
||||
|
||||
void BoxCharacterController::setHalfForwardExtent(float v) {
|
||||
_impl->setHalfForwardExtent(v);
|
||||
}
|
||||
|
||||
} // namespace physics
|
||||
} // namespace cc
|
||||
80
cocos/physics/sdk/CharacterController.h
Normal file
80
cocos/physics/sdk/CharacterController.h
Normal file
@@ -0,0 +1,80 @@
|
||||
/****************************************************************************
|
||||
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 <memory>
|
||||
#include "base/Macros.h"
|
||||
#include "core/scene-graph/Node.h"
|
||||
#include "physics/spec/IShape.h"
|
||||
#include "physics/spec/ICharacterController.h"
|
||||
|
||||
#define CC_PHYSICS_CCT_CLASS(CLASS) \
|
||||
class CC_DLL CLASS final : public I##CLASS { \
|
||||
protected: \
|
||||
std::unique_ptr<I##CLASS> _impl; \
|
||||
\
|
||||
public: \
|
||||
CLASS(); \
|
||||
~CLASS() override; \
|
||||
bool initialize(Node *node) override; \
|
||||
void onEnable() override; \
|
||||
void onDisable() override; \
|
||||
void onDestroy() override; \
|
||||
virtual cc::Vec3 getPosition() override; \
|
||||
virtual void setPosition(float x, float y, float z) override; \
|
||||
virtual bool onGround() override; \
|
||||
virtual void move(float x, float y, float z, float minDist, \
|
||||
float elapsedTime) override; \
|
||||
void syncPhysicsToScene() override; \
|
||||
virtual void setStepOffset(float v) override; \
|
||||
virtual float getStepOffset() override; \
|
||||
virtual void setSlopeLimit(float v) override; \
|
||||
virtual float getSlopeLimit() override; \
|
||||
virtual void setContactOffset(float v) override; \
|
||||
virtual float getContactOffset() override; \
|
||||
virtual void setDetectCollisions(bool v) override; \
|
||||
virtual void setOverlapRecovery(bool v) override; \
|
||||
virtual void setCenter(float x, float y, float z) override; \
|
||||
uint32_t getGroup() override; \
|
||||
void setGroup(uint32_t g) override; \
|
||||
uint32_t getMask() override; \
|
||||
void setMask(uint32_t m) override; \
|
||||
void updateEventListener(EShapeFilterFlag flag) override; \
|
||||
uint32_t getObjectID() const override;
|
||||
|
||||
namespace cc {
|
||||
namespace physics {
|
||||
CC_PHYSICS_CCT_CLASS(CapsuleCharacterController)
|
||||
void setRadius(float v) override;
|
||||
void setHeight(float v) override;
|
||||
};
|
||||
|
||||
CC_PHYSICS_CCT_CLASS(BoxCharacterController)
|
||||
void setHalfHeight(float v) override;
|
||||
void setHalfSideExtent(float v) override;
|
||||
void setHalfForwardExtent(float v) override;
|
||||
};
|
||||
}; // namespace physics
|
||||
} // namespace cc
|
||||
223
cocos/physics/sdk/Joint.cpp
Normal file
223
cocos/physics/sdk/Joint.cpp
Normal file
@@ -0,0 +1,223 @@
|
||||
/****************************************************************************
|
||||
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/sdk/Joint.h"
|
||||
#include "base/memory/Memory.h"
|
||||
#include "physics/PhysicsSelector.h"
|
||||
|
||||
#define CC_PHYSICS_JOINT_DEFINITION(CLASS, WRAPPED) \
|
||||
\
|
||||
CLASS::CLASS() { \
|
||||
_impl.reset(ccnew WRAPPED()); \
|
||||
} \
|
||||
\
|
||||
CLASS::~CLASS() { \
|
||||
_impl.reset(nullptr); \
|
||||
} \
|
||||
\
|
||||
void CLASS::initialize(Node *node) { \
|
||||
_impl->initialize(node); \
|
||||
} \
|
||||
\
|
||||
void CLASS::onEnable() { \
|
||||
_impl->onEnable(); \
|
||||
} \
|
||||
\
|
||||
void CLASS::onDisable() { \
|
||||
_impl->onDisable(); \
|
||||
} \
|
||||
\
|
||||
void CLASS::onDestroy() { \
|
||||
_impl->onDestroy(); \
|
||||
} \
|
||||
\
|
||||
void CLASS::setConnectedBody(uint32_t rigidBodyID) { \
|
||||
_impl->setConnectedBody(rigidBodyID); \
|
||||
} \
|
||||
\
|
||||
void CLASS::setEnableCollision(bool v) { \
|
||||
_impl->setEnableCollision(v); \
|
||||
} \
|
||||
uint32_t CLASS::getObjectID() const { \
|
||||
return _impl->getObjectID(); \
|
||||
}
|
||||
|
||||
namespace cc {
|
||||
namespace physics {
|
||||
|
||||
/// COMMON ///
|
||||
|
||||
CC_PHYSICS_JOINT_DEFINITION(SphericalJoint, WrappedSphericalJoint)
|
||||
CC_PHYSICS_JOINT_DEFINITION(RevoluteJoint, WrappedRevoluteJoint)
|
||||
CC_PHYSICS_JOINT_DEFINITION(FixedJoint, WrappedFixedJoint)
|
||||
CC_PHYSICS_JOINT_DEFINITION(GenericJoint, WrappedGenericJoint)
|
||||
|
||||
/// EXTRAS ///
|
||||
|
||||
void SphericalJoint::setPivotA(float x, float y, float z) {
|
||||
_impl->setPivotA(x, y, z);
|
||||
}
|
||||
|
||||
void SphericalJoint::setPivotB(float x, float y, float z) {
|
||||
_impl->setPivotB(x, y, z);
|
||||
}
|
||||
|
||||
void RevoluteJoint::setPivotA(float x, float y, float z) {
|
||||
_impl->setPivotA(x, y, z);
|
||||
}
|
||||
|
||||
void RevoluteJoint::setPivotB(float x, float y, float z) {
|
||||
_impl->setPivotB(x, y, z);
|
||||
}
|
||||
|
||||
void RevoluteJoint::setAxis(float x, float y, float z) {
|
||||
_impl->setAxis(x, y, z);
|
||||
}
|
||||
|
||||
void RevoluteJoint::setLimitEnabled(bool v) {
|
||||
_impl->setLimitEnabled(v);
|
||||
}
|
||||
|
||||
void RevoluteJoint::setLowerLimit(float v) {
|
||||
_impl->setLowerLimit(v);
|
||||
}
|
||||
|
||||
void RevoluteJoint::setUpperLimit(float v) {
|
||||
_impl->setUpperLimit(v);
|
||||
}
|
||||
|
||||
void RevoluteJoint::setMotorEnabled(bool v) {
|
||||
_impl->setMotorEnabled(v);
|
||||
}
|
||||
|
||||
void RevoluteJoint::setMotorVelocity(float v) {
|
||||
_impl->setMotorVelocity(v);
|
||||
}
|
||||
|
||||
void RevoluteJoint::setMotorForceLimit(float v) {
|
||||
_impl->setMotorForceLimit(v);
|
||||
}
|
||||
|
||||
void FixedJoint::setBreakForce(float force) {
|
||||
_impl->setBreakForce(force);
|
||||
}
|
||||
|
||||
void FixedJoint::setBreakTorque(float torque) {
|
||||
_impl->setBreakTorque(torque);
|
||||
}
|
||||
|
||||
void GenericJoint::setConstraintMode(uint32_t index, uint32_t mode) {
|
||||
_impl->setConstraintMode(index, mode);
|
||||
}
|
||||
void GenericJoint::setLinearLimit(uint32_t index, float lower, float upper) {
|
||||
_impl->setLinearLimit(index, lower, upper);
|
||||
}
|
||||
|
||||
void GenericJoint::setAngularExtent(float twist, float swing1, float swing2) {
|
||||
_impl->setAngularExtent(twist, swing1, swing2);
|
||||
}
|
||||
void GenericJoint::setLinearSoftConstraint(bool enable) {
|
||||
_impl->setLinearSoftConstraint(enable);
|
||||
}
|
||||
void GenericJoint::setLinearStiffness(float stiffness) {
|
||||
_impl->setLinearStiffness(stiffness);
|
||||
}
|
||||
void GenericJoint::setLinearDamping(float damping) {
|
||||
_impl->setLinearDamping(damping);
|
||||
}
|
||||
void GenericJoint::setLinearRestitution(float restitution) {
|
||||
_impl->setLinearRestitution(restitution);
|
||||
}
|
||||
|
||||
void GenericJoint::setSwingSoftConstraint(bool enable) {
|
||||
_impl->setSwingSoftConstraint(enable);
|
||||
}
|
||||
void GenericJoint::setTwistSoftConstraint(bool enable) {
|
||||
_impl->setTwistSoftConstraint(enable);
|
||||
}
|
||||
void GenericJoint::setSwingStiffness(float stiffness) {
|
||||
_impl->setSwingStiffness(stiffness);
|
||||
}
|
||||
void GenericJoint::setSwingDamping(float damping) {
|
||||
_impl->setSwingDamping(damping);
|
||||
}
|
||||
void GenericJoint::setSwingRestitution(float restitution) {
|
||||
_impl->setSwingRestitution(restitution);
|
||||
}
|
||||
void GenericJoint::setTwistStiffness(float stiffness) {
|
||||
_impl->setTwistStiffness(stiffness);
|
||||
}
|
||||
void GenericJoint::setTwistDamping(float damping) {
|
||||
_impl->setTwistDamping(damping);
|
||||
}
|
||||
void GenericJoint::setTwistRestitution(float restitution) {
|
||||
_impl->setTwistRestitution(restitution);
|
||||
}
|
||||
|
||||
void GenericJoint::setDriverMode(uint32_t index, uint32_t mode) {
|
||||
_impl->setDriverMode(index, mode);
|
||||
}
|
||||
void GenericJoint::setLinearMotorTarget(float x, float y, float z) {
|
||||
_impl->setLinearMotorTarget(x, y, z);
|
||||
}
|
||||
void GenericJoint::setLinearMotorVelocity(float x, float y, float z) {
|
||||
_impl->setLinearMotorVelocity(x, y, z);
|
||||
}
|
||||
void GenericJoint::setLinearMotorForceLimit(float limit) {
|
||||
_impl->setLinearMotorForceLimit(limit);
|
||||
}
|
||||
void GenericJoint::setAngularMotorTarget(float x, float y, float z) {
|
||||
_impl->setAngularMotorTarget(x, y, z);
|
||||
}
|
||||
void GenericJoint::setAngularMotorVelocity(float x, float y, float z) {
|
||||
_impl->setAngularMotorVelocity(x, y, z);
|
||||
}
|
||||
void GenericJoint::setAngularMotorForceLimit(float limit) {
|
||||
_impl->setAngularMotorForceLimit(limit);
|
||||
}
|
||||
void GenericJoint::setPivotA(float x, float y, float z) {
|
||||
_impl->setPivotA(x, y, z);
|
||||
}
|
||||
void GenericJoint::setPivotB(float x, float y, float z) {
|
||||
_impl->setPivotB(x, y, z);
|
||||
}
|
||||
void GenericJoint::setAutoPivotB(bool enable) {
|
||||
_impl->setAutoPivotB(enable);
|
||||
}
|
||||
void GenericJoint::setAxis(float x, float y, float z) {
|
||||
_impl->setAxis(x, y, z);
|
||||
}
|
||||
void GenericJoint::setSecondaryAxis(float x, float y, float z) {
|
||||
_impl->setSecondaryAxis(x, y, z);
|
||||
}
|
||||
|
||||
void GenericJoint::setBreakForce(float force) {
|
||||
_impl->setBreakForce(force);
|
||||
}
|
||||
void GenericJoint::setBreakTorque(float torque) {
|
||||
_impl->setBreakTorque(torque);
|
||||
}
|
||||
|
||||
} // namespace physics
|
||||
} // namespace cc
|
||||
114
cocos/physics/sdk/Joint.h
Normal file
114
cocos/physics/sdk/Joint.h
Normal file
@@ -0,0 +1,114 @@
|
||||
/****************************************************************************
|
||||
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 <cstdint>
|
||||
#include <memory>
|
||||
#include "base/Macros.h"
|
||||
#include "core/scene-graph/Node.h"
|
||||
#include "physics/spec/IJoint.h"
|
||||
|
||||
#define CC_PHYSICS_JOINT_CLASS(CLASS) \
|
||||
class CC_DLL CLASS final : virtual public I##CLASS { \
|
||||
protected: \
|
||||
std::unique_ptr<I##CLASS> _impl; \
|
||||
\
|
||||
public: \
|
||||
CLASS(); \
|
||||
~CLASS() override; \
|
||||
void initialize(Node *node) override; \
|
||||
void onEnable() override; \
|
||||
void onDisable() override; \
|
||||
void onDestroy() override; \
|
||||
void setEnableCollision(bool v) override; \
|
||||
void setConnectedBody(uint32_t rigidBodyID) override; \
|
||||
uint32_t getObjectID() const override;
|
||||
namespace cc {
|
||||
namespace physics {
|
||||
|
||||
CC_PHYSICS_JOINT_CLASS(RevoluteJoint)
|
||||
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;
|
||||
}; // RevoluteJoint
|
||||
|
||||
CC_PHYSICS_JOINT_CLASS(SphericalJoint)
|
||||
void setPivotA(float x, float y, float z) override;
|
||||
void setPivotB(float x, float y, float z) override;
|
||||
}; // SphericalJoint
|
||||
|
||||
CC_PHYSICS_JOINT_CLASS(FixedJoint)
|
||||
void setBreakForce(float force) override;
|
||||
void setBreakTorque(float torque) override;
|
||||
}
|
||||
; // FixedJoint
|
||||
|
||||
CC_PHYSICS_JOINT_CLASS(GenericJoint)
|
||||
void setConstraintMode(uint32_t index, uint32_t mode) override;
|
||||
void setLinearLimit(uint32_t index, float lower, float upper) override;
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
virtual 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 enable) 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;
|
||||
}
|
||||
;
|
||||
|
||||
} // namespace physics
|
||||
} // namespace cc
|
||||
193
cocos/physics/sdk/RigidBody.cpp
Normal file
193
cocos/physics/sdk/RigidBody.cpp
Normal file
@@ -0,0 +1,193 @@
|
||||
/****************************************************************************
|
||||
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/sdk/RigidBody.h"
|
||||
#include <memory>
|
||||
#include "physics/PhysicsSelector.h"
|
||||
|
||||
namespace cc {
|
||||
namespace physics {
|
||||
|
||||
RigidBody::RigidBody() {
|
||||
_impl = std::make_unique<WrappedRigidBody>();
|
||||
}
|
||||
|
||||
RigidBody::~RigidBody() {
|
||||
_impl.reset(nullptr);
|
||||
}
|
||||
|
||||
void RigidBody::initialize(Node *node, const ERigidBodyType t, const uint32_t g) {
|
||||
_impl->initialize(node, t, g);
|
||||
}
|
||||
|
||||
void RigidBody::onEnable() {
|
||||
_impl->onEnable();
|
||||
}
|
||||
|
||||
void RigidBody::onDisable() {
|
||||
_impl->onDisable();
|
||||
}
|
||||
|
||||
void RigidBody::onDestroy() {
|
||||
_impl->onDestroy();
|
||||
}
|
||||
|
||||
bool RigidBody::isAwake() {
|
||||
return _impl->isAwake();
|
||||
}
|
||||
|
||||
bool RigidBody::isSleepy() {
|
||||
return _impl->isSleepy();
|
||||
}
|
||||
|
||||
bool RigidBody::isSleeping() {
|
||||
return _impl->isSleeping();
|
||||
}
|
||||
|
||||
void RigidBody::setType(ERigidBodyType v) {
|
||||
_impl->setType(v);
|
||||
}
|
||||
|
||||
void RigidBody::setMass(float v) {
|
||||
_impl->setMass(v);
|
||||
}
|
||||
|
||||
void RigidBody::setLinearDamping(float v) {
|
||||
_impl->setLinearDamping(v);
|
||||
}
|
||||
|
||||
void RigidBody::setAngularDamping(float v) {
|
||||
_impl->setAngularDamping(v);
|
||||
}
|
||||
|
||||
void RigidBody::useCCD(bool v) {
|
||||
_impl->useCCD(v);
|
||||
}
|
||||
|
||||
void RigidBody::useGravity(bool v) {
|
||||
_impl->useGravity(v);
|
||||
}
|
||||
|
||||
void RigidBody::setLinearFactor(float x, float y, float z) {
|
||||
_impl->setLinearFactor(x, y, z);
|
||||
}
|
||||
|
||||
void RigidBody::setAngularFactor(float x, float y, float z) {
|
||||
_impl->setAngularFactor(x, y, z);
|
||||
}
|
||||
|
||||
void RigidBody::setAllowSleep(bool v) {
|
||||
_impl->setAllowSleep(v);
|
||||
}
|
||||
|
||||
void RigidBody::wakeUp() {
|
||||
_impl->wakeUp();
|
||||
}
|
||||
|
||||
void RigidBody::sleep() {
|
||||
_impl->sleep();
|
||||
}
|
||||
|
||||
void RigidBody::clearState() {
|
||||
_impl->clearState();
|
||||
}
|
||||
|
||||
void RigidBody::clearForces() {
|
||||
_impl->clearForces();
|
||||
}
|
||||
|
||||
void RigidBody::clearVelocity() {
|
||||
_impl->clearVelocity();
|
||||
}
|
||||
|
||||
void RigidBody::setSleepThreshold(float v) {
|
||||
_impl->setSleepThreshold(v);
|
||||
}
|
||||
|
||||
float RigidBody::getSleepThreshold() {
|
||||
return _impl->getSleepThreshold();
|
||||
}
|
||||
|
||||
cc::Vec3 RigidBody::getLinearVelocity() {
|
||||
return _impl->getLinearVelocity();
|
||||
}
|
||||
|
||||
void RigidBody::setLinearVelocity(float x, float y, float z) {
|
||||
_impl->setLinearVelocity(x, y, z);
|
||||
}
|
||||
|
||||
cc::Vec3 RigidBody::getAngularVelocity() {
|
||||
return _impl->getAngularVelocity();
|
||||
}
|
||||
|
||||
void RigidBody::setAngularVelocity(float x, float y, float z) {
|
||||
_impl->setAngularVelocity(x, y, z);
|
||||
}
|
||||
|
||||
void RigidBody::applyForce(float x, float y, float z, float rx, float ry, float rz) {
|
||||
_impl->applyForce(x, y, z, rx, ry, rz);
|
||||
}
|
||||
|
||||
void RigidBody::applyLocalForce(float x, float y, float z, float rx, float ry, float rz) {
|
||||
_impl->applyLocalForce(x, y, z, rx, ry, rz);
|
||||
}
|
||||
|
||||
void RigidBody::applyImpulse(float x, float y, float z, float rx, float ry, float rz) {
|
||||
_impl->applyImpulse(x, y, z, rx, ry, rz);
|
||||
}
|
||||
|
||||
void RigidBody::applyLocalImpulse(float x, float y, float z, float rx, float ry, float rz) {
|
||||
_impl->applyLocalImpulse(x, y, z, rx, ry, rz);
|
||||
}
|
||||
|
||||
void RigidBody::applyTorque(float x, float y, float z) {
|
||||
_impl->applyTorque(x, y, z);
|
||||
}
|
||||
|
||||
void RigidBody::applyLocalTorque(float x, float y, float z) {
|
||||
_impl->applyLocalTorque(x, y, z);
|
||||
}
|
||||
|
||||
uint32_t RigidBody::getGroup() {
|
||||
return _impl->getGroup();
|
||||
}
|
||||
|
||||
void RigidBody::setGroup(uint32_t g) {
|
||||
_impl->setGroup(g);
|
||||
}
|
||||
|
||||
uint32_t RigidBody::getMask() {
|
||||
return _impl->getMask();
|
||||
}
|
||||
|
||||
void RigidBody::setMask(uint32_t m) {
|
||||
_impl->setMask(m);
|
||||
}
|
||||
|
||||
uint32_t RigidBody::getObjectID() const {
|
||||
return _impl->getObjectID();
|
||||
}
|
||||
|
||||
} // namespace physics
|
||||
} // namespace cc
|
||||
80
cocos/physics/sdk/RigidBody.h
Normal file
80
cocos/physics/sdk/RigidBody.h
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.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include "base/Macros.h"
|
||||
#include "physics/spec/IBody.h"
|
||||
|
||||
namespace cc {
|
||||
namespace physics {
|
||||
class CC_DLL RigidBody final : public IRigidBody {
|
||||
public:
|
||||
RigidBody();
|
||||
~RigidBody() override;
|
||||
void initialize(Node *node, ERigidBodyType t, uint32_t g) override;
|
||||
void onEnable() override;
|
||||
void onDisable() override;
|
||||
void onDestroy() override;
|
||||
bool isAwake() override;
|
||||
bool isSleepy() override;
|
||||
bool isSleeping() override;
|
||||
void setType(ERigidBodyType v) override;
|
||||
void setMass(float v) override;
|
||||
void setLinearDamping(float v) override;
|
||||
void setAngularDamping(float v) override;
|
||||
void useGravity(bool v) override;
|
||||
void useCCD(bool v) override;
|
||||
void setLinearFactor(float x, float y, float z) override;
|
||||
void setAngularFactor(float x, float y, float z) override;
|
||||
void setAllowSleep(bool v) override;
|
||||
void wakeUp() override;
|
||||
void sleep() override;
|
||||
void clearState() override;
|
||||
void clearForces() override;
|
||||
void clearVelocity() override;
|
||||
void setSleepThreshold(float v) override;
|
||||
float getSleepThreshold() override;
|
||||
cc::Vec3 getLinearVelocity() override;
|
||||
void setLinearVelocity(float x, float y, float z) override;
|
||||
cc::Vec3 getAngularVelocity() override;
|
||||
void setAngularVelocity(float x, float y, float z) override;
|
||||
void applyForce(float x, float y, float z, float rx, float ry, float rz) override;
|
||||
void applyLocalForce(float x, float y, float z, float rx, float ry, float rz) override;
|
||||
void applyImpulse(float x, float y, float z, float rx, float ry, float rz) override;
|
||||
void applyLocalImpulse(float x, float y, float z, float rx, float ry, float rz) override;
|
||||
void applyTorque(float x, float y, float z) override;
|
||||
void applyLocalTorque(float x, float y, float z) override;
|
||||
uint32_t getGroup() override;
|
||||
void setGroup(uint32_t g) override;
|
||||
uint32_t getMask() override;
|
||||
void setMask(uint32_t m) override;
|
||||
uint32_t getObjectID() const override;
|
||||
|
||||
private:
|
||||
std::unique_ptr<IRigidBody> _impl;
|
||||
};
|
||||
} // namespace physics
|
||||
} // namespace cc
|
||||
173
cocos/physics/sdk/Shape.cpp
Normal file
173
cocos/physics/sdk/Shape.cpp
Normal file
@@ -0,0 +1,173 @@
|
||||
/****************************************************************************
|
||||
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/sdk/Shape.h"
|
||||
#include "base/memory/Memory.h"
|
||||
#include "physics/PhysicsSelector.h"
|
||||
|
||||
#define CC_PHYSICS_SHAPE_DEFINITION(CLASS, WRAPPED) \
|
||||
\
|
||||
CLASS::CLASS() { \
|
||||
_impl.reset(ccnew WRAPPED()); \
|
||||
} \
|
||||
\
|
||||
CLASS::~CLASS() { \
|
||||
_impl.reset(nullptr); \
|
||||
} \
|
||||
\
|
||||
void CLASS::initialize(Node *node) { \
|
||||
_impl->initialize(node); \
|
||||
} \
|
||||
\
|
||||
void CLASS::onEnable() { \
|
||||
_impl->onEnable(); \
|
||||
} \
|
||||
\
|
||||
void CLASS::onDisable() { \
|
||||
_impl->onDisable(); \
|
||||
} \
|
||||
\
|
||||
void CLASS::onDestroy() { \
|
||||
_impl->onDestroy(); \
|
||||
} \
|
||||
\
|
||||
void CLASS::setMaterial(uint16_t ID, float f, float df, float r, \
|
||||
uint8_t m0, uint8_t m1) { \
|
||||
_impl->setMaterial(ID, f, df, r, m0, m1); \
|
||||
} \
|
||||
\
|
||||
void CLASS::setAsTrigger(bool v) { \
|
||||
_impl->setAsTrigger(v); \
|
||||
} \
|
||||
\
|
||||
void CLASS::setCenter(float x, float y, float z) { \
|
||||
_impl->setCenter(x, y, z); \
|
||||
} \
|
||||
\
|
||||
void CLASS::setGroup(uint32_t g) { \
|
||||
_impl->setGroup(g); \
|
||||
} \
|
||||
\
|
||||
uint32_t CLASS::getGroup() { \
|
||||
return _impl->getGroup(); \
|
||||
} \
|
||||
\
|
||||
void CLASS::setMask(uint32_t m) { \
|
||||
_impl->setMask(m); \
|
||||
} \
|
||||
\
|
||||
uint32_t CLASS::getMask() { \
|
||||
return _impl->getMask(); \
|
||||
} \
|
||||
\
|
||||
void CLASS::updateEventListener(EShapeFilterFlag v) { \
|
||||
_impl->updateEventListener(v); \
|
||||
} \
|
||||
\
|
||||
geometry::AABB &CLASS::getAABB() { \
|
||||
return _impl->getAABB(); \
|
||||
} \
|
||||
\
|
||||
geometry::Sphere &CLASS::getBoundingSphere() { \
|
||||
return _impl->getBoundingSphere(); \
|
||||
} \
|
||||
\
|
||||
uint32_t CLASS::getObjectID() const { \
|
||||
return _impl->getObjectID(); \
|
||||
}
|
||||
|
||||
namespace cc {
|
||||
namespace physics {
|
||||
|
||||
/// COMMON ///
|
||||
|
||||
CC_PHYSICS_SHAPE_DEFINITION(SphereShape, WrappedSphereShape)
|
||||
CC_PHYSICS_SHAPE_DEFINITION(BoxShape, WrappedBoxShape)
|
||||
CC_PHYSICS_SHAPE_DEFINITION(PlaneShape, WrappedPlaneShape)
|
||||
CC_PHYSICS_SHAPE_DEFINITION(CapsuleShape, WrappedCapsuleShape)
|
||||
CC_PHYSICS_SHAPE_DEFINITION(CylinderShape, WrappedCylinderShape)
|
||||
CC_PHYSICS_SHAPE_DEFINITION(ConeShape, WrappedConeShape)
|
||||
CC_PHYSICS_SHAPE_DEFINITION(TrimeshShape, WrappedTrimeshShape)
|
||||
CC_PHYSICS_SHAPE_DEFINITION(TerrainShape, WrappedTerrainShape)
|
||||
|
||||
/// EXTRAS ///
|
||||
|
||||
void SphereShape::setRadius(float v) {
|
||||
_impl->setRadius(v);
|
||||
}
|
||||
|
||||
void BoxShape::setSize(float x, float y, float z) {
|
||||
_impl->setSize(x, y, z);
|
||||
}
|
||||
|
||||
void CapsuleShape::setRadius(float v) {
|
||||
_impl->setRadius(v);
|
||||
}
|
||||
|
||||
void CapsuleShape::setCylinderHeight(float v) {
|
||||
_impl->setCylinderHeight(v);
|
||||
}
|
||||
|
||||
void CapsuleShape::setDirection(EAxisDirection v) {
|
||||
_impl->setDirection(v);
|
||||
}
|
||||
|
||||
void PlaneShape::setConstant(float v) {
|
||||
_impl->setConstant(v);
|
||||
}
|
||||
|
||||
void PlaneShape::setNormal(float x, float y, float z) {
|
||||
_impl->setNormal(x, y, z);
|
||||
}
|
||||
|
||||
void TrimeshShape::setMesh(uint32_t objectID) {
|
||||
_impl->setMesh(objectID);
|
||||
}
|
||||
|
||||
void TrimeshShape::useConvex(bool v) {
|
||||
_impl->useConvex(v);
|
||||
}
|
||||
|
||||
void TerrainShape::setTerrain(uint32_t objectID, float rs, float cs, float hs) {
|
||||
_impl->setTerrain(objectID, rs, cs, hs);
|
||||
}
|
||||
|
||||
void CylinderShape::setConvex(uint32_t objectID) {
|
||||
_impl->setConvex(objectID);
|
||||
}
|
||||
|
||||
void CylinderShape::setCylinder(float r, float h, EAxisDirection d) {
|
||||
_impl->setCylinder(r, h, d);
|
||||
}
|
||||
|
||||
void ConeShape::setConvex(uint32_t objectID) {
|
||||
_impl->setConvex(objectID);
|
||||
}
|
||||
|
||||
void ConeShape::setCone(float r, float h, EAxisDirection d) {
|
||||
_impl->setCone(r, h, d);
|
||||
}
|
||||
|
||||
} // namespace physics
|
||||
} // namespace cc
|
||||
107
cocos/physics/sdk/Shape.h
Normal file
107
cocos/physics/sdk/Shape.h
Normal file
@@ -0,0 +1,107 @@
|
||||
/****************************************************************************
|
||||
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 <cstdint>
|
||||
#include <memory>
|
||||
#include "base/Macros.h"
|
||||
#include "core/geometry/AABB.h"
|
||||
#include "core/geometry/Sphere.h"
|
||||
#include "physics/spec/IShape.h"
|
||||
|
||||
#define CC_PHYSICS_SHAPE_CLASS(CLASS) \
|
||||
class CC_DLL CLASS final : public I##CLASS { \
|
||||
protected: \
|
||||
std::unique_ptr<I##CLASS> _impl; \
|
||||
\
|
||||
public: \
|
||||
CLASS(); \
|
||||
~CLASS() override; \
|
||||
void initialize(Node *node) override; \
|
||||
void onEnable() override; \
|
||||
void onDisable() override; \
|
||||
void onDestroy() override; \
|
||||
void setMaterial(uint16_t ID, float f, float df, float r, \
|
||||
uint8_t m0, uint8_t m1) override; \
|
||||
void setAsTrigger(bool v) override; \
|
||||
void setCenter(float x, float y, float z) override; \
|
||||
void updateEventListener(EShapeFilterFlag v) override; \
|
||||
geometry::AABB &getAABB() override; \
|
||||
geometry::Sphere &getBoundingSphere() override; \
|
||||
uint32_t getGroup() override; \
|
||||
void setGroup(uint32_t g) override; \
|
||||
uint32_t getMask() override; \
|
||||
void setMask(uint32_t m) override; \
|
||||
uint32_t getObjectID() const override;
|
||||
|
||||
namespace cc {
|
||||
namespace physics {
|
||||
|
||||
CC_PHYSICS_SHAPE_CLASS(SphereShape)
|
||||
void setRadius(float v) override;
|
||||
}; // namespace physics
|
||||
|
||||
CC_PHYSICS_SHAPE_CLASS(BoxShape)
|
||||
void setSize(float x, float y, float z) override;
|
||||
}; // namespace cc
|
||||
|
||||
CC_PHYSICS_SHAPE_CLASS(CapsuleShape)
|
||||
void setRadius(float v) override;
|
||||
void setCylinderHeight(float v) override;
|
||||
void setDirection(EAxisDirection v) override;
|
||||
}
|
||||
;
|
||||
|
||||
CC_PHYSICS_SHAPE_CLASS(PlaneShape)
|
||||
void setConstant(float v) override;
|
||||
void setNormal(float x, float y, float z) override;
|
||||
}
|
||||
;
|
||||
|
||||
CC_PHYSICS_SHAPE_CLASS(TrimeshShape)
|
||||
void setMesh(uint32_t objectID) override;
|
||||
void useConvex(bool v) override;
|
||||
}
|
||||
;
|
||||
|
||||
CC_PHYSICS_SHAPE_CLASS(CylinderShape)
|
||||
void setConvex(uint32_t objectID) override;
|
||||
void setCylinder(float r, float h, EAxisDirection d) override;
|
||||
}
|
||||
;
|
||||
|
||||
CC_PHYSICS_SHAPE_CLASS(ConeShape)
|
||||
void setConvex(uint32_t objectID) override;
|
||||
void setCone(float r, float h, EAxisDirection d) override;
|
||||
}
|
||||
;
|
||||
|
||||
CC_PHYSICS_SHAPE_CLASS(TerrainShape)
|
||||
void setTerrain(uint32_t objectID, float rs, float cs, float hs) override;
|
||||
}
|
||||
;
|
||||
|
||||
} // namespace physics
|
||||
} // namespace cc
|
||||
182
cocos/physics/sdk/World.cpp
Normal file
182
cocos/physics/sdk/World.cpp
Normal file
@@ -0,0 +1,182 @@
|
||||
/****************************************************************************
|
||||
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/sdk/World.h"
|
||||
#include <memory>
|
||||
#include "physics/PhysicsSelector.h"
|
||||
|
||||
namespace cc {
|
||||
namespace physics {
|
||||
|
||||
World::World() {
|
||||
_impl = std::make_unique<WrappedWorld>();
|
||||
}
|
||||
|
||||
World::~World() {
|
||||
_impl.reset(nullptr);
|
||||
}
|
||||
|
||||
void World::emitEvents() {
|
||||
_impl->emitEvents();
|
||||
}
|
||||
|
||||
void World::step(float fixedTimeStep) {
|
||||
_impl->step(fixedTimeStep);
|
||||
}
|
||||
|
||||
void World::setAllowSleep(bool v) {
|
||||
_impl->setAllowSleep(v);
|
||||
}
|
||||
|
||||
void World::setGravity(float x, float y, float z) {
|
||||
_impl->setGravity(x, y, z);
|
||||
}
|
||||
|
||||
bool World::createMaterial(uint16_t id, float f, float df, float r,
|
||||
uint8_t m0, uint8_t m1) {
|
||||
return _impl->createMaterial(id, f, df, r, m0, m1);
|
||||
}
|
||||
|
||||
void World::syncSceneToPhysics() {
|
||||
_impl->syncSceneToPhysics();
|
||||
}
|
||||
|
||||
void World::syncSceneWithCheck() {
|
||||
_impl->syncSceneWithCheck();
|
||||
}
|
||||
|
||||
void World::destroy() {
|
||||
_impl->destroy();
|
||||
}
|
||||
|
||||
ccstd::vector<std::shared_ptr<TriggerEventPair>> &World::getTriggerEventPairs() {
|
||||
return _impl->getTriggerEventPairs();
|
||||
}
|
||||
|
||||
ccstd::vector<std::shared_ptr<ContactEventPair>> &World::getContactEventPairs() {
|
||||
return _impl->getContactEventPairs();
|
||||
}
|
||||
|
||||
ccstd::vector<std::shared_ptr<CCTShapeEventPair>>& World::getCCTShapeEventPairs() {
|
||||
return _impl->getCCTShapeEventPairs();
|
||||
}
|
||||
|
||||
ccstd::vector<std::shared_ptr<CCTTriggerEventPair>> &World::getCCTTriggerEventPairs() {
|
||||
return _impl->getCCTTriggerEventPairs();
|
||||
}
|
||||
|
||||
void World::setDebugDrawFlags(EPhysicsDrawFlags flags) {
|
||||
_impl->setDebugDrawFlags(flags);
|
||||
}
|
||||
|
||||
EPhysicsDrawFlags World::getDebugDrawFlags() {
|
||||
return _impl->getDebugDrawFlags();
|
||||
}
|
||||
|
||||
void World::setDebugDrawConstraintSize(float size) {
|
||||
_impl->setDebugDrawConstraintSize(size);
|
||||
}
|
||||
|
||||
float World::getDebugDrawConstraintSize() {
|
||||
return _impl->getDebugDrawConstraintSize();
|
||||
}
|
||||
|
||||
void World::setCollisionMatrix(uint32_t i, uint32_t m) {
|
||||
_impl->setCollisionMatrix(i, m);
|
||||
}
|
||||
|
||||
uint32_t World::createConvex(ConvexDesc &desc) {
|
||||
return _impl->createConvex(desc);
|
||||
}
|
||||
|
||||
uint32_t World::createTrimesh(TrimeshDesc &desc) {
|
||||
return _impl->createTrimesh(desc);
|
||||
}
|
||||
|
||||
uint32_t World::createHeightField(HeightFieldDesc &desc) {
|
||||
return _impl->createHeightField(desc);
|
||||
}
|
||||
|
||||
bool World::raycast(RaycastOptions &opt) {
|
||||
return _impl->raycast(opt);
|
||||
}
|
||||
|
||||
ccstd::vector<RaycastResult> &World::raycastResult() {
|
||||
return _impl->raycastResult();
|
||||
}
|
||||
|
||||
bool World::raycastClosest(RaycastOptions &opt) {
|
||||
return _impl->raycastClosest(opt);
|
||||
}
|
||||
|
||||
RaycastResult &World::raycastClosestResult() {
|
||||
return _impl->raycastClosestResult();
|
||||
}
|
||||
|
||||
float World::getFixedTimeStep() const {
|
||||
return _impl->getFixedTimeStep();
|
||||
}
|
||||
|
||||
void World::setFixedTimeStep(float fixedTimeStep) {
|
||||
_impl->setFixedTimeStep(fixedTimeStep);
|
||||
}
|
||||
|
||||
bool World::sweepBox(RaycastOptions &opt, float halfExtentX, float halfExtentY, float halfExtentZ,
|
||||
float orientationW, float orientationX, float orientationY, float orientationZ){
|
||||
return _impl->sweepBox(opt, halfExtentX, halfExtentY, halfExtentZ, orientationW, orientationX, orientationY, orientationZ);
|
||||
}
|
||||
|
||||
bool World::sweepBoxClosest(RaycastOptions &opt, float halfExtentX, float halfExtentY, float halfExtentZ,
|
||||
float orientationW, float orientationX, float orientationY, float orientationZ){
|
||||
return _impl->sweepBoxClosest(opt, halfExtentX, halfExtentY, halfExtentZ, orientationW, orientationX, orientationY, orientationZ);
|
||||
}
|
||||
|
||||
bool World::sweepSphere(RaycastOptions &opt, float radius) {
|
||||
return _impl->sweepSphere(opt, radius);
|
||||
}
|
||||
|
||||
bool World::sweepSphereClosest(RaycastOptions &opt, float radius) {
|
||||
return _impl->sweepSphereClosest(opt, radius);
|
||||
}
|
||||
|
||||
bool World::sweepCapsule(RaycastOptions &opt, float radius, float height,
|
||||
float orientationW, float orientationX, float orientationY, float orientationZ) {
|
||||
return _impl->sweepCapsule(opt, radius, height, orientationW, orientationX, orientationY, orientationZ);
|
||||
}
|
||||
|
||||
bool World::sweepCapsuleClosest(RaycastOptions &opt, float radius, float height,
|
||||
float orientationW, float orientationX, float orientationY, float orientationZ) {
|
||||
return _impl->sweepCapsuleClosest(opt, radius, height, orientationW, orientationX, orientationY, orientationZ);
|
||||
}
|
||||
|
||||
RaycastResult &World::sweepClosestResult() {
|
||||
return _impl->sweepClosestResult();
|
||||
}
|
||||
|
||||
ccstd::vector<RaycastResult> &World::sweepResult() {
|
||||
return _impl->sweepResult();
|
||||
}
|
||||
|
||||
} // namespace physics
|
||||
} // namespace cc
|
||||
83
cocos/physics/sdk/World.h
Normal file
83
cocos/physics/sdk/World.h
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.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include "base/Macros.h"
|
||||
#include "physics/spec/IWorld.h"
|
||||
|
||||
namespace cc {
|
||||
namespace physics {
|
||||
class CC_DLL World final : public IPhysicsWorld {
|
||||
public:
|
||||
World();
|
||||
~World() override;
|
||||
void setGravity(float x, float y, float z) override;
|
||||
void setAllowSleep(bool v) override;
|
||||
void step(float fixedTimeStep) override;
|
||||
void emitEvents() override;
|
||||
void syncSceneToPhysics() override;
|
||||
void syncSceneWithCheck() override;
|
||||
void setDebugDrawFlags(EPhysicsDrawFlags flags) override;
|
||||
EPhysicsDrawFlags getDebugDrawFlags() override;
|
||||
void setDebugDrawConstraintSize(float size) override;
|
||||
float getDebugDrawConstraintSize() override;
|
||||
void setCollisionMatrix(uint32_t i, uint32_t m) override;
|
||||
ccstd::vector<std::shared_ptr<TriggerEventPair>> &getTriggerEventPairs() override;
|
||||
ccstd::vector<std::shared_ptr<ContactEventPair>>& getContactEventPairs() override;
|
||||
ccstd::vector<std::shared_ptr<CCTShapeEventPair>>& getCCTShapeEventPairs() override;
|
||||
ccstd::vector<std::shared_ptr<CCTTriggerEventPair>>& getCCTTriggerEventPairs() override;
|
||||
bool raycast(RaycastOptions &opt) override;
|
||||
bool raycastClosest(RaycastOptions &opt) override;
|
||||
ccstd::vector<RaycastResult> &raycastResult() override;
|
||||
RaycastResult &raycastClosestResult() override;
|
||||
bool sweepBox(RaycastOptions &opt, float halfExtentX, float halfExtentY, float halfExtentZ,
|
||||
float orientationW, float orientationX, float orientationY, float orientationZ) override;
|
||||
bool sweepBoxClosest(RaycastOptions &opt, float halfExtentX, float halfExtentY, float halfExtentZ,
|
||||
float orientationW, float orientationX, float orientationY, float orientationZ) override;
|
||||
bool sweepSphere(RaycastOptions &opt, float radius) override;
|
||||
bool sweepSphereClosest(RaycastOptions &opt, float radius) override;
|
||||
bool sweepCapsule(RaycastOptions &opt, float radius, float height,
|
||||
float orientationW, float orientationX, float orientationY, float orientationZ) override;
|
||||
bool sweepCapsuleClosest(RaycastOptions &opt, float radius, float height,
|
||||
float orientationW, float orientationX, float orientationY, float orientationZ) override;
|
||||
RaycastResult &sweepClosestResult() override;
|
||||
ccstd::vector<RaycastResult> &sweepResult() override;
|
||||
|
||||
uint32_t createConvex(ConvexDesc &desc) override;
|
||||
uint32_t createTrimesh(TrimeshDesc &desc) override;
|
||||
uint32_t createHeightField(HeightFieldDesc &desc) override;
|
||||
bool createMaterial(uint16_t id, float f, float df, float r,
|
||||
uint8_t m0, uint8_t m1) override;
|
||||
float getFixedTimeStep() const override;
|
||||
void setFixedTimeStep(float fixedTimeStep) override;
|
||||
|
||||
void destroy() override;
|
||||
|
||||
private:
|
||||
std::unique_ptr<IPhysicsWorld> _impl;
|
||||
};
|
||||
} // namespace physics
|
||||
} // namespace cc
|
||||
81
cocos/physics/spec/IBody.h
Normal file
81
cocos/physics/spec/IBody.h
Normal file
@@ -0,0 +1,81 @@
|
||||
/****************************************************************************
|
||||
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 "core/scene-graph/Node.h"
|
||||
#include "math/Vec3.h"
|
||||
#include "physics/spec/ILifecycle.h"
|
||||
|
||||
namespace cc {
|
||||
namespace physics {
|
||||
|
||||
enum class ERigidBodyType : uint8_t {
|
||||
DYNAMIC = 1,
|
||||
STATIC = 2,
|
||||
KINEMATIC = 4,
|
||||
};
|
||||
|
||||
class IRigidBody : public ILifecycle {
|
||||
public:
|
||||
~IRigidBody() override = default;
|
||||
virtual void initialize(Node *node, ERigidBodyType t, uint32_t g) = 0;
|
||||
virtual bool isAwake() = 0;
|
||||
virtual bool isSleepy() = 0;
|
||||
virtual bool isSleeping() = 0;
|
||||
virtual void setType(ERigidBodyType v) = 0;
|
||||
virtual void setMass(float v) = 0;
|
||||
virtual void setLinearDamping(float v) = 0;
|
||||
virtual void setAngularDamping(float v) = 0;
|
||||
virtual void useGravity(bool v) = 0;
|
||||
virtual void useCCD(bool v) = 0;
|
||||
virtual void setLinearFactor(float x, float y, float z) = 0;
|
||||
virtual void setAngularFactor(float x, float y, float z) = 0;
|
||||
virtual void setAllowSleep(bool v) = 0;
|
||||
virtual void wakeUp() = 0;
|
||||
virtual void sleep() = 0;
|
||||
virtual void clearState() = 0;
|
||||
virtual void clearForces() = 0;
|
||||
virtual void clearVelocity() = 0;
|
||||
virtual void setSleepThreshold(float v) = 0;
|
||||
virtual float getSleepThreshold() = 0;
|
||||
virtual cc::Vec3 getLinearVelocity() = 0;
|
||||
virtual void setLinearVelocity(float x, float y, float z) = 0;
|
||||
virtual cc::Vec3 getAngularVelocity() = 0;
|
||||
virtual void setAngularVelocity(float x, float y, float z) = 0;
|
||||
virtual void applyForce(float x, float y, float z, float rx, float ry, float rz) = 0;
|
||||
virtual void applyLocalForce(float x, float y, float z, float rx, float ry, float rz) = 0;
|
||||
virtual void applyImpulse(float x, float y, float z, float rx, float ry, float rz) = 0;
|
||||
virtual void applyLocalImpulse(float x, float y, float z, float rx, float ry, float rz) = 0;
|
||||
virtual void applyTorque(float x, float y, float z) = 0;
|
||||
virtual void applyLocalTorque(float x, float y, float z) = 0;
|
||||
virtual uint32_t getGroup() = 0;
|
||||
virtual void setGroup(uint32_t g) = 0;
|
||||
virtual uint32_t getMask() = 0;
|
||||
virtual void setMask(uint32_t m) = 0;
|
||||
virtual uint32_t getObjectID() const = 0;
|
||||
};
|
||||
|
||||
} // namespace physics
|
||||
} // namespace cc
|
||||
81
cocos/physics/spec/ICharacterController.h
Normal file
81
cocos/physics/spec/ICharacterController.h
Normal file
@@ -0,0 +1,81 @@
|
||||
/****************************************************************************
|
||||
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 "core/scene-graph/Node.h"
|
||||
#include "math/Vec3.h"
|
||||
#include "physics/spec/ILifecycle.h"
|
||||
#include "physics/spec/IShape.h"
|
||||
|
||||
namespace cc {
|
||||
namespace physics {
|
||||
|
||||
class IBaseCharacterController : virtual public ILifecycle {
|
||||
public:
|
||||
~IBaseCharacterController() override = default;
|
||||
virtual bool initialize(Node *node) = 0;
|
||||
|
||||
virtual void setStepOffset(float v) = 0;
|
||||
virtual float getStepOffset() = 0;
|
||||
virtual void setSlopeLimit(float v) = 0;
|
||||
virtual float getSlopeLimit() = 0;
|
||||
virtual void setContactOffset(float v) = 0;
|
||||
virtual float getContactOffset() = 0;
|
||||
virtual void setDetectCollisions(bool v) = 0;
|
||||
virtual void setOverlapRecovery(bool v) = 0;
|
||||
virtual void setCenter(float x, float y, float z) = 0;
|
||||
|
||||
virtual cc::Vec3 getPosition() = 0;
|
||||
virtual void setPosition(float x, float y, float z) = 0;
|
||||
virtual bool onGround() = 0;
|
||||
virtual void move(float x, float y, float z, float minDist, float elapsedTime) = 0;
|
||||
virtual void syncPhysicsToScene() = 0;
|
||||
|
||||
virtual uint32_t getGroup() = 0;
|
||||
virtual void setGroup(uint32_t g) = 0;
|
||||
virtual uint32_t getMask() = 0;
|
||||
virtual void setMask(uint32_t m) = 0;
|
||||
virtual void updateEventListener(EShapeFilterFlag flag) = 0;
|
||||
|
||||
virtual uint32_t getObjectID() const = 0;
|
||||
};
|
||||
|
||||
class ICapsuleCharacterController : virtual public IBaseCharacterController {
|
||||
public:
|
||||
~ICapsuleCharacterController() override = default;
|
||||
virtual void setRadius(float v) = 0;
|
||||
virtual void setHeight(float v) = 0;
|
||||
};
|
||||
|
||||
class IBoxCharacterController : virtual public IBaseCharacterController {
|
||||
public:
|
||||
~IBoxCharacterController() override = default;
|
||||
virtual void setHalfHeight(float v) = 0;
|
||||
virtual void setHalfSideExtent(float v) = 0;
|
||||
virtual void setHalfForwardExtent(float v) = 0;
|
||||
};
|
||||
|
||||
} // namespace physics
|
||||
} // namespace cc
|
||||
113
cocos/physics/spec/IJoint.h
Normal file
113
cocos/physics/spec/IJoint.h
Normal file
@@ -0,0 +1,113 @@
|
||||
/****************************************************************************
|
||||
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 <cstdint>
|
||||
#include "core/scene-graph/Node.h"
|
||||
#include "physics/spec/ILifecycle.h"
|
||||
|
||||
namespace cc {
|
||||
namespace physics {
|
||||
|
||||
class IBaseJoint : virtual public ILifecycle {
|
||||
public:
|
||||
~IBaseJoint() override = default;
|
||||
virtual void initialize(Node *node) = 0;
|
||||
virtual void setEnableCollision(bool v) = 0;
|
||||
virtual void setConnectedBody(uint32_t rigidBodyID) = 0;
|
||||
virtual uint32_t getObjectID() const = 0;
|
||||
};
|
||||
|
||||
class ISphericalJoint : virtual public IBaseJoint {
|
||||
public:
|
||||
~ISphericalJoint() override = default;
|
||||
virtual void setPivotA(float x, float y, float z) = 0;
|
||||
virtual void setPivotB(float x, float y, float z) = 0;
|
||||
};
|
||||
|
||||
class IRevoluteJoint : virtual public IBaseJoint {
|
||||
public:
|
||||
~IRevoluteJoint() override = default;
|
||||
virtual void setPivotA(float x, float y, float z) = 0;
|
||||
virtual void setPivotB(float x, float y, float z) = 0;
|
||||
virtual void setAxis(float x, float y, float z) = 0;
|
||||
virtual void setLimitEnabled(bool v) = 0;
|
||||
virtual void setLowerLimit(float v) = 0;
|
||||
virtual void setUpperLimit(float v) = 0;
|
||||
virtual void setMotorEnabled(bool v) = 0;
|
||||
virtual void setMotorVelocity(float v) = 0;
|
||||
virtual void setMotorForceLimit(float v) = 0;
|
||||
};
|
||||
|
||||
class IFixedJoint : virtual public IBaseJoint {
|
||||
public:
|
||||
~IFixedJoint() override = default;
|
||||
virtual void setBreakForce(float force) = 0;
|
||||
virtual void setBreakTorque(float torque) = 0;
|
||||
};
|
||||
|
||||
class IGenericJoint : virtual public IBaseJoint {
|
||||
public:
|
||||
~IGenericJoint() override = default;
|
||||
|
||||
virtual void setConstraintMode(uint32_t index, uint32_t mode) = 0;
|
||||
virtual void setLinearLimit(uint32_t index, float lower, float upper) = 0;
|
||||
virtual void setAngularExtent(float twist, float swing1, float swing2) = 0;
|
||||
virtual void setLinearSoftConstraint(bool enable) = 0;
|
||||
virtual void setLinearStiffness(float stiffness) = 0;
|
||||
virtual void setLinearDamping(float damping) = 0;
|
||||
virtual void setLinearRestitution(float restitution) = 0;
|
||||
|
||||
virtual void setSwingSoftConstraint(bool enable) = 0;
|
||||
virtual void setTwistSoftConstraint(bool enable) = 0;
|
||||
virtual void setSwingStiffness(float stiffness) = 0;
|
||||
virtual void setSwingDamping(float damping) = 0;
|
||||
virtual void setSwingRestitution(float restitution) = 0;
|
||||
virtual void setTwistStiffness(float stiffness) = 0;
|
||||
virtual void setTwistDamping(float damping) = 0;
|
||||
virtual void setTwistRestitution(float restitution) = 0;
|
||||
|
||||
// motor
|
||||
virtual void setDriverMode(uint32_t index, uint32_t mode) = 0;
|
||||
virtual void setLinearMotorTarget(float x, float y, float z) = 0;
|
||||
virtual void setLinearMotorVelocity(float x, float y, float z) = 0;
|
||||
virtual void setLinearMotorForceLimit(float limit) = 0;
|
||||
|
||||
virtual void setAngularMotorTarget(float x, float y, float z) = 0;
|
||||
virtual void setAngularMotorVelocity(float x, float y, float z) = 0;
|
||||
virtual void setAngularMotorForceLimit(float limit) = 0;
|
||||
|
||||
virtual void setPivotA(float x, float y, float z) = 0;
|
||||
virtual void setPivotB(float x, float y, float z) = 0;
|
||||
virtual void setAutoPivotB(bool enable) = 0;
|
||||
virtual void setAxis(float x, float y, float z) = 0;
|
||||
virtual void setSecondaryAxis(float x, float y, float z) = 0;
|
||||
|
||||
virtual void setBreakForce(float force) = 0;
|
||||
virtual void setBreakTorque(float torque) = 0;
|
||||
};
|
||||
|
||||
} // namespace physics
|
||||
} // namespace cc
|
||||
40
cocos/physics/spec/ILifecycle.h
Normal file
40
cocos/physics/spec/ILifecycle.h
Normal file
@@ -0,0 +1,40 @@
|
||||
/****************************************************************************
|
||||
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 <cstdint>
|
||||
#include "base/TypeDef.h"
|
||||
|
||||
namespace cc {
|
||||
namespace physics {
|
||||
class ILifecycle {
|
||||
public:
|
||||
virtual ~ILifecycle() = default;
|
||||
virtual void onEnable() = 0;
|
||||
virtual void onDisable() = 0;
|
||||
virtual void onDestroy() = 0;
|
||||
};
|
||||
} // namespace physics
|
||||
} // namespace cc
|
||||
130
cocos/physics/spec/IShape.h
Normal file
130
cocos/physics/spec/IShape.h
Normal file
@@ -0,0 +1,130 @@
|
||||
/****************************************************************************
|
||||
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 <cstdint>
|
||||
#include "core/geometry/AABB.h"
|
||||
#include "core/geometry/Sphere.h"
|
||||
#include "core/scene-graph/Node.h"
|
||||
#include "physics/spec/ILifecycle.h"
|
||||
|
||||
namespace cc {
|
||||
namespace physics {
|
||||
|
||||
enum class EAxisDirection : uint8_t {
|
||||
X_AXIS,
|
||||
Y_AXIS,
|
||||
Z_AXIS,
|
||||
};
|
||||
|
||||
enum class EShapeFilterFlag : uint8_t {
|
||||
NONE = 0,
|
||||
IS_TRIGGER = 1 << 0,
|
||||
NEED_EVENT = 1 << 1,
|
||||
NEED_CONTACT_DATA = 1 << 2,
|
||||
DETECT_CONTACT_CCD = 1 << 3,
|
||||
};
|
||||
|
||||
class IBaseShape : virtual public ILifecycle {
|
||||
public:
|
||||
~IBaseShape() override = default;
|
||||
;
|
||||
virtual void initialize(Node *node) = 0;
|
||||
virtual void setMaterial(uint16_t id, float f, float df, float r,
|
||||
uint8_t m0, uint8_t m1) = 0;
|
||||
virtual void setAsTrigger(bool v) = 0;
|
||||
virtual void setCenter(float x, float y, float z) = 0;
|
||||
virtual geometry::AABB &getAABB() = 0;
|
||||
virtual geometry::Sphere &getBoundingSphere() = 0;
|
||||
virtual void updateEventListener(EShapeFilterFlag flag) = 0;
|
||||
virtual uint32_t getGroup() = 0;
|
||||
virtual void setGroup(uint32_t g) = 0;
|
||||
virtual uint32_t getMask() = 0;
|
||||
virtual void setMask(uint32_t m) = 0;
|
||||
virtual uint32_t getObjectID() const = 0;
|
||||
};
|
||||
|
||||
class ISphereShape : virtual public IBaseShape {
|
||||
public:
|
||||
~ISphereShape() override = default;
|
||||
;
|
||||
virtual void setRadius(float v) = 0;
|
||||
};
|
||||
|
||||
class IBoxShape : virtual public IBaseShape {
|
||||
public:
|
||||
~IBoxShape() override = default;
|
||||
;
|
||||
virtual void setSize(float x, float y, float z) = 0;
|
||||
};
|
||||
|
||||
class ICapsuleShape : virtual public IBaseShape {
|
||||
public:
|
||||
~ICapsuleShape() override = default;
|
||||
;
|
||||
virtual void setRadius(float v) = 0;
|
||||
virtual void setCylinderHeight(float v) = 0;
|
||||
virtual void setDirection(EAxisDirection v) = 0;
|
||||
};
|
||||
|
||||
class ICylinderShape : virtual public IBaseShape {
|
||||
public:
|
||||
~ICylinderShape() override = default;
|
||||
;
|
||||
virtual void setConvex(uint32_t ObjectID) = 0;
|
||||
virtual void setCylinder(float r, float h, EAxisDirection d) = 0;
|
||||
};
|
||||
|
||||
class IConeShape : virtual public IBaseShape {
|
||||
public:
|
||||
~IConeShape() override = default;
|
||||
;
|
||||
virtual void setConvex(uint32_t ObjectID) = 0;
|
||||
virtual void setCone(float r, float h, EAxisDirection d) = 0;
|
||||
};
|
||||
|
||||
class IPlaneShape : virtual public IBaseShape {
|
||||
public:
|
||||
~IPlaneShape() override = default;
|
||||
;
|
||||
virtual void setConstant(float v) = 0;
|
||||
virtual void setNormal(float x, float y, float z) = 0;
|
||||
};
|
||||
|
||||
class ITrimeshShape : virtual public IBaseShape {
|
||||
public:
|
||||
~ITrimeshShape() override = default;
|
||||
;
|
||||
virtual void setMesh(uint32_t ObjectID) = 0;
|
||||
virtual void useConvex(bool v) = 0;
|
||||
};
|
||||
|
||||
class ITerrainShape : virtual public IBaseShape {
|
||||
public:
|
||||
virtual void setTerrain(uint32_t ObjectID, float rs, float cs, float hs) = 0;
|
||||
};
|
||||
|
||||
} // namespace physics
|
||||
} // namespace cc
|
||||
190
cocos/physics/spec/IWorld.h
Normal file
190
cocos/physics/spec/IWorld.h
Normal file
@@ -0,0 +1,190 @@
|
||||
/****************************************************************************
|
||||
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 <cstdint>
|
||||
#include <memory>
|
||||
#include "base/TypeDef.h"
|
||||
#include "base/std/container/vector.h"
|
||||
#include "math/Vec3.h"
|
||||
|
||||
namespace cc {
|
||||
namespace physics {
|
||||
|
||||
enum class ETouchState : uint8_t {
|
||||
ENTER = 0,
|
||||
STAY = 1,
|
||||
EXIT = 2,
|
||||
};
|
||||
|
||||
enum class EPhysicsDrawFlags : uint32_t {
|
||||
NONE = 0,
|
||||
WIRE_FRAME = 0x0001,
|
||||
CONSTRAINT = 0x0002,
|
||||
AABB = 0x0004
|
||||
};
|
||||
|
||||
struct TriggerEventPair {
|
||||
uint32_t shapeA; //wrapper object ID
|
||||
uint32_t shapeB; //wrapper object ID
|
||||
ETouchState state;
|
||||
static constexpr uint8_t COUNT = 3;
|
||||
TriggerEventPair(const uint32_t a, const uint32_t b)
|
||||
: shapeA(a),
|
||||
shapeB(b),
|
||||
state(ETouchState::ENTER) {}
|
||||
};
|
||||
|
||||
struct ContactPoint {
|
||||
Vec3 position;
|
||||
float separation;
|
||||
Vec3 normal;
|
||||
uint32_t internalFaceIndex0;
|
||||
Vec3 impulse;
|
||||
uint32_t internalFaceIndex1;
|
||||
static constexpr uint8_t COUNT = 12;
|
||||
};
|
||||
|
||||
struct ContactEventPair {
|
||||
uint32_t shapeA; //wrapper object ID
|
||||
uint32_t shapeB; //wrapper object ID
|
||||
ETouchState state;
|
||||
ccstd::vector<ContactPoint> contacts;
|
||||
static constexpr uint8_t COUNT = 4;
|
||||
ContactEventPair(const uint32_t a, const uint32_t b)
|
||||
: shapeA(a),
|
||||
shapeB(b),
|
||||
state(ETouchState::ENTER) {}
|
||||
};
|
||||
|
||||
struct CharacterControllerContact {
|
||||
Vec3 worldPosition;
|
||||
Vec3 worldNormal;
|
||||
Vec3 motionDirection;
|
||||
float motionLength;
|
||||
static constexpr uint8_t COUNT = 10;
|
||||
};
|
||||
struct CCTShapeEventPair {
|
||||
uint32_t cct; //wrapper object ID
|
||||
uint32_t shape; //wrapper object ID
|
||||
//ETouchState state;
|
||||
ccstd::vector<CharacterControllerContact> contacts;
|
||||
static constexpr uint8_t COUNT = 3;
|
||||
CCTShapeEventPair(const uint32_t cct, const uint32_t shape)
|
||||
: cct(cct), shape(shape) {
|
||||
}
|
||||
};
|
||||
|
||||
struct CCTTriggerEventPair {
|
||||
uint32_t cct; //wrapper object ID
|
||||
uint32_t shape; //wrapper object ID
|
||||
ETouchState state;
|
||||
static constexpr uint8_t COUNT = 3;
|
||||
CCTTriggerEventPair(const uint32_t cct, const uint32_t shape)
|
||||
: cct(cct),
|
||||
shape(shape),
|
||||
state(ETouchState::ENTER) {}
|
||||
};
|
||||
|
||||
struct ConvexDesc {
|
||||
void *positions;
|
||||
uint32_t positionLength;
|
||||
};
|
||||
|
||||
struct TrimeshDesc : ConvexDesc {
|
||||
void *triangles;
|
||||
uint32_t triangleLength;
|
||||
bool isU16;
|
||||
};
|
||||
|
||||
struct HeightFieldDesc {
|
||||
uint32_t rows;
|
||||
uint32_t columns;
|
||||
void *samples;
|
||||
};
|
||||
|
||||
struct RaycastOptions {
|
||||
Vec3 origin;
|
||||
float distance;
|
||||
Vec3 unitDir;
|
||||
uint32_t mask;
|
||||
bool queryTrigger;
|
||||
};
|
||||
|
||||
struct RaycastResult {
|
||||
uint32_t shape{0};
|
||||
Vec3 hitPoint;
|
||||
float distance;
|
||||
Vec3 hitNormal;
|
||||
RaycastResult() = default;
|
||||
};
|
||||
|
||||
class IPhysicsWorld {
|
||||
public:
|
||||
virtual ~IPhysicsWorld() = default;
|
||||
;
|
||||
virtual void setGravity(float x, float y, float z) = 0;
|
||||
virtual void setAllowSleep(bool v) = 0;
|
||||
virtual void step(float s) = 0;
|
||||
virtual void emitEvents() = 0;
|
||||
virtual void syncSceneToPhysics() = 0;
|
||||
virtual void syncSceneWithCheck() = 0;
|
||||
virtual void destroy() = 0;
|
||||
virtual void setDebugDrawFlags(EPhysicsDrawFlags f) = 0;
|
||||
virtual EPhysicsDrawFlags getDebugDrawFlags() = 0;
|
||||
virtual void setDebugDrawConstraintSize(float s) = 0;
|
||||
virtual float getDebugDrawConstraintSize() = 0;
|
||||
virtual void setCollisionMatrix(uint32_t i, uint32_t m) = 0;
|
||||
virtual ccstd::vector<std::shared_ptr<TriggerEventPair>> &getTriggerEventPairs() = 0;
|
||||
virtual ccstd::vector<std::shared_ptr<ContactEventPair>>& getContactEventPairs() = 0;
|
||||
virtual ccstd::vector<std::shared_ptr<CCTShapeEventPair>>& getCCTShapeEventPairs() = 0;
|
||||
virtual ccstd::vector<std::shared_ptr<CCTTriggerEventPair>> &getCCTTriggerEventPairs() = 0;
|
||||
virtual bool raycast(RaycastOptions &opt) = 0;
|
||||
virtual bool raycastClosest(RaycastOptions &opt) = 0;
|
||||
virtual ccstd::vector<RaycastResult> &raycastResult() = 0;
|
||||
virtual RaycastResult &raycastClosestResult() = 0;
|
||||
virtual bool sweepBox(RaycastOptions &opt, float halfExtentX, float halfExtentY, float halfExtentZ,
|
||||
float orientationW, float orientationX, float orientationY, float orientationZ) = 0;
|
||||
virtual bool sweepBoxClosest(RaycastOptions &opt, float halfExtentX, float halfExtentY, float halfExtentZ,
|
||||
float orientationW, float orientationX, float orientationY, float orientationZ) = 0;
|
||||
virtual bool sweepSphere(RaycastOptions &opt, float radius) = 0;
|
||||
virtual bool sweepSphereClosest(RaycastOptions &opt, float radius) = 0;
|
||||
virtual bool sweepCapsule(RaycastOptions &opt, float radius, float height,
|
||||
float orientationW, float orientationX, float orientationY, float orientationZ) = 0;
|
||||
virtual bool sweepCapsuleClosest(RaycastOptions &opt, float radius, float height,
|
||||
float orientationW, float orientationX, float orientationY, float orientationZ) = 0;
|
||||
virtual RaycastResult &sweepClosestResult() = 0;
|
||||
virtual ccstd::vector<RaycastResult> &sweepResult() = 0;
|
||||
virtual uint32_t createConvex(ConvexDesc &desc) = 0;
|
||||
virtual uint32_t createTrimesh(TrimeshDesc &desc) = 0;
|
||||
virtual uint32_t createHeightField(HeightFieldDesc &desc) = 0;
|
||||
virtual bool createMaterial(uint16_t id, float f, float df, float r,
|
||||
uint8_t m0, uint8_t m1) = 0;
|
||||
virtual void setFixedTimeStep(float v) = 0;
|
||||
virtual float getFixedTimeStep() const = 0;
|
||||
};
|
||||
|
||||
} // namespace physics
|
||||
} // namespace cc
|
||||
Reference in New Issue
Block a user