no message
This commit is contained in:
@@ -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
|
||||
Reference in New Issue
Block a user