1 | //************************************ bs::framework - Copyright 2018 Marko Pintera **************************************// |
2 | //*********** Licensed under the MIT license. See LICENSE.md for full terms. This notice is not to be removed. ***********// |
3 | #include "BsPhysXMeshCollider.h" |
4 | #include "BsPhysX.h" |
5 | #include "PxPhysics.h" |
6 | #include "BsFPhysXCollider.h" |
7 | #include "BsPhysXMesh.h" |
8 | |
9 | using namespace physx; |
10 | |
11 | namespace bs |
12 | { |
13 | PhysXMeshCollider::PhysXMeshCollider(PxPhysics* physx, PxScene* scene, const Vector3& position, |
14 | const Quaternion& rotation) |
15 | { |
16 | PxSphereGeometry geometry(0.01f); // Dummy |
17 | |
18 | PxShape* shape = physx->createShape(geometry, *gPhysX().getDefaultMaterial(), true); |
19 | shape->setLocalPose(toPxTransform(position, rotation)); |
20 | shape->userData = this; |
21 | |
22 | mInternal = bs_new<FPhysXCollider>(scene, shape); |
23 | } |
24 | |
25 | PhysXMeshCollider::~PhysXMeshCollider() |
26 | { |
27 | bs_delete(mInternal); |
28 | } |
29 | |
30 | void PhysXMeshCollider::setScale(const Vector3& scale) |
31 | { |
32 | MeshCollider::setScale(scale); |
33 | applyGeometry(); |
34 | } |
35 | |
36 | void PhysXMeshCollider::onMeshChanged() |
37 | { |
38 | applyGeometry(); |
39 | } |
40 | |
41 | void PhysXMeshCollider::applyGeometry() |
42 | { |
43 | if (!mMesh.isLoaded()) |
44 | { |
45 | setGeometry(PxSphereGeometry(0.01f)); // Dummy |
46 | return; |
47 | } |
48 | |
49 | FPhysXMesh* physxMesh = static_cast<FPhysXMesh*>(mMesh->_getInternal()); |
50 | |
51 | if (mMesh->getType() == PhysicsMeshType::Convex) |
52 | { |
53 | PxConvexMeshGeometry geometry; |
54 | geometry.scale = PxMeshScale(toPxVector(getScale()), PxIdentity); |
55 | geometry.convexMesh = physxMesh->_getConvex(); |
56 | |
57 | setGeometry(geometry); |
58 | } |
59 | else // Triangle |
60 | { |
61 | PxTriangleMeshGeometry geometry; |
62 | geometry.scale = PxMeshScale(toPxVector(getScale()), PxIdentity); |
63 | geometry.triangleMesh = physxMesh->_getTriangle(); |
64 | |
65 | setGeometry(geometry); |
66 | } |
67 | } |
68 | |
69 | void PhysXMeshCollider::setGeometry(const PxGeometry& geometry) |
70 | { |
71 | PxShape* shape = getInternal()->_getShape(); |
72 | if (shape->getGeometryType() != geometry.getType()) |
73 | { |
74 | PxShape* newShape = gPhysX().getPhysX()->createShape(geometry, *gPhysX().getDefaultMaterial(), true); |
75 | getInternal()->_setShape(newShape); |
76 | } |
77 | else |
78 | getInternal()->_getShape()->setGeometry(geometry); |
79 | } |
80 | |
81 | FPhysXCollider* PhysXMeshCollider::getInternal() const |
82 | { |
83 | return static_cast<FPhysXCollider*>(mInternal); |
84 | } |
85 | } |