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
9using namespace physx;
10
11namespace 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}