2019-11-23 20:27:39 +08:00
|
|
|
/****************************************************************************
|
|
|
|
Copyright (c) 2015-2016 Chukong Technologies Inc.
|
|
|
|
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2022-10-01 16:24:52 +08:00
|
|
|
https://axmolengine.github.io/
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2019-11-23 20:27:39 +08:00
|
|
|
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:
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2019-11-23 20:27:39 +08:00
|
|
|
The above copyright notice and this permission notice shall be included in
|
|
|
|
all copies or substantial portions of the Software.
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2019-11-23 20:27:39 +08:00
|
|
|
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.
|
|
|
|
****************************************************************************/
|
|
|
|
|
2023-06-11 13:08:08 +08:00
|
|
|
#include "physics3d/Physics3D.h"
|
2019-11-23 20:27:39 +08:00
|
|
|
|
2022-07-16 10:43:05 +08:00
|
|
|
#if AX_USE_3D_PHYSICS
|
2019-11-23 20:27:39 +08:00
|
|
|
|
2022-07-16 10:43:05 +08:00
|
|
|
# if (AX_ENABLE_BULLET_INTEGRATION)
|
2021-12-25 10:04:45 +08:00
|
|
|
# include "bullet/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h"
|
2019-11-23 20:27:39 +08:00
|
|
|
|
2022-07-11 17:50:21 +08:00
|
|
|
NS_AX_BEGIN
|
2019-11-23 20:27:39 +08:00
|
|
|
|
|
|
|
Physics3DShape::ShapeType Physics3DShape::getShapeType() const
|
|
|
|
{
|
|
|
|
return _shapeType;
|
|
|
|
}
|
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
Physics3DShape::Physics3DShape() : _shapeType(ShapeType::UNKNOWN)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
2022-07-16 10:43:05 +08:00
|
|
|
# if (AX_ENABLE_BULLET_INTEGRATION)
|
2021-12-25 10:04:45 +08:00
|
|
|
_btShape = nullptr;
|
2019-11-23 20:27:39 +08:00
|
|
|
_heightfieldData = nullptr;
|
2021-12-25 10:04:45 +08:00
|
|
|
# endif
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
|
|
|
Physics3DShape::~Physics3DShape()
|
|
|
|
{
|
2022-07-16 10:43:05 +08:00
|
|
|
# if (AX_ENABLE_BULLET_INTEGRATION)
|
|
|
|
AX_SAFE_DELETE(_btShape);
|
|
|
|
AX_SAFE_DELETE_ARRAY(_heightfieldData);
|
2022-07-21 19:19:08 +08:00
|
|
|
for (auto&& iter : _compoundChildShapes)
|
2021-12-25 10:04:45 +08:00
|
|
|
{
|
2022-07-16 10:43:05 +08:00
|
|
|
AX_SAFE_RELEASE(iter);
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
|
|
|
_compoundChildShapes.clear();
|
2021-12-25 10:04:45 +08:00
|
|
|
# endif
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
|
|
|
|
2022-08-08 18:02:17 +08:00
|
|
|
Physics3DShape* Physics3DShape::createBox(const ax::Vec3& extent)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
2021-12-08 00:11:53 +08:00
|
|
|
auto shape = new Physics3DShape();
|
2019-11-23 20:27:39 +08:00
|
|
|
shape->initBox(extent);
|
|
|
|
shape->autorelease();
|
|
|
|
return shape;
|
|
|
|
}
|
|
|
|
|
|
|
|
Physics3DShape* Physics3DShape::createSphere(float radius)
|
|
|
|
{
|
2021-12-08 00:11:53 +08:00
|
|
|
auto shape = new Physics3DShape();
|
2019-11-23 20:27:39 +08:00
|
|
|
shape->initSphere(radius);
|
|
|
|
shape->autorelease();
|
|
|
|
return shape;
|
|
|
|
}
|
|
|
|
|
|
|
|
Physics3DShape* Physics3DShape::createCylinder(float radius, float height)
|
|
|
|
{
|
2021-12-08 00:11:53 +08:00
|
|
|
auto shape = new Physics3DShape();
|
2019-11-23 20:27:39 +08:00
|
|
|
shape->initCylinder(radius, height);
|
|
|
|
shape->autorelease();
|
|
|
|
return shape;
|
|
|
|
}
|
|
|
|
|
|
|
|
Physics3DShape* Physics3DShape::createCapsule(float radius, float height)
|
|
|
|
{
|
2021-12-08 00:11:53 +08:00
|
|
|
auto shape = new Physics3DShape();
|
2019-11-23 20:27:39 +08:00
|
|
|
shape->initCapsule(radius, height);
|
|
|
|
shape->autorelease();
|
|
|
|
return shape;
|
|
|
|
}
|
|
|
|
|
2022-08-08 18:02:17 +08:00
|
|
|
Physics3DShape* Physics3DShape::createConvexHull(const ax::Vec3* points, int numPoints)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
2021-12-08 00:11:53 +08:00
|
|
|
auto shape = new Physics3DShape();
|
2019-11-23 20:27:39 +08:00
|
|
|
shape->initConvexHull(points, numPoints);
|
|
|
|
shape->autorelease();
|
|
|
|
return shape;
|
|
|
|
}
|
|
|
|
|
2022-08-08 18:02:17 +08:00
|
|
|
Physics3DShape* Physics3DShape::createMesh(const ax::Vec3* triangles, int numTriangles)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
2021-12-08 00:11:53 +08:00
|
|
|
auto shape = new Physics3DShape();
|
2019-11-23 20:27:39 +08:00
|
|
|
shape->initMesh(triangles, numTriangles);
|
|
|
|
shape->autorelease();
|
|
|
|
return shape;
|
|
|
|
}
|
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
Physics3DShape* Physics3DShape::createHeightfield(int heightStickWidth,
|
|
|
|
int heightStickLength,
|
|
|
|
const void* heightfieldData,
|
|
|
|
float heightScale,
|
|
|
|
float minHeight,
|
|
|
|
float maxHeight,
|
|
|
|
bool useFloatDatam,
|
|
|
|
bool flipQuadEdges,
|
|
|
|
bool useDiamondSubdivision)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
2021-12-08 00:11:53 +08:00
|
|
|
auto shape = new Physics3DShape();
|
2021-12-25 10:04:45 +08:00
|
|
|
shape->initHeightfield(heightStickWidth, heightStickLength, heightfieldData, heightScale, minHeight, maxHeight,
|
|
|
|
useFloatDatam, flipQuadEdges, useDiamondSubdivision);
|
2019-11-23 20:27:39 +08:00
|
|
|
shape->autorelease();
|
2021-12-25 10:04:45 +08:00
|
|
|
return shape;
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
Physics3DShape* Physics3DShape::createCompoundShape(const std::vector<std::pair<Physics3DShape*, Mat4>>& shapes)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
2021-12-08 00:11:53 +08:00
|
|
|
auto shape = new Physics3DShape();
|
2019-11-23 20:27:39 +08:00
|
|
|
shape->initCompoundShape(shapes);
|
|
|
|
shape->autorelease();
|
|
|
|
return shape;
|
|
|
|
}
|
|
|
|
|
2022-08-08 18:02:17 +08:00
|
|
|
bool Physics3DShape::initBox(const ax::Vec3& ext)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
|
|
|
_shapeType = ShapeType::BOX;
|
2021-12-25 10:04:45 +08:00
|
|
|
_btShape = new btBoxShape(convertVec3TobtVector3(ext * 0.5f));
|
2019-11-23 20:27:39 +08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
bool Physics3DShape::initSphere(float radius)
|
|
|
|
{
|
|
|
|
_shapeType = ShapeType::SPHERE;
|
2021-12-25 10:04:45 +08:00
|
|
|
_btShape = new btSphereShape(radius);
|
2019-11-23 20:27:39 +08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
bool Physics3DShape::initCylinder(float radius, float height)
|
|
|
|
{
|
|
|
|
_shapeType = ShapeType::CYLINDER;
|
2022-08-08 18:02:17 +08:00
|
|
|
_btShape = new btCylinderShape(convertVec3TobtVector3(ax::Vec3(radius, height, radius) * 0.5f));
|
2019-11-23 20:27:39 +08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
bool Physics3DShape::initCapsule(float radius, float height)
|
|
|
|
{
|
|
|
|
_shapeType = ShapeType::CAPSULE;
|
2021-12-25 10:04:45 +08:00
|
|
|
_btShape = new btCapsuleShape(radius, height);
|
2019-11-23 20:27:39 +08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2022-08-08 18:02:17 +08:00
|
|
|
bool Physics3DShape::initConvexHull(const ax::Vec3* points, int numPoints)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
|
|
|
_shapeType = ShapeType::CONVEX;
|
2022-08-08 18:02:17 +08:00
|
|
|
_btShape = new btConvexHullShape((btScalar*)points, numPoints, sizeof(ax::Vec3));
|
2019-11-23 20:27:39 +08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2022-08-08 18:02:17 +08:00
|
|
|
bool Physics3DShape::initMesh(const ax::Vec3* triangles, int numTriangles)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
|
|
|
_shapeType = ShapeType::MESH;
|
2021-12-25 10:04:45 +08:00
|
|
|
auto mesh = new btTriangleMesh(false);
|
|
|
|
for (int i = 0; i < numTriangles * 3; i += 3)
|
|
|
|
{
|
|
|
|
mesh->addTriangle(convertVec3TobtVector3(triangles[i]), convertVec3TobtVector3(triangles[i + 1]),
|
|
|
|
convertVec3TobtVector3(triangles[i + 2]));
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
|
|
|
_btShape = new btBvhTriangleMeshShape(mesh, true);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
bool Physics3DShape::initHeightfield(int heightStickWidth,
|
|
|
|
int heightStickLength,
|
|
|
|
const void* heightfieldData,
|
|
|
|
float heightScale,
|
|
|
|
float minHeight,
|
|
|
|
float maxHeight,
|
|
|
|
bool useFloatDatam,
|
|
|
|
bool flipQuadEdges,
|
|
|
|
bool useDiamondSubdivision)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
_shapeType = ShapeType::HEIGHT_FIELD;
|
|
|
|
PHY_ScalarType type = PHY_UCHAR;
|
2019-11-23 20:27:39 +08:00
|
|
|
unsigned int dataSizeInByte = heightStickWidth * heightStickLength;
|
2021-12-25 10:04:45 +08:00
|
|
|
if (useFloatDatam)
|
|
|
|
{
|
2019-11-23 20:27:39 +08:00
|
|
|
type = PHY_FLOAT;
|
|
|
|
dataSizeInByte *= sizeof(float);
|
|
|
|
}
|
|
|
|
_heightfieldData = new unsigned char[dataSizeInByte];
|
|
|
|
memcpy(_heightfieldData, heightfieldData, dataSizeInByte);
|
2021-12-25 10:04:45 +08:00
|
|
|
auto heightfield = new btHeightfieldTerrainShape(heightStickWidth, heightStickLength, _heightfieldData, heightScale,
|
|
|
|
minHeight, maxHeight, 1, type, flipQuadEdges);
|
2019-11-23 20:27:39 +08:00
|
|
|
heightfield->setUseDiamondSubdivision(useDiamondSubdivision);
|
|
|
|
_btShape = heightfield;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
bool Physics3DShape::initCompoundShape(const std::vector<std::pair<Physics3DShape*, Mat4>>& shapes)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
_shapeType = ShapeType::COMPOUND;
|
2019-11-23 20:27:39 +08:00
|
|
|
auto compound = new btCompoundShape;
|
2022-07-21 19:19:08 +08:00
|
|
|
for (auto&& iter : shapes)
|
2021-12-25 10:04:45 +08:00
|
|
|
{
|
2019-11-23 20:27:39 +08:00
|
|
|
compound->addChildShape(convertMat4TobtTransform(iter.second), iter.first->getbtShape());
|
2022-07-16 10:43:05 +08:00
|
|
|
AX_SAFE_RETAIN(iter.first);
|
2022-08-08 13:18:33 +08:00
|
|
|
_compoundChildShapes.emplace_back(iter.first);
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
|
|
|
_btShape = compound;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2022-07-11 17:50:21 +08:00
|
|
|
NS_AX_END
|
2019-11-23 20:27:39 +08:00
|
|
|
|
2022-07-16 10:43:05 +08:00
|
|
|
# endif // AX_ENABLE_BULLET_INTEGRATION
|
2019-11-23 20:27:39 +08:00
|
|
|
|
2022-07-16 10:43:05 +08:00
|
|
|
#endif // AX_USE_3D_PHYSICS
|