diff options
Diffstat (limited to 'modules')
91 files changed, 1009 insertions, 11606 deletions
diff --git a/modules/bullet/SCsub b/modules/bullet/SCsub deleted file mode 100644 index 09509abc44..0000000000 --- a/modules/bullet/SCsub +++ /dev/null @@ -1,224 +0,0 @@ -#!/usr/bin/env python - -Import("env") -Import("env_modules") - -env_bullet = env_modules.Clone() - -# Thirdparty source files - -thirdparty_obj = [] - -if env["builtin_bullet"]: - # Build only "Bullet2" API (not "Bullet3" folders). - # Sync file list with relevant upstream CMakeLists.txt for each folder. - if env["float"] == "64": - env.Append(CPPDEFINES=["BT_USE_DOUBLE_PRECISION=1"]) - thirdparty_dir = "#thirdparty/bullet/" - - bullet2_src = [ - # BulletCollision - "BulletCollision/BroadphaseCollision/btAxisSweep3.cpp", - "BulletCollision/BroadphaseCollision/btBroadphaseProxy.cpp", - "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.cpp", - "BulletCollision/BroadphaseCollision/btDbvt.cpp", - "BulletCollision/BroadphaseCollision/btDbvtBroadphase.cpp", - "BulletCollision/BroadphaseCollision/btDispatcher.cpp", - "BulletCollision/BroadphaseCollision/btOverlappingPairCache.cpp", - "BulletCollision/BroadphaseCollision/btQuantizedBvh.cpp", - "BulletCollision/BroadphaseCollision/btSimpleBroadphase.cpp", - "BulletCollision/CollisionDispatch/btActivatingCollisionAlgorithm.cpp", - "BulletCollision/CollisionDispatch/btBoxBoxCollisionAlgorithm.cpp", - "BulletCollision/CollisionDispatch/btBox2dBox2dCollisionAlgorithm.cpp", - "BulletCollision/CollisionDispatch/btBoxBoxDetector.cpp", - "BulletCollision/CollisionDispatch/btCollisionDispatcher.cpp", - "BulletCollision/CollisionDispatch/btCollisionDispatcherMt.cpp", - "BulletCollision/CollisionDispatch/btCollisionObject.cpp", - "BulletCollision/CollisionDispatch/btCollisionWorld.cpp", - "BulletCollision/CollisionDispatch/btCollisionWorldImporter.cpp", - "BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.cpp", - "BulletCollision/CollisionDispatch/btCompoundCompoundCollisionAlgorithm.cpp", - "BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp", - "BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.cpp", - "BulletCollision/CollisionDispatch/btConvexPlaneCollisionAlgorithm.cpp", - "BulletCollision/CollisionDispatch/btConvex2dConvex2dAlgorithm.cpp", - "BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.cpp", - "BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.cpp", - "BulletCollision/CollisionDispatch/btGhostObject.cpp", - "BulletCollision/CollisionDispatch/btHashedSimplePairCache.cpp", - "BulletCollision/CollisionDispatch/btInternalEdgeUtility.cpp", - "BulletCollision/CollisionDispatch/btManifoldResult.cpp", - "BulletCollision/CollisionDispatch/btSimulationIslandManager.cpp", - "BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.cpp", - "BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.cpp", - "BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.cpp", - "BulletCollision/CollisionDispatch/btUnionFind.cpp", - "BulletCollision/CollisionDispatch/SphereTriangleDetector.cpp", - "BulletCollision/CollisionShapes/btBoxShape.cpp", - "BulletCollision/CollisionShapes/btBox2dShape.cpp", - "BulletCollision/CollisionShapes/btBvhTriangleMeshShape.cpp", - "BulletCollision/CollisionShapes/btCapsuleShape.cpp", - "BulletCollision/CollisionShapes/btCollisionShape.cpp", - "BulletCollision/CollisionShapes/btCompoundShape.cpp", - "BulletCollision/CollisionShapes/btConcaveShape.cpp", - "BulletCollision/CollisionShapes/btConeShape.cpp", - "BulletCollision/CollisionShapes/btConvexHullShape.cpp", - "BulletCollision/CollisionShapes/btConvexInternalShape.cpp", - "BulletCollision/CollisionShapes/btConvexPointCloudShape.cpp", - "BulletCollision/CollisionShapes/btConvexPolyhedron.cpp", - "BulletCollision/CollisionShapes/btConvexShape.cpp", - "BulletCollision/CollisionShapes/btConvex2dShape.cpp", - "BulletCollision/CollisionShapes/btConvexTriangleMeshShape.cpp", - "BulletCollision/CollisionShapes/btCylinderShape.cpp", - "BulletCollision/CollisionShapes/btEmptyShape.cpp", - "BulletCollision/CollisionShapes/btHeightfieldTerrainShape.cpp", - "BulletCollision/CollisionShapes/btMiniSDF.cpp", - "BulletCollision/CollisionShapes/btMinkowskiSumShape.cpp", - "BulletCollision/CollisionShapes/btMultimaterialTriangleMeshShape.cpp", - "BulletCollision/CollisionShapes/btMultiSphereShape.cpp", - "BulletCollision/CollisionShapes/btOptimizedBvh.cpp", - "BulletCollision/CollisionShapes/btPolyhedralConvexShape.cpp", - "BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.cpp", - "BulletCollision/CollisionShapes/btSdfCollisionShape.cpp", - "BulletCollision/CollisionShapes/btShapeHull.cpp", - "BulletCollision/CollisionShapes/btSphereShape.cpp", - "BulletCollision/CollisionShapes/btStaticPlaneShape.cpp", - "BulletCollision/CollisionShapes/btStridingMeshInterface.cpp", - "BulletCollision/CollisionShapes/btTetrahedronShape.cpp", - "BulletCollision/CollisionShapes/btTriangleBuffer.cpp", - "BulletCollision/CollisionShapes/btTriangleCallback.cpp", - "BulletCollision/CollisionShapes/btTriangleIndexVertexArray.cpp", - "BulletCollision/CollisionShapes/btTriangleIndexVertexMaterialArray.cpp", - "BulletCollision/CollisionShapes/btTriangleMesh.cpp", - "BulletCollision/CollisionShapes/btTriangleMeshShape.cpp", - "BulletCollision/CollisionShapes/btUniformScalingShape.cpp", - "BulletCollision/Gimpact/btContactProcessing.cpp", - "BulletCollision/Gimpact/btGenericPoolAllocator.cpp", - "BulletCollision/Gimpact/btGImpactBvh.cpp", - "BulletCollision/Gimpact/btGImpactCollisionAlgorithm.cpp", - "BulletCollision/Gimpact/btGImpactQuantizedBvh.cpp", - "BulletCollision/Gimpact/btGImpactShape.cpp", - "BulletCollision/Gimpact/btTriangleShapeEx.cpp", - "BulletCollision/Gimpact/gim_box_set.cpp", - "BulletCollision/Gimpact/gim_contact.cpp", - "BulletCollision/Gimpact/gim_memory.cpp", - "BulletCollision/Gimpact/gim_tri_collision.cpp", - "BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.cpp", - "BulletCollision/NarrowPhaseCollision/btConvexCast.cpp", - "BulletCollision/NarrowPhaseCollision/btGjkConvexCast.cpp", - "BulletCollision/NarrowPhaseCollision/btGjkEpa2.cpp", - "BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.cpp", - "BulletCollision/NarrowPhaseCollision/btGjkPairDetector.cpp", - "BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.cpp", - "BulletCollision/NarrowPhaseCollision/btPersistentManifold.cpp", - "BulletCollision/NarrowPhaseCollision/btRaycastCallback.cpp", - "BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.cpp", - "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.cpp", - "BulletCollision/NarrowPhaseCollision/btPolyhedralContactClipping.cpp", - # BulletDynamics - "BulletDynamics/Character/btKinematicCharacterController.cpp", - "BulletDynamics/ConstraintSolver/btConeTwistConstraint.cpp", - "BulletDynamics/ConstraintSolver/btContactConstraint.cpp", - "BulletDynamics/ConstraintSolver/btFixedConstraint.cpp", - "BulletDynamics/ConstraintSolver/btGearConstraint.cpp", - "BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.cpp", - "BulletDynamics/ConstraintSolver/btGeneric6DofSpringConstraint.cpp", - "BulletDynamics/ConstraintSolver/btGeneric6DofSpring2Constraint.cpp", - "BulletDynamics/ConstraintSolver/btHinge2Constraint.cpp", - "BulletDynamics/ConstraintSolver/btHingeConstraint.cpp", - "BulletDynamics/ConstraintSolver/btPoint2PointConstraint.cpp", - "BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp", - "BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolverMt.cpp", - "BulletDynamics/ConstraintSolver/btBatchedConstraints.cpp", - "BulletDynamics/ConstraintSolver/btNNCGConstraintSolver.cpp", - "BulletDynamics/ConstraintSolver/btSliderConstraint.cpp", - "BulletDynamics/ConstraintSolver/btSolve2LinearConstraint.cpp", - "BulletDynamics/ConstraintSolver/btTypedConstraint.cpp", - "BulletDynamics/ConstraintSolver/btUniversalConstraint.cpp", - "BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp", - "BulletDynamics/Dynamics/btDiscreteDynamicsWorldMt.cpp", - "BulletDynamics/Dynamics/btSimulationIslandManagerMt.cpp", - "BulletDynamics/Dynamics/btRigidBody.cpp", - "BulletDynamics/Dynamics/btSimpleDynamicsWorld.cpp", - # "BulletDynamics/Dynamics/Bullet-C-API.cpp", - "BulletDynamics/Vehicle/btRaycastVehicle.cpp", - "BulletDynamics/Vehicle/btWheelInfo.cpp", - "BulletDynamics/Featherstone/btMultiBody.cpp", - "BulletDynamics/Featherstone/btMultiBodyConstraint.cpp", - "BulletDynamics/Featherstone/btMultiBodyConstraintSolver.cpp", - "BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.cpp", - "BulletDynamics/Featherstone/btMultiBodyFixedConstraint.cpp", - "BulletDynamics/Featherstone/btMultiBodyGearConstraint.cpp", - "BulletDynamics/Featherstone/btMultiBodyJointLimitConstraint.cpp", - "BulletDynamics/Featherstone/btMultiBodyJointMotor.cpp", - "BulletDynamics/Featherstone/btMultiBodyMLCPConstraintSolver.cpp", - "BulletDynamics/Featherstone/btMultiBodyPoint2Point.cpp", - "BulletDynamics/Featherstone/btMultiBodySliderConstraint.cpp", - "BulletDynamics/Featherstone/btMultiBodySphericalJointMotor.cpp", - "BulletDynamics/MLCPSolvers/btDantzigLCP.cpp", - "BulletDynamics/MLCPSolvers/btMLCPSolver.cpp", - "BulletDynamics/MLCPSolvers/btLemkeAlgorithm.cpp", - # BulletInverseDynamics - "BulletInverseDynamics/IDMath.cpp", - "BulletInverseDynamics/MultiBodyTree.cpp", - "BulletInverseDynamics/details/MultiBodyTreeInitCache.cpp", - "BulletInverseDynamics/details/MultiBodyTreeImpl.cpp", - # BulletSoftBody - "BulletSoftBody/btSoftBody.cpp", - "BulletSoftBody/btSoftBodyConcaveCollisionAlgorithm.cpp", - "BulletSoftBody/btSoftBodyHelpers.cpp", - "BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.cpp", - "BulletSoftBody/btSoftRigidCollisionAlgorithm.cpp", - "BulletSoftBody/btSoftRigidDynamicsWorld.cpp", - "BulletSoftBody/btSoftMultiBodyDynamicsWorld.cpp", - "BulletSoftBody/btSoftSoftCollisionAlgorithm.cpp", - "BulletSoftBody/btDefaultSoftBodySolver.cpp", - "BulletSoftBody/btDeformableBackwardEulerObjective.cpp", - "BulletSoftBody/btDeformableBodySolver.cpp", - "BulletSoftBody/btDeformableMultiBodyConstraintSolver.cpp", - "BulletSoftBody/btDeformableContactProjection.cpp", - "BulletSoftBody/btDeformableMultiBodyDynamicsWorld.cpp", - "BulletSoftBody/btDeformableContactConstraint.cpp", - "BulletSoftBody/poly34.cpp", - # clew - "clew/clew.c", - # LinearMath - "LinearMath/btAlignedAllocator.cpp", - "LinearMath/btConvexHull.cpp", - "LinearMath/btConvexHullComputer.cpp", - "LinearMath/btGeometryUtil.cpp", - "LinearMath/btPolarDecomposition.cpp", - "LinearMath/btQuickprof.cpp", - "LinearMath/btReducedVector.cpp", - "LinearMath/btSerializer.cpp", - "LinearMath/btSerializer64.cpp", - "LinearMath/btThreads.cpp", - "LinearMath/btVector3.cpp", - "LinearMath/TaskScheduler/btTaskScheduler.cpp", - "LinearMath/TaskScheduler/btThreadSupportPosix.cpp", - "LinearMath/TaskScheduler/btThreadSupportWin32.cpp", - ] - - thirdparty_sources = [thirdparty_dir + file for file in bullet2_src] - - env_bullet.Prepend(CPPPATH=[thirdparty_dir]) - if env["target"] == "debug" or env["target"] == "release_debug": - env_bullet.Append(CPPDEFINES=["DEBUG"]) - - env_bullet.Append(CPPDEFINES=["BT_USE_OLD_DAMPING_METHOD", "BT_THREADSAFE"]) - - env_thirdparty = env_bullet.Clone() - env_thirdparty.disable_warnings() - env_thirdparty.add_source_files(thirdparty_obj, thirdparty_sources) - env.modules_sources += thirdparty_obj - - -# Godot source files - -module_obj = [] - -env_bullet.add_source_files(module_obj, "*.cpp") -env.modules_sources += module_obj - -# Needed to force rebuilding the module files when the thirdparty library is updated. -env.Depends(module_obj, thirdparty_obj) diff --git a/modules/bullet/area_bullet.cpp b/modules/bullet/area_bullet.cpp deleted file mode 100644 index f816691cde..0000000000 --- a/modules/bullet/area_bullet.cpp +++ /dev/null @@ -1,324 +0,0 @@ -/*************************************************************************/ -/* area_bullet.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* 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 "area_bullet.h" - -#include "bullet_physics_server.h" -#include "bullet_types_converter.h" -#include "bullet_utilities.h" -#include "collision_object_bullet.h" -#include "space_bullet.h" - -#include <BulletCollision/CollisionDispatch/btGhostObject.h> -#include <btBulletCollisionCommon.h> - -AreaBullet::AreaBullet() : - RigidCollisionObjectBullet(CollisionObjectBullet::TYPE_AREA) { - btGhost = bulletnew(btGhostObject); - reload_shapes(); - setupBulletCollisionObject(btGhost); - /// Collision objects with a callback still have collision response with dynamic rigid bodies. - /// In order to use collision objects as trigger, you have to disable the collision response. - set_collision_enabled(false); - - for (int i = 0; i < 5; ++i) { - call_event_res_ptr[i] = &call_event_res[i]; - } -} - -AreaBullet::~AreaBullet() { - // signal are handled by godot, so just clear without notify - for (int i = 0; i < overlapping_shapes.size(); i++) { - overlapping_shapes[i].other_object->on_exit_area(this); - } -} - -void AreaBullet::dispatch_callbacks() { - if (!isScratched) { - return; - } - isScratched = false; - - // Reverse order so items can be removed. - for (int i = overlapping_shapes.size() - 1; i >= 0; i--) { - OverlappingShapeData &overlapping_shape = overlapping_shapes.write[i]; - - switch (overlapping_shape.state) { - case OVERLAP_STATE_ENTER: - overlapping_shape.state = OVERLAP_STATE_INSIDE; - call_event(overlapping_shape, PhysicsServer3D::AREA_BODY_ADDED); - if (_overlapping_shape_count(overlapping_shape.other_object) == 1) { - // This object's first shape being added. - overlapping_shape.other_object->on_enter_area(this); - } - break; - case OVERLAP_STATE_EXIT: - call_event(overlapping_shape, PhysicsServer3D::AREA_BODY_REMOVED); - if (_overlapping_shape_count(overlapping_shape.other_object) == 1) { - // This object's last shape being removed. - overlapping_shape.other_object->on_exit_area(this); - } - overlapping_shapes.remove_at(i); // Remove after callback - break; - case OVERLAP_STATE_INSIDE: { - if (overlapping_shape.other_object->getType() == TYPE_RIGID_BODY) { - RigidBodyBullet *body = static_cast<RigidBodyBullet *>(overlapping_shape.other_object); - body->scratch_space_override_modificator(); - } - break; - } - case OVERLAP_STATE_DIRTY: - break; - } - } -} - -void AreaBullet::call_event(const OverlappingShapeData &p_overlapping_shape, PhysicsServer3D::AreaBodyStatus p_status) { - InOutEventCallback &event = eventsCallbacks[static_cast<int>(p_overlapping_shape.other_object->getType())]; - - if (!event.event_callback.is_valid()) { - event.event_callback = Callable(); - return; - } - - call_event_res[0] = p_status; - call_event_res[1] = p_overlapping_shape.other_object->get_self(); // RID - call_event_res[2] = p_overlapping_shape.other_object->get_instance_id(); // Object ID - call_event_res[3] = p_overlapping_shape.other_shape_id; // Other object's shape ID - call_event_res[4] = p_overlapping_shape.our_shape_id; // This area's shape ID - - Callable::CallError outResp; - Variant ret; - event.event_callback.call((const Variant **)call_event_res, 5, ret, outResp); -} - -int AreaBullet::_overlapping_shape_count(CollisionObjectBullet *p_other_object) { - int count = 0; - for (int i = 0; i < overlapping_shapes.size(); i++) { - if (overlapping_shapes[i].other_object == p_other_object) { - count++; - } - } - return count; -} - -int AreaBullet::_find_overlapping_shape(CollisionObjectBullet *p_other_object, uint32_t p_other_shape_id, uint32_t p_our_shape_id) { - for (int i = 0; i < overlapping_shapes.size(); i++) { - const OverlappingShapeData &overlapping_shape = overlapping_shapes[i]; - if (overlapping_shape.other_object == p_other_object && overlapping_shape.other_shape_id == p_other_shape_id && overlapping_shape.our_shape_id == p_our_shape_id) { - return i; - } - } - return -1; -} - -void AreaBullet::mark_all_overlaps_dirty() { - OverlappingShapeData *overlapping_shapes_w = overlapping_shapes.ptrw(); - for (int i = 0; i < overlapping_shapes.size(); i++) { - // Don't overwrite OVERLAP_STATE_ENTER state. - if (overlapping_shapes_w[i].state != OVERLAP_STATE_ENTER) { - overlapping_shapes_w[i].state = OVERLAP_STATE_DIRTY; - } - } -} - -void AreaBullet::mark_object_overlaps_inside(CollisionObjectBullet *p_other_object) { - OverlappingShapeData *overlapping_shapes_w = overlapping_shapes.ptrw(); - for (int i = 0; i < overlapping_shapes.size(); i++) { - if (overlapping_shapes_w[i].other_object == p_other_object && overlapping_shapes_w[i].state == OVERLAP_STATE_DIRTY) { - overlapping_shapes_w[i].state = OVERLAP_STATE_INSIDE; - } - } -} - -void AreaBullet::set_overlap(CollisionObjectBullet *p_other_object, uint32_t p_other_shape_id, uint32_t p_our_shape_id) { - int i = _find_overlapping_shape(p_other_object, p_other_shape_id, p_our_shape_id); - if (i == -1) { // Not found, create new one. - OverlappingShapeData overlapping_shape(p_other_object, OVERLAP_STATE_ENTER, p_other_shape_id, p_our_shape_id); - overlapping_shapes.push_back(overlapping_shape); - p_other_object->notify_new_overlap(this); - isScratched = true; - } else { - overlapping_shapes.ptrw()[i].state = OVERLAP_STATE_INSIDE; - } -} - -void AreaBullet::mark_all_dirty_overlaps_as_exit() { - OverlappingShapeData *overlapping_shapes_w = overlapping_shapes.ptrw(); - for (int i = 0; i < overlapping_shapes.size(); i++) { - if (overlapping_shapes[i].state == OVERLAP_STATE_DIRTY) { - overlapping_shapes_w[i].state = OVERLAP_STATE_EXIT; - isScratched = true; - } - } -} - -void AreaBullet::remove_object_overlaps(CollisionObjectBullet *p_object) { - // Reverse order so items can be removed. - for (int i = overlapping_shapes.size() - 1; i >= 0; i--) { - if (overlapping_shapes[i].other_object == p_object) { - overlapping_shapes.remove_at(i); - } - } -} - -void AreaBullet::clear_overlaps() { - for (int i = 0; i < overlapping_shapes.size(); i++) { - call_event(overlapping_shapes[i], PhysicsServer3D::AREA_BODY_REMOVED); - overlapping_shapes[i].other_object->on_exit_area(this); - } - overlapping_shapes.clear(); -} - -void AreaBullet::set_monitorable(bool p_monitorable) { - monitorable = p_monitorable; - updated = true; -} - -bool AreaBullet::is_monitoring() const { - return get_godot_object_flags() & GOF_IS_MONITORING_AREA; -} - -void AreaBullet::main_shape_changed() { - CRASH_COND(!get_main_shape()); - btGhost->setCollisionShape(get_main_shape()); - updated = true; -} - -void AreaBullet::reload_body() { - if (space) { - space->remove_area(this); - space->add_area(this); - } -} - -void AreaBullet::set_space(SpaceBullet *p_space) { - // Clear the old space if there is one - if (space) { - clear_overlaps(); - isScratched = false; - - // Remove this object form the physics world - space->remove_area(this); - } - - space = p_space; - - if (space) { - space->add_area(this); - } -} - -void AreaBullet::on_collision_filters_change() { - if (space) { - space->reload_collision_filters(this); - } - updated = true; -} - -void AreaBullet::set_param(PhysicsServer3D::AreaParameter p_param, const Variant &p_value) { - switch (p_param) { - case PhysicsServer3D::AREA_PARAM_GRAVITY: - set_spOv_gravityMag(p_value); - break; - case PhysicsServer3D::AREA_PARAM_GRAVITY_VECTOR: - set_spOv_gravityVec(p_value); - break; - case PhysicsServer3D::AREA_PARAM_LINEAR_DAMP: - set_spOv_linearDump(p_value); - break; - case PhysicsServer3D::AREA_PARAM_ANGULAR_DAMP: - set_spOv_angularDump(p_value); - break; - case PhysicsServer3D::AREA_PARAM_PRIORITY: - set_spOv_priority(p_value); - break; - case PhysicsServer3D::AREA_PARAM_GRAVITY_IS_POINT: - set_spOv_gravityPoint(p_value); - break; - case PhysicsServer3D::AREA_PARAM_GRAVITY_DISTANCE_SCALE: - set_spOv_gravityPointDistanceScale(p_value); - break; - case PhysicsServer3D::AREA_PARAM_GRAVITY_POINT_ATTENUATION: - set_spOv_gravityPointAttenuation(p_value); - break; - default: - WARN_PRINT("Area doesn't support this parameter in the Bullet backend: " + itos(p_param)); - } - isScratched = true; -} - -Variant AreaBullet::get_param(PhysicsServer3D::AreaParameter p_param) const { - switch (p_param) { - case PhysicsServer3D::AREA_PARAM_GRAVITY: - return spOv_gravityMag; - case PhysicsServer3D::AREA_PARAM_GRAVITY_VECTOR: - return spOv_gravityVec; - case PhysicsServer3D::AREA_PARAM_LINEAR_DAMP: - return spOv_linearDump; - case PhysicsServer3D::AREA_PARAM_ANGULAR_DAMP: - return spOv_angularDump; - case PhysicsServer3D::AREA_PARAM_PRIORITY: - return spOv_priority; - case PhysicsServer3D::AREA_PARAM_GRAVITY_IS_POINT: - return spOv_gravityPoint; - case PhysicsServer3D::AREA_PARAM_GRAVITY_DISTANCE_SCALE: - return spOv_gravityPointDistanceScale; - case PhysicsServer3D::AREA_PARAM_GRAVITY_POINT_ATTENUATION: - return spOv_gravityPointAttenuation; - default: - WARN_PRINT("Area doesn't support this parameter in the Bullet backend: " + itos(p_param)); - return Variant(); - } -} - -void AreaBullet::set_event_callback(Type p_callbackObjectType, const Callable &p_callback) { - InOutEventCallback &ev = eventsCallbacks[static_cast<int>(p_callbackObjectType)]; - ev.event_callback = p_callback; - - /// Set if monitoring - if (!eventsCallbacks[0].event_callback.is_null() || !eventsCallbacks[1].event_callback.is_null()) { - set_godot_object_flags(get_godot_object_flags() | GOF_IS_MONITORING_AREA); - } else { - set_godot_object_flags(get_godot_object_flags() & (~GOF_IS_MONITORING_AREA)); - clear_overlaps(); - } -} - -bool AreaBullet::has_event_callback(Type p_callbackObjectType) { - return !eventsCallbacks[static_cast<int>(p_callbackObjectType)].event_callback.is_null(); -} - -void AreaBullet::on_enter_area(AreaBullet *p_area) { -} - -void AreaBullet::on_exit_area(AreaBullet *p_area) { - CollisionObjectBullet::on_exit_area(p_area); -} diff --git a/modules/bullet/area_bullet.h b/modules/bullet/area_bullet.h deleted file mode 100644 index 740378d0e3..0000000000 --- a/modules/bullet/area_bullet.h +++ /dev/null @@ -1,162 +0,0 @@ -/*************************************************************************/ -/* area_bullet.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* 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. */ -/*************************************************************************/ - -#ifndef AREA_BULLET_H -#define AREA_BULLET_H - -#include "collision_object_bullet.h" -#include "core/templates/vector.h" -#include "servers/physics_server_3d.h" -#include "space_bullet.h" - -class btGhostObject; - -class AreaBullet : public RigidCollisionObjectBullet { -public: - struct InOutEventCallback { - Callable event_callback; - - InOutEventCallback() {} - }; - - enum OverlapState { - OVERLAP_STATE_DIRTY = 0, // Mark processed overlaps - OVERLAP_STATE_INSIDE, // Mark old overlap - OVERLAP_STATE_ENTER, // Mark just enter overlap - OVERLAP_STATE_EXIT // Mark ended overlaps - }; - - struct OverlappingShapeData { - CollisionObjectBullet *other_object = nullptr; - OverlapState state = OVERLAP_STATE_DIRTY; - uint32_t other_shape_id = 0; - uint32_t our_shape_id = 0; - - OverlappingShapeData() {} - - OverlappingShapeData(CollisionObjectBullet *p_other_object, OverlapState p_state, uint32_t p_other_shape_id, uint32_t p_our_shape_id) : - other_object(p_other_object), - state(p_state), - other_shape_id(p_other_shape_id), - our_shape_id(p_our_shape_id) {} - }; - -private: - // These are used by function callEvent. Instead to create this each call I create if one time. - Variant call_event_res[5]; - Variant *call_event_res_ptr[5] = {}; - - btGhostObject *btGhost = nullptr; - Vector<OverlappingShapeData> overlapping_shapes; - int _overlapping_shape_count(CollisionObjectBullet *p_other_object); - int _find_overlapping_shape(CollisionObjectBullet *p_other_object, uint32_t p_other_shape_id, uint32_t p_our_shape_id); - bool monitorable = true; - - PhysicsServer3D::AreaSpaceOverrideMode spOv_mode = PhysicsServer3D::AREA_SPACE_OVERRIDE_DISABLED; - bool spOv_gravityPoint = false; - real_t spOv_gravityPointDistanceScale = 0.0; - real_t spOv_gravityPointAttenuation = 1.0; - Vector3 spOv_gravityVec = Vector3(0, -1, 0); - real_t spOv_gravityMag = 10.0; - real_t spOv_linearDump = 0.1; - real_t spOv_angularDump = 0.1; - int spOv_priority = 0; - - bool isScratched = false; - - InOutEventCallback eventsCallbacks[2]; - -public: - AreaBullet(); - ~AreaBullet(); - - _FORCE_INLINE_ btGhostObject *get_bt_ghost() const { return btGhost; } - - void set_monitorable(bool p_monitorable); - _FORCE_INLINE_ bool is_monitorable() const { return monitorable; } - - bool is_monitoring() const; - - _FORCE_INLINE_ void set_spOv_mode(PhysicsServer3D::AreaSpaceOverrideMode p_mode) { spOv_mode = p_mode; } - _FORCE_INLINE_ PhysicsServer3D::AreaSpaceOverrideMode get_spOv_mode() { return spOv_mode; } - - _FORCE_INLINE_ void set_spOv_gravityPoint(bool p_isGP) { spOv_gravityPoint = p_isGP; } - _FORCE_INLINE_ bool is_spOv_gravityPoint() { return spOv_gravityPoint; } - - _FORCE_INLINE_ void set_spOv_gravityPointDistanceScale(real_t p_GPDS) { spOv_gravityPointDistanceScale = p_GPDS; } - _FORCE_INLINE_ real_t get_spOv_gravityPointDistanceScale() { return spOv_gravityPointDistanceScale; } - - _FORCE_INLINE_ void set_spOv_gravityPointAttenuation(real_t p_GPA) { spOv_gravityPointAttenuation = p_GPA; } - _FORCE_INLINE_ real_t get_spOv_gravityPointAttenuation() { return spOv_gravityPointAttenuation; } - - _FORCE_INLINE_ void set_spOv_gravityVec(Vector3 p_vec) { spOv_gravityVec = p_vec; } - _FORCE_INLINE_ const Vector3 &get_spOv_gravityVec() const { return spOv_gravityVec; } - - _FORCE_INLINE_ void set_spOv_gravityMag(real_t p_gravityMag) { spOv_gravityMag = p_gravityMag; } - _FORCE_INLINE_ real_t get_spOv_gravityMag() { return spOv_gravityMag; } - - _FORCE_INLINE_ void set_spOv_linearDump(real_t p_linearDump) { spOv_linearDump = p_linearDump; } - _FORCE_INLINE_ real_t get_spOv_linearDamp() { return spOv_linearDump; } - - _FORCE_INLINE_ void set_spOv_angularDump(real_t p_angularDump) { spOv_angularDump = p_angularDump; } - _FORCE_INLINE_ real_t get_spOv_angularDamp() { return spOv_angularDump; } - - _FORCE_INLINE_ void set_spOv_priority(int p_priority) { spOv_priority = p_priority; } - _FORCE_INLINE_ int get_spOv_priority() { return spOv_priority; } - - virtual void main_shape_changed(); - virtual void reload_body(); - virtual void set_space(SpaceBullet *p_space); - - virtual void dispatch_callbacks(); - void call_event(const OverlappingShapeData &p_overlapping_shape, PhysicsServer3D::AreaBodyStatus p_status); - - virtual void on_collision_filters_change(); - virtual void on_collision_checker_start() {} - virtual void on_collision_checker_end() { updated = false; } - - void mark_all_overlaps_dirty(); - void mark_object_overlaps_inside(CollisionObjectBullet *p_other_object); - void set_overlap(CollisionObjectBullet *p_other_object, uint32_t p_other_shape_id, uint32_t p_our_shape_id); - void mark_all_dirty_overlaps_as_exit(); - void remove_object_overlaps(CollisionObjectBullet *p_object); - void clear_overlaps(); - - void set_param(PhysicsServer3D::AreaParameter p_param, const Variant &p_value); - Variant get_param(PhysicsServer3D::AreaParameter p_param) const; - - void set_event_callback(Type p_callbackObjectType, const Callable &p_callback); - bool has_event_callback(Type p_callbackObjectType); - - virtual void on_enter_area(AreaBullet *p_area); - virtual void on_exit_area(AreaBullet *p_area); -}; - -#endif // AREA_BULLET_H diff --git a/modules/bullet/btRayShape.cpp b/modules/bullet/btRayShape.cpp deleted file mode 100644 index 14bc7442a7..0000000000 --- a/modules/bullet/btRayShape.cpp +++ /dev/null @@ -1,101 +0,0 @@ -/*************************************************************************/ -/* btRayShape.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* 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 "btRayShape.h" - -#include "core/math/math_funcs.h" - -#include <LinearMath/btAabbUtil2.h> - -btRayShape::btRayShape(btScalar length) : - btConvexInternalShape() { - m_shapeType = CUSTOM_CONVEX_SHAPE_TYPE; - setLength(length); -} - -btRayShape::~btRayShape() { -} - -void btRayShape::setLength(btScalar p_length) { - m_length = p_length; - reload_cache(); -} - -void btRayShape::setMargin(btScalar margin) { - btConvexInternalShape::setMargin(margin); - reload_cache(); -} - -void btRayShape::setSlipsOnSlope(bool p_slipsOnSlope) { - slipsOnSlope = p_slipsOnSlope; -} - -btVector3 btRayShape::localGetSupportingVertex(const btVector3 &vec) const { - return localGetSupportingVertexWithoutMargin(vec) + (m_shapeAxis * m_collisionMargin); -} - -btVector3 btRayShape::localGetSupportingVertexWithoutMargin(const btVector3 &vec) const { - if (vec.z() > 0) { - return m_shapeAxis * m_cacheScaledLength; - } else { - return btVector3(0, 0, 0); - } -} - -void btRayShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3 *vectors, btVector3 *supportVerticesOut, int numVectors) const { - for (int i = 0; i < numVectors; ++i) { - supportVerticesOut[i] = localGetSupportingVertexWithoutMargin(vectors[i]); - } -} - -void btRayShape::getAabb(const btTransform &t, btVector3 &aabbMin, btVector3 &aabbMax) const { - btVector3 localAabbMin(0, 0, 0); - btVector3 localAabbMax(m_shapeAxis * m_cacheScaledLength); - btTransformAabb(localAabbMin, localAabbMax, m_collisionMargin, t, aabbMin, aabbMax); -} - -void btRayShape::calculateLocalInertia(btScalar mass, btVector3 &inertia) const { - inertia.setZero(); -} - -int btRayShape::getNumPreferredPenetrationDirections() const { - return 0; -} - -void btRayShape::getPreferredPenetrationDirection(int index, btVector3 &penetrationVector) const { - penetrationVector.setZero(); -} - -void btRayShape::reload_cache() { - m_cacheScaledLength = m_length * m_localScaling[2]; - - m_cacheSupportPoint.setIdentity(); - m_cacheSupportPoint.setOrigin(m_shapeAxis * m_cacheScaledLength); -} diff --git a/modules/bullet/btRayShape.h b/modules/bullet/btRayShape.h deleted file mode 100644 index 90e4524d64..0000000000 --- a/modules/bullet/btRayShape.h +++ /dev/null @@ -1,91 +0,0 @@ -/*************************************************************************/ -/* btRayShape.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* 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. */ -/*************************************************************************/ - -/// IMPORTANT The class name and filename was created by following Bullet writing rules for an easy (eventually) porting to bullet -/// This shape is a custom shape that is not present to Bullet physics engine -#ifndef BTRAYSHAPE_H -#define BTRAYSHAPE_H - -#include <BulletCollision/CollisionShapes/btConvexInternalShape.h> - -/// Ray shape around z axis -ATTRIBUTE_ALIGNED16(class) -btRayShape : public btConvexInternalShape { - btScalar m_length = 0; - bool slipsOnSlope = false; - /// The default axis is the z - btVector3 m_shapeAxis = btVector3(0, 0, 1); - - btTransform m_cacheSupportPoint; - btScalar m_cacheScaledLength; - -public: - BT_DECLARE_ALIGNED_ALLOCATOR(); - - btRayShape(btScalar length); - virtual ~btRayShape(); - - void setLength(btScalar p_length); - btScalar getLength() const { return m_length; } - - virtual void setMargin(btScalar margin); - - void setSlipsOnSlope(bool p_slipsOnSlope); - bool getSlipsOnSlope() const { return slipsOnSlope; } - - const btTransform &getSupportPoint() const { return m_cacheSupportPoint; } - const btScalar &getScaledLength() const { return m_cacheScaledLength; } - - virtual btVector3 localGetSupportingVertex(const btVector3 &vec) const; -#ifndef __SPU__ - virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3 &vec) const; -#endif //#ifndef __SPU__ - - virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3 *vectors, btVector3 *supportVerticesOut, int numVectors) const; - - ///getAabb returns the axis aligned bounding box in the coordinate frame of the given transform t. - virtual void getAabb(const btTransform &t, btVector3 &aabbMin, btVector3 &aabbMax) const; - -#ifndef __SPU__ - virtual void calculateLocalInertia(btScalar mass, btVector3 & inertia) const; - - virtual const char *getName() const { - return "RayZ"; - } -#endif //__SPU__ - - virtual int getNumPreferredPenetrationDirections() const; - virtual void getPreferredPenetrationDirection(int index, btVector3 &penetrationVector) const; - -private: - void reload_cache(); -}; - -#endif // BTRAYSHAPE_H diff --git a/modules/bullet/bullet_physics_server.cpp b/modules/bullet/bullet_physics_server.cpp deleted file mode 100644 index 7e9e621032..0000000000 --- a/modules/bullet/bullet_physics_server.cpp +++ /dev/null @@ -1,1535 +0,0 @@ -/*************************************************************************/ -/* bullet_physics_server.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* 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 "bullet_physics_server.h" - -#include "bullet_utilities.h" -#include "cone_twist_joint_bullet.h" -#include "core/error/error_macros.h" -#include "core/object/class_db.h" -#include "core/string/ustring.h" -#include "generic_6dof_joint_bullet.h" -#include "hinge_joint_bullet.h" -#include "pin_joint_bullet.h" -#include "shape_bullet.h" -#include "slider_joint_bullet.h" - -#include <LinearMath/btVector3.h> - -#include <assert.h> - -#define CreateThenReturnRID(owner, ridData) \ - RID rid = owner.make_rid(ridData); \ - ridData->set_self(rid); \ - ridData->_set_physics_server(this); \ - return rid; - -// <--------------- Joint creation asserts -/// Assert the body is assigned to a space -#define JointAssertSpace(body, bIndex, ret) \ - if (!body->get_space()) { \ - ERR_PRINT("Before create a joint the Body" + String(bIndex) + " must be added to a space!"); \ - return ret; \ - } - -/// Assert the two bodies of joint are in the same space -#define JointAssertSameSpace(bodyA, bodyB, ret) \ - if (bodyA->get_space() != bodyB->get_space()) { \ - ERR_PRINT("In order to create a joint the Body_A and Body_B must be in the same space!"); \ - return RID(); \ - } - -#define AddJointToSpace(body, joint) \ - body->get_space()->add_constraint(joint, joint->is_disabled_collisions_between_bodies()); -// <--------------- Joint creation asserts - -void BulletPhysicsServer3D::_bind_methods() { - //ClassDB::bind_method(D_METHOD("DoTest"), &BulletPhysicsServer3D::DoTest); -} - -BulletPhysicsServer3D::BulletPhysicsServer3D() : - PhysicsServer3D() {} - -BulletPhysicsServer3D::~BulletPhysicsServer3D() {} - -RID BulletPhysicsServer3D::shape_create(ShapeType p_shape) { - ShapeBullet *shape = nullptr; - - switch (p_shape) { - case SHAPE_WORLD_BOUNDARY: { - shape = bulletnew(WorldBoundaryShapeBullet); - } break; - case SHAPE_SPHERE: { - shape = bulletnew(SphereShapeBullet); - } break; - case SHAPE_BOX: { - shape = bulletnew(BoxShapeBullet); - } break; - case SHAPE_CAPSULE: { - shape = bulletnew(CapsuleShapeBullet); - } break; - case SHAPE_CYLINDER: { - shape = bulletnew(CylinderShapeBullet); - } break; - case SHAPE_CONVEX_POLYGON: { - shape = bulletnew(ConvexPolygonShapeBullet); - } break; - case SHAPE_CONCAVE_POLYGON: { - shape = bulletnew(ConcavePolygonShapeBullet); - } break; - case SHAPE_HEIGHTMAP: { - shape = bulletnew(HeightMapShapeBullet); - } break; - case SHAPE_RAY: { - shape = bulletnew(RayShapeBullet); - } break; - case SHAPE_CUSTOM: - default: - ERR_FAIL_V(RID()); - break; - } - - CreateThenReturnRID(shape_owner, shape) -} - -void BulletPhysicsServer3D::shape_set_data(RID p_shape, const Variant &p_data) { - ShapeBullet *shape = shape_owner.get_or_null(p_shape); - ERR_FAIL_COND(!shape); - shape->set_data(p_data); -} - -void BulletPhysicsServer3D::shape_set_custom_solver_bias(RID p_shape, real_t p_bias) { - //WARN_PRINT("Bias not supported by Bullet physics engine"); -} - -PhysicsServer3D::ShapeType BulletPhysicsServer3D::shape_get_type(RID p_shape) const { - ShapeBullet *shape = shape_owner.get_or_null(p_shape); - ERR_FAIL_COND_V(!shape, PhysicsServer3D::SHAPE_CUSTOM); - return shape->get_type(); -} - -Variant BulletPhysicsServer3D::shape_get_data(RID p_shape) const { - ShapeBullet *shape = shape_owner.get_or_null(p_shape); - ERR_FAIL_COND_V(!shape, Variant()); - return shape->get_data(); -} - -void BulletPhysicsServer3D::shape_set_margin(RID p_shape, real_t p_margin) { - ShapeBullet *shape = shape_owner.get_or_null(p_shape); - ERR_FAIL_COND(!shape); - shape->set_margin(p_margin); -} - -real_t BulletPhysicsServer3D::shape_get_margin(RID p_shape) const { - ShapeBullet *shape = shape_owner.get_or_null(p_shape); - ERR_FAIL_COND_V(!shape, 0.0); - return shape->get_margin(); -} - -real_t BulletPhysicsServer3D::shape_get_custom_solver_bias(RID p_shape) const { - //WARN_PRINT("Bias not supported by Bullet physics engine"); - return 0.; -} - -RID BulletPhysicsServer3D::space_create() { - SpaceBullet *space = bulletnew(SpaceBullet); - CreateThenReturnRID(space_owner, space); -} - -void BulletPhysicsServer3D::space_set_active(RID p_space, bool p_active) { - SpaceBullet *space = space_owner.get_or_null(p_space); - ERR_FAIL_COND(!space); - - if (space_is_active(p_space) == p_active) { - return; - } - - if (p_active) { - ++active_spaces_count; - active_spaces.push_back(space); - } else { - --active_spaces_count; - active_spaces.erase(space); - } -} - -bool BulletPhysicsServer3D::space_is_active(RID p_space) const { - SpaceBullet *space = space_owner.get_or_null(p_space); - ERR_FAIL_COND_V(!space, false); - - return -1 != active_spaces.find(space); -} - -void BulletPhysicsServer3D::space_set_param(RID p_space, SpaceParameter p_param, real_t p_value) { - SpaceBullet *space = space_owner.get_or_null(p_space); - ERR_FAIL_COND(!space); - space->set_param(p_param, p_value); -} - -real_t BulletPhysicsServer3D::space_get_param(RID p_space, SpaceParameter p_param) const { - SpaceBullet *space = space_owner.get_or_null(p_space); - ERR_FAIL_COND_V(!space, 0); - return space->get_param(p_param); -} - -PhysicsDirectSpaceState3D *BulletPhysicsServer3D::space_get_direct_state(RID p_space) { - SpaceBullet *space = space_owner.get_or_null(p_space); - ERR_FAIL_COND_V(!space, nullptr); - - return space->get_direct_state(); -} - -void BulletPhysicsServer3D::space_set_debug_contacts(RID p_space, int p_max_contacts) { - SpaceBullet *space = space_owner.get_or_null(p_space); - ERR_FAIL_COND(!space); - - space->set_debug_contacts(p_max_contacts); -} - -Vector<Vector3> BulletPhysicsServer3D::space_get_contacts(RID p_space) const { - SpaceBullet *space = space_owner.get_or_null(p_space); - ERR_FAIL_COND_V(!space, Vector<Vector3>()); - - return space->get_debug_contacts(); -} - -int BulletPhysicsServer3D::space_get_contact_count(RID p_space) const { - SpaceBullet *space = space_owner.get_or_null(p_space); - ERR_FAIL_COND_V(!space, 0); - - return space->get_debug_contact_count(); -} - -RID BulletPhysicsServer3D::area_create() { - AreaBullet *area = bulletnew(AreaBullet); - area->set_collision_layer(1); - area->set_collision_mask(1); - CreateThenReturnRID(area_owner, area) -} - -void BulletPhysicsServer3D::area_set_space(RID p_area, RID p_space) { - AreaBullet *area = area_owner.get_or_null(p_area); - ERR_FAIL_COND(!area); - SpaceBullet *space = nullptr; - if (p_space.is_valid()) { - space = space_owner.get_or_null(p_space); - ERR_FAIL_COND(!space); - } - area->set_space(space); -} - -RID BulletPhysicsServer3D::area_get_space(RID p_area) const { - AreaBullet *area = area_owner.get_or_null(p_area); - return area->get_space()->get_self(); -} - -void BulletPhysicsServer3D::area_set_space_override_mode(RID p_area, AreaSpaceOverrideMode p_mode) { - AreaBullet *area = area_owner.get_or_null(p_area); - ERR_FAIL_COND(!area); - - area->set_spOv_mode(p_mode); -} - -PhysicsServer3D::AreaSpaceOverrideMode BulletPhysicsServer3D::area_get_space_override_mode(RID p_area) const { - AreaBullet *area = area_owner.get_or_null(p_area); - ERR_FAIL_COND_V(!area, PhysicsServer3D::AREA_SPACE_OVERRIDE_DISABLED); - - return area->get_spOv_mode(); -} - -void BulletPhysicsServer3D::area_add_shape(RID p_area, RID p_shape, const Transform3D &p_transform, bool p_disabled) { - AreaBullet *area = area_owner.get_or_null(p_area); - ERR_FAIL_COND(!area); - - ShapeBullet *shape = shape_owner.get_or_null(p_shape); - ERR_FAIL_COND(!shape); - - area->add_shape(shape, p_transform, p_disabled); -} - -void BulletPhysicsServer3D::area_set_shape(RID p_area, int p_shape_idx, RID p_shape) { - AreaBullet *area = area_owner.get_or_null(p_area); - ERR_FAIL_COND(!area); - - ShapeBullet *shape = shape_owner.get_or_null(p_shape); - ERR_FAIL_COND(!shape); - - area->set_shape(p_shape_idx, shape); -} - -void BulletPhysicsServer3D::area_set_shape_transform(RID p_area, int p_shape_idx, const Transform3D &p_transform) { - AreaBullet *area = area_owner.get_or_null(p_area); - ERR_FAIL_COND(!area); - - area->set_shape_transform(p_shape_idx, p_transform); -} - -int BulletPhysicsServer3D::area_get_shape_count(RID p_area) const { - AreaBullet *area = area_owner.get_or_null(p_area); - ERR_FAIL_COND_V(!area, 0); - - return area->get_shape_count(); -} - -RID BulletPhysicsServer3D::area_get_shape(RID p_area, int p_shape_idx) const { - AreaBullet *area = area_owner.get_or_null(p_area); - ERR_FAIL_COND_V(!area, RID()); - - return area->get_shape(p_shape_idx)->get_self(); -} - -Transform3D BulletPhysicsServer3D::area_get_shape_transform(RID p_area, int p_shape_idx) const { - AreaBullet *area = area_owner.get_or_null(p_area); - ERR_FAIL_COND_V(!area, Transform3D()); - - return area->get_shape_transform(p_shape_idx); -} - -void BulletPhysicsServer3D::area_remove_shape(RID p_area, int p_shape_idx) { - AreaBullet *area = area_owner.get_or_null(p_area); - ERR_FAIL_COND(!area); - return area->remove_shape_full(p_shape_idx); -} - -void BulletPhysicsServer3D::area_clear_shapes(RID p_area) { - AreaBullet *area = area_owner.get_or_null(p_area); - ERR_FAIL_COND(!area); - - for (int i = area->get_shape_count(); 0 < i; --i) { - area->remove_shape_full(0); - } -} - -void BulletPhysicsServer3D::area_set_shape_disabled(RID p_area, int p_shape_idx, bool p_disabled) { - AreaBullet *area = area_owner.get_or_null(p_area); - ERR_FAIL_COND(!area); - - area->set_shape_disabled(p_shape_idx, p_disabled); -} - -void BulletPhysicsServer3D::area_attach_object_instance_id(RID p_area, ObjectID p_id) { - if (space_owner.owns(p_area)) { - return; - } - AreaBullet *area = area_owner.get_or_null(p_area); - ERR_FAIL_COND(!area); - area->set_instance_id(p_id); -} - -ObjectID BulletPhysicsServer3D::area_get_object_instance_id(RID p_area) const { - if (space_owner.owns(p_area)) { - return ObjectID(); - } - AreaBullet *area = area_owner.get_or_null(p_area); - ERR_FAIL_COND_V(!area, ObjectID()); - return area->get_instance_id(); -} - -void BulletPhysicsServer3D::area_set_param(RID p_area, AreaParameter p_param, const Variant &p_value) { - if (space_owner.owns(p_area)) { - SpaceBullet *space = space_owner.get_or_null(p_area); - if (space) { - space->set_param(p_param, p_value); - } - } else { - AreaBullet *area = area_owner.get_or_null(p_area); - ERR_FAIL_COND(!area); - - area->set_param(p_param, p_value); - } -} - -Variant BulletPhysicsServer3D::area_get_param(RID p_area, AreaParameter p_param) const { - if (space_owner.owns(p_area)) { - SpaceBullet *space = space_owner.get_or_null(p_area); - return space->get_param(p_param); - } else { - AreaBullet *area = area_owner.get_or_null(p_area); - ERR_FAIL_COND_V(!area, Variant()); - - return area->get_param(p_param); - } -} - -void BulletPhysicsServer3D::area_set_transform(RID p_area, const Transform3D &p_transform) { - AreaBullet *area = area_owner.get_or_null(p_area); - ERR_FAIL_COND(!area); - area->set_transform(p_transform); -} - -Transform3D BulletPhysicsServer3D::area_get_transform(RID p_area) const { - AreaBullet *area = area_owner.get_or_null(p_area); - ERR_FAIL_COND_V(!area, Transform3D()); - return area->get_transform(); -} - -void BulletPhysicsServer3D::area_set_collision_mask(RID p_area, uint32_t p_mask) { - AreaBullet *area = area_owner.get_or_null(p_area); - ERR_FAIL_COND(!area); - area->set_collision_mask(p_mask); -} - -void BulletPhysicsServer3D::area_set_collision_layer(RID p_area, uint32_t p_layer) { - AreaBullet *area = area_owner.get_or_null(p_area); - ERR_FAIL_COND(!area); - area->set_collision_layer(p_layer); -} - -void BulletPhysicsServer3D::area_set_monitorable(RID p_area, bool p_monitorable) { - AreaBullet *area = area_owner.get_or_null(p_area); - ERR_FAIL_COND(!area); - - area->set_monitorable(p_monitorable); -} - -void BulletPhysicsServer3D::area_set_monitor_callback(RID p_area, const Callable &p_callback) { - AreaBullet *area = area_owner.get_or_null(p_area); - ERR_FAIL_COND(!area); - - area->set_event_callback(CollisionObjectBullet::TYPE_RIGID_BODY, p_callback.is_valid() ? p_callback : Callable()); -} - -void BulletPhysicsServer3D::area_set_area_monitor_callback(RID p_area, const Callable &p_callback) { - AreaBullet *area = area_owner.get_or_null(p_area); - ERR_FAIL_COND(!area); - - area->set_event_callback(CollisionObjectBullet::TYPE_AREA, p_callback.is_valid() ? p_callback : Callable()); -} - -void BulletPhysicsServer3D::area_set_ray_pickable(RID p_area, bool p_enable) { - AreaBullet *area = area_owner.get_or_null(p_area); - ERR_FAIL_COND(!area); - area->set_ray_pickable(p_enable); -} - -RID BulletPhysicsServer3D::body_create(BodyMode p_mode, bool p_init_sleeping) { - RigidBodyBullet *body = bulletnew(RigidBodyBullet); - body->set_mode(p_mode); - body->set_collision_layer(1); - body->set_collision_mask(1); - if (p_init_sleeping) { - body->set_state(BODY_STATE_SLEEPING, p_init_sleeping); - } - CreateThenReturnRID(rigid_body_owner, body); -} - -void BulletPhysicsServer3D::body_set_space(RID p_body, RID p_space) { - RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - SpaceBullet *space = nullptr; - - if (p_space.is_valid()) { - space = space_owner.get_or_null(p_space); - ERR_FAIL_COND(!space); - } - - if (body->get_space() == space) { - return; //pointless - } - - body->set_space(space); -} - -RID BulletPhysicsServer3D::body_get_space(RID p_body) const { - RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); - ERR_FAIL_COND_V(!body, RID()); - - SpaceBullet *space = body->get_space(); - if (!space) { - return RID(); - } - return space->get_self(); -} - -void BulletPhysicsServer3D::body_set_mode(RID p_body, PhysicsServer3D::BodyMode p_mode) { - RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - body->set_mode(p_mode); -} - -PhysicsServer3D::BodyMode BulletPhysicsServer3D::body_get_mode(RID p_body) const { - RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); - ERR_FAIL_COND_V(!body, BODY_MODE_STATIC); - return body->get_mode(); -} - -void BulletPhysicsServer3D::body_add_shape(RID p_body, RID p_shape, const Transform3D &p_transform, bool p_disabled) { - RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - - ShapeBullet *shape = shape_owner.get_or_null(p_shape); - ERR_FAIL_COND(!shape); - - body->add_shape(shape, p_transform, p_disabled); -} - -void BulletPhysicsServer3D::body_set_shape(RID p_body, int p_shape_idx, RID p_shape) { - RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - - ShapeBullet *shape = shape_owner.get_or_null(p_shape); - ERR_FAIL_COND(!shape); - - body->set_shape(p_shape_idx, shape); -} - -void BulletPhysicsServer3D::body_set_shape_transform(RID p_body, int p_shape_idx, const Transform3D &p_transform) { - RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - - body->set_shape_transform(p_shape_idx, p_transform); -} - -int BulletPhysicsServer3D::body_get_shape_count(RID p_body) const { - RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); - ERR_FAIL_COND_V(!body, 0); - return body->get_shape_count(); -} - -RID BulletPhysicsServer3D::body_get_shape(RID p_body, int p_shape_idx) const { - RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); - ERR_FAIL_COND_V(!body, RID()); - - ShapeBullet *shape = body->get_shape(p_shape_idx); - ERR_FAIL_COND_V(!shape, RID()); - - return shape->get_self(); -} - -Transform3D BulletPhysicsServer3D::body_get_shape_transform(RID p_body, int p_shape_idx) const { - RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); - ERR_FAIL_COND_V(!body, Transform3D()); - return body->get_shape_transform(p_shape_idx); -} - -void BulletPhysicsServer3D::body_set_shape_disabled(RID p_body, int p_shape_idx, bool p_disabled) { - RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - - body->set_shape_disabled(p_shape_idx, p_disabled); -} - -void BulletPhysicsServer3D::body_remove_shape(RID p_body, int p_shape_idx) { - RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - - body->remove_shape_full(p_shape_idx); -} - -void BulletPhysicsServer3D::body_clear_shapes(RID p_body) { - RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - - body->remove_all_shapes(); -} - -void BulletPhysicsServer3D::body_attach_object_instance_id(RID p_body, ObjectID p_id) { - CollisionObjectBullet *body = get_collision_object(p_body); - ERR_FAIL_COND(!body); - - body->set_instance_id(p_id); -} - -ObjectID BulletPhysicsServer3D::body_get_object_instance_id(RID p_body) const { - CollisionObjectBullet *body = get_collision_object(p_body); - ERR_FAIL_COND_V(!body, ObjectID()); - - return body->get_instance_id(); -} - -void BulletPhysicsServer3D::body_set_enable_continuous_collision_detection(RID p_body, bool p_enable) { - RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - - body->set_continuous_collision_detection(p_enable); -} - -bool BulletPhysicsServer3D::body_is_continuous_collision_detection_enabled(RID p_body) const { - RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); - ERR_FAIL_COND_V(!body, false); - - return body->is_continuous_collision_detection_enabled(); -} - -void BulletPhysicsServer3D::body_set_collision_layer(RID p_body, uint32_t p_layer) { - RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - - body->set_collision_layer(p_layer); -} - -uint32_t BulletPhysicsServer3D::body_get_collision_layer(RID p_body) const { - const RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); - ERR_FAIL_COND_V(!body, 0); - - return body->get_collision_layer(); -} - -void BulletPhysicsServer3D::body_set_collision_mask(RID p_body, uint32_t p_mask) { - RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - - body->set_collision_mask(p_mask); -} - -uint32_t BulletPhysicsServer3D::body_get_collision_mask(RID p_body) const { - RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); - ERR_FAIL_COND_V(!body, 0); - - return body->get_collision_mask(); -} - -void BulletPhysicsServer3D::body_set_user_flags(RID p_body, uint32_t p_flags) { - // This function is not currently supported -} - -uint32_t BulletPhysicsServer3D::body_get_user_flags(RID p_body) const { - // This function is not currently supported - return 0; -} - -void BulletPhysicsServer3D::body_set_param(RID p_body, BodyParameter p_param, real_t p_value) { - RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - - body->set_param(p_param, p_value); -} - -real_t BulletPhysicsServer3D::body_get_param(RID p_body, BodyParameter p_param) const { - RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); - ERR_FAIL_COND_V(!body, 0); - - return body->get_param(p_param); -} - -void BulletPhysicsServer3D::body_set_kinematic_safe_margin(RID p_body, real_t p_margin) { - RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - - if (body->get_kinematic_utilities()) { - body->get_kinematic_utilities()->setSafeMargin(p_margin); - } -} - -real_t BulletPhysicsServer3D::body_get_kinematic_safe_margin(RID p_body) const { - RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); - ERR_FAIL_COND_V(!body, 0); - - if (body->get_kinematic_utilities()) { - return body->get_kinematic_utilities()->safe_margin; - } - - return 0; -} - -void BulletPhysicsServer3D::body_set_state(RID p_body, BodyState p_state, const Variant &p_variant) { - RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - - body->set_state(p_state, p_variant); -} - -Variant BulletPhysicsServer3D::body_get_state(RID p_body, BodyState p_state) const { - RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); - ERR_FAIL_COND_V(!body, Variant()); - - return body->get_state(p_state); -} - -void BulletPhysicsServer3D::body_set_applied_force(RID p_body, const Vector3 &p_force) { - RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - - body->set_applied_force(p_force); -} - -Vector3 BulletPhysicsServer3D::body_get_applied_force(RID p_body) const { - RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); - ERR_FAIL_COND_V(!body, Vector3()); - return body->get_applied_force(); -} - -void BulletPhysicsServer3D::body_set_applied_torque(RID p_body, const Vector3 &p_torque) { - RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - - body->set_applied_torque(p_torque); -} - -Vector3 BulletPhysicsServer3D::body_get_applied_torque(RID p_body) const { - RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); - ERR_FAIL_COND_V(!body, Vector3()); - - return body->get_applied_torque(); -} - -void BulletPhysicsServer3D::body_add_central_force(RID p_body, const Vector3 &p_force) { - RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - - body->apply_central_force(p_force); -} - -void BulletPhysicsServer3D::body_add_force(RID p_body, const Vector3 &p_force, const Vector3 &p_position) { - RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - - body->apply_force(p_force, p_position); -} - -void BulletPhysicsServer3D::body_add_torque(RID p_body, const Vector3 &p_torque) { - RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - - body->apply_torque(p_torque); -} - -void BulletPhysicsServer3D::body_apply_central_impulse(RID p_body, const Vector3 &p_impulse) { - RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - - body->apply_central_impulse(p_impulse); -} - -void BulletPhysicsServer3D::body_apply_impulse(RID p_body, const Vector3 &p_impulse, const Vector3 &p_position) { - RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - - body->apply_impulse(p_impulse, p_position); -} - -void BulletPhysicsServer3D::body_apply_torque_impulse(RID p_body, const Vector3 &p_impulse) { - RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - - body->apply_torque_impulse(p_impulse); -} - -void BulletPhysicsServer3D::body_set_axis_velocity(RID p_body, const Vector3 &p_axis_velocity) { - RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - - Vector3 v = body->get_linear_velocity(); - Vector3 axis = p_axis_velocity.normalized(); - v -= axis * axis.dot(v); - v += p_axis_velocity; - body->set_linear_velocity(v); -} - -void BulletPhysicsServer3D::body_set_axis_lock(RID p_body, BodyAxis p_axis, bool p_lock) { - RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - body->set_axis_lock(p_axis, p_lock); -} - -bool BulletPhysicsServer3D::body_is_axis_locked(RID p_body, BodyAxis p_axis) const { - const RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); - ERR_FAIL_COND_V(!body, 0); - return body->is_axis_locked(p_axis); -} - -void BulletPhysicsServer3D::body_add_collision_exception(RID p_body, RID p_body_b) { - RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - - RigidBodyBullet *other_body = rigid_body_owner.get_or_null(p_body_b); - ERR_FAIL_COND(!other_body); - - body->add_collision_exception(other_body); -} - -void BulletPhysicsServer3D::body_remove_collision_exception(RID p_body, RID p_body_b) { - RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - - RigidBodyBullet *other_body = rigid_body_owner.get_or_null(p_body_b); - ERR_FAIL_COND(!other_body); - - body->remove_collision_exception(other_body); -} - -void BulletPhysicsServer3D::body_get_collision_exceptions(RID p_body, List<RID> *p_exceptions) { - RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - for (int i = 0; i < body->get_exceptions().size(); i++) { - p_exceptions->push_back(body->get_exceptions()[i]); - } -} - -void BulletPhysicsServer3D::body_set_max_contacts_reported(RID p_body, int p_contacts) { - RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - - body->set_max_collisions_detection(p_contacts); -} - -int BulletPhysicsServer3D::body_get_max_contacts_reported(RID p_body) const { - RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); - ERR_FAIL_COND_V(!body, 0); - - return body->get_max_collisions_detection(); -} - -void BulletPhysicsServer3D::body_set_contacts_reported_depth_threshold(RID p_body, real_t p_threshold) { - // Not supported by bullet and even Godot -} - -real_t BulletPhysicsServer3D::body_get_contacts_reported_depth_threshold(RID p_body) const { - // Not supported by bullet and even Godot - return 0.; -} - -void BulletPhysicsServer3D::body_set_omit_force_integration(RID p_body, bool p_omit) { - RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - - body->set_omit_forces_integration(p_omit); -} - -bool BulletPhysicsServer3D::body_is_omitting_force_integration(RID p_body) const { - RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); - ERR_FAIL_COND_V(!body, false); - - return body->get_omit_forces_integration(); -} - -void BulletPhysicsServer3D::body_set_force_integration_callback(RID p_body, const Callable &p_callable, const Variant &p_udata) { - RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - body->set_force_integration_callback(p_callable, p_udata); -} - -void BulletPhysicsServer3D::body_set_ray_pickable(RID p_body, bool p_enable) { - RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - body->set_ray_pickable(p_enable); -} - -PhysicsDirectBodyState3D *BulletPhysicsServer3D::body_get_direct_state(RID p_body) { - if (!rigid_body_owner.owns(p_body)) { - return nullptr; - } - - RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); - ERR_FAIL_COND_V(!body, nullptr); - - if (!body->get_space()) { - return nullptr; - } - - return BulletPhysicsDirectBodyState3D::get_singleton(body); -} - -bool BulletPhysicsServer3D::body_test_motion(RID p_body, const Transform3D &p_from, const Vector3 &p_motion, bool p_infinite_inertia, MotionResult *r_result, bool p_exclude_raycast_shapes, const Set<RID> &p_exclude) { - RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); - ERR_FAIL_COND_V(!body, false); - ERR_FAIL_COND_V(!body->get_space(), false); - - return body->get_space()->test_body_motion(body, p_from, p_motion, p_infinite_inertia, r_result, p_exclude_raycast_shapes, p_exclude); -} - -int BulletPhysicsServer3D::body_test_ray_separation(RID p_body, const Transform3D &p_transform, bool p_infinite_inertia, Vector3 &r_recover_motion, SeparationResult *r_results, int p_result_max, real_t p_margin) { - RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); - ERR_FAIL_COND_V(!body, 0); - ERR_FAIL_COND_V(!body->get_space(), 0); - - return body->get_space()->test_ray_separation(body, p_transform, p_infinite_inertia, r_recover_motion, r_results, p_result_max, p_margin); -} - -RID BulletPhysicsServer3D::soft_body_create(bool p_init_sleeping) { - SoftBodyBullet *body = bulletnew(SoftBodyBullet); - body->set_collision_layer(1); - body->set_collision_mask(1); - if (p_init_sleeping) { - body->set_activation_state(false); - } - CreateThenReturnRID(soft_body_owner, body); -} - -void BulletPhysicsServer3D::soft_body_update_rendering_server(RID p_body, RenderingServerHandler *p_rendering_server_handler) { - SoftBodyBullet *body = soft_body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - - body->update_rendering_server(p_rendering_server_handler); -} - -void BulletPhysicsServer3D::soft_body_set_space(RID p_body, RID p_space) { - SoftBodyBullet *body = soft_body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - SpaceBullet *space = nullptr; - - if (p_space.is_valid()) { - space = space_owner.get_or_null(p_space); - ERR_FAIL_COND(!space); - } - - if (body->get_space() == space) { - return; //pointless - } - - body->set_space(space); -} - -RID BulletPhysicsServer3D::soft_body_get_space(RID p_body) const { - SoftBodyBullet *body = soft_body_owner.get_or_null(p_body); - ERR_FAIL_COND_V(!body, RID()); - - SpaceBullet *space = body->get_space(); - if (!space) { - return RID(); - } - return space->get_self(); -} - -void BulletPhysicsServer3D::soft_body_set_mesh(RID p_body, RID p_mesh) { - SoftBodyBullet *body = soft_body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - - body->set_soft_mesh(p_mesh); -} - -AABB BulletPhysicsServer::soft_body_get_bounds(RID p_body) const { - SoftBodyBullet *body = soft_body_owner.get(p_body); - ERR_FAIL_COND_V(!body, AABB()); - - return body->get_bounds(); -} - -void BulletPhysicsServer3D::soft_body_set_collision_layer(RID p_body, uint32_t p_layer) { - SoftBodyBullet *body = soft_body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - - body->set_collision_layer(p_layer); -} - -uint32_t BulletPhysicsServer3D::soft_body_get_collision_layer(RID p_body) const { - const SoftBodyBullet *body = soft_body_owner.get_or_null(p_body); - ERR_FAIL_COND_V(!body, 0); - - return body->get_collision_layer(); -} - -void BulletPhysicsServer3D::soft_body_set_collision_mask(RID p_body, uint32_t p_mask) { - SoftBodyBullet *body = soft_body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - - body->set_collision_mask(p_mask); -} - -uint32_t BulletPhysicsServer3D::soft_body_get_collision_mask(RID p_body) const { - const SoftBodyBullet *body = soft_body_owner.get_or_null(p_body); - ERR_FAIL_COND_V(!body, 0); - - return body->get_collision_mask(); -} - -void BulletPhysicsServer3D::soft_body_add_collision_exception(RID p_body, RID p_body_b) { - SoftBodyBullet *body = soft_body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - - CollisionObjectBullet *other_body = rigid_body_owner.get_or_null(p_body_b); - if (!other_body) { - other_body = soft_body_owner.get_or_null(p_body_b); - } - ERR_FAIL_COND(!other_body); - - body->add_collision_exception(other_body); -} - -void BulletPhysicsServer3D::soft_body_remove_collision_exception(RID p_body, RID p_body_b) { - SoftBodyBullet *body = soft_body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - - CollisionObjectBullet *other_body = rigid_body_owner.get_or_null(p_body_b); - if (!other_body) { - other_body = soft_body_owner.get_or_null(p_body_b); - } - ERR_FAIL_COND(!other_body); - - body->remove_collision_exception(other_body); -} - -void BulletPhysicsServer3D::soft_body_get_collision_exceptions(RID p_body, List<RID> *p_exceptions) { - SoftBodyBullet *body = soft_body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - for (int i = 0; i < body->get_exceptions().size(); i++) { - p_exceptions->push_back(body->get_exceptions()[i]); - } -} - -void BulletPhysicsServer3D::soft_body_set_state(RID p_body, BodyState p_state, const Variant &p_variant) { - // FIXME: Must be implemented. - WARN_PRINT("soft_body_state is not implemented yet in Bullet backend."); -} - -Variant BulletPhysicsServer3D::soft_body_get_state(RID p_body, BodyState p_state) const { - // FIXME: Must be implemented. - WARN_PRINT("soft_body_state is not implemented yet in Bullet backend."); - return Variant(); -} - -void BulletPhysicsServer3D::soft_body_set_transform(RID p_body, const Transform3D &p_transform) { - SoftBodyBullet *body = soft_body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - - body->set_soft_transform(p_transform); -} - -void BulletPhysicsServer3D::soft_body_set_ray_pickable(RID p_body, bool p_enable) { - SoftBodyBullet *body = soft_body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - body->set_ray_pickable(p_enable); -} - -void BulletPhysicsServer3D::soft_body_set_simulation_precision(RID p_body, int p_simulation_precision) { - SoftBodyBullet *body = soft_body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - body->set_simulation_precision(p_simulation_precision); -} - -int BulletPhysicsServer3D::soft_body_get_simulation_precision(RID p_body) const { - SoftBodyBullet *body = soft_body_owner.get_or_null(p_body); - ERR_FAIL_COND_V(!body, 0.f); - return body->get_simulation_precision(); -} - -void BulletPhysicsServer3D::soft_body_set_total_mass(RID p_body, real_t p_total_mass) { - SoftBodyBullet *body = soft_body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - body->set_total_mass(p_total_mass); -} - -real_t BulletPhysicsServer3D::soft_body_get_total_mass(RID p_body) const { - SoftBodyBullet *body = soft_body_owner.get_or_null(p_body); - ERR_FAIL_COND_V(!body, 0.f); - return body->get_total_mass(); -} - -void BulletPhysicsServer3D::soft_body_set_linear_stiffness(RID p_body, real_t p_stiffness) const { - SoftBodyBullet *body = soft_body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - body->set_linear_stiffness(p_stiffness); -} - -real_t BulletPhysicsServer3D::soft_body_get_linear_stiffness(RID p_body) { - SoftBodyBullet *body = soft_body_owner.get_or_null(p_body); - ERR_FAIL_COND_V(!body, 0.f); - return body->get_linear_stiffness(); -} - -void BulletPhysicsServer3D::soft_body_set_pressure_coefficient(RID p_body, real_t p_pressure_coefficient) { - SoftBodyBullet *body = soft_body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - body->set_pressure_coefficient(p_pressure_coefficient); -} - -real_t BulletPhysicsServer3D::soft_body_get_pressure_coefficient(RID p_body) const { - SoftBodyBullet *body = soft_body_owner.get_or_null(p_body); - ERR_FAIL_COND_V(!body, 0.f); - return body->get_pressure_coefficient(); -} - -void BulletPhysicsServer3D::soft_body_set_damping_coefficient(RID p_body, real_t p_damping_coefficient) { - SoftBodyBullet *body = soft_body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - body->set_damping_coefficient(p_damping_coefficient); -} - -real_t BulletPhysicsServer3D::soft_body_get_damping_coefficient(RID p_body) const { - SoftBodyBullet *body = soft_body_owner.get_or_null(p_body); - ERR_FAIL_COND_V(!body, 0.f); - return body->get_damping_coefficient(); -} - -void BulletPhysicsServer3D::soft_body_set_drag_coefficient(RID p_body, real_t p_drag_coefficient) { - SoftBodyBullet *body = soft_body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - body->set_drag_coefficient(p_drag_coefficient); -} - -real_t BulletPhysicsServer3D::soft_body_get_drag_coefficient(RID p_body) const { - SoftBodyBullet *body = soft_body_owner.get_or_null(p_body); - ERR_FAIL_COND_V(!body, 0.f); - return body->get_drag_coefficient(); -} - -void BulletPhysicsServer3D::soft_body_move_point(RID p_body, int p_point_index, const Vector3 &p_global_position) { - SoftBodyBullet *body = soft_body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - body->set_node_position(p_point_index, p_global_position); -} - -Vector3 BulletPhysicsServer3D::soft_body_get_point_global_position(RID p_body, int p_point_index) const { - SoftBodyBullet *body = soft_body_owner.get_or_null(p_body); - ERR_FAIL_COND_V(!body, Vector3(0., 0., 0.)); - Vector3 pos; - body->get_node_position(p_point_index, pos); - return pos; -} - -void BulletPhysicsServer3D::soft_body_remove_all_pinned_points(RID p_body) { - SoftBodyBullet *body = soft_body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - body->reset_all_node_mass(); -} - -void BulletPhysicsServer3D::soft_body_pin_point(RID p_body, int p_point_index, bool p_pin) { - SoftBodyBullet *body = soft_body_owner.get_or_null(p_body); - ERR_FAIL_COND(!body); - body->set_node_mass(p_point_index, p_pin ? 0 : 1); -} - -bool BulletPhysicsServer3D::soft_body_is_point_pinned(RID p_body, int p_point_index) const { - SoftBodyBullet *body = soft_body_owner.get_or_null(p_body); - ERR_FAIL_COND_V(!body, 0.f); - return body->get_node_mass(p_point_index); -} - -PhysicsServer3D::JointType BulletPhysicsServer3D::joint_get_type(RID p_joint) const { - JointBullet *joint = joint_owner.get_or_null(p_joint); - ERR_FAIL_COND_V(!joint, JOINT_PIN); - return joint->get_type(); -} - -void BulletPhysicsServer3D::joint_set_solver_priority(RID p_joint, int p_priority) { - // Joint priority not supported by bullet -} - -int BulletPhysicsServer3D::joint_get_solver_priority(RID p_joint) const { - // Joint priority not supported by bullet - return 0; -} - -void BulletPhysicsServer3D::joint_disable_collisions_between_bodies(RID p_joint, const bool p_disable) { - JointBullet *joint = joint_owner.get_or_null(p_joint); - ERR_FAIL_COND(!joint); - - joint->disable_collisions_between_bodies(p_disable); -} - -bool BulletPhysicsServer3D::joint_is_disabled_collisions_between_bodies(RID p_joint) const { - JointBullet *joint(joint_owner.get_or_null(p_joint)); - ERR_FAIL_COND_V(!joint, false); - - return joint->is_disabled_collisions_between_bodies(); -} - -RID BulletPhysicsServer3D::joint_create_pin(RID p_body_A, const Vector3 &p_local_A, RID p_body_B, const Vector3 &p_local_B) { - RigidBodyBullet *body_A = rigid_body_owner.get_or_null(p_body_A); - ERR_FAIL_COND_V(!body_A, RID()); - - JointAssertSpace(body_A, "A", RID()); - - RigidBodyBullet *body_B = nullptr; - if (p_body_B.is_valid()) { - body_B = rigid_body_owner.get_or_null(p_body_B); - JointAssertSpace(body_B, "B", RID()); - JointAssertSameSpace(body_A, body_B, RID()); - } - - ERR_FAIL_COND_V(body_A == body_B, RID()); - - JointBullet *joint = bulletnew(PinJointBullet(body_A, p_local_A, body_B, p_local_B)); - AddJointToSpace(body_A, joint); - - CreateThenReturnRID(joint_owner, joint); -} - -void BulletPhysicsServer3D::pin_joint_set_param(RID p_joint, PinJointParam p_param, real_t p_value) { - JointBullet *joint = joint_owner.get_or_null(p_joint); - ERR_FAIL_COND(!joint); - ERR_FAIL_COND(joint->get_type() != JOINT_PIN); - PinJointBullet *pin_joint = static_cast<PinJointBullet *>(joint); - pin_joint->set_param(p_param, p_value); -} - -real_t BulletPhysicsServer3D::pin_joint_get_param(RID p_joint, PinJointParam p_param) const { - JointBullet *joint = joint_owner.get_or_null(p_joint); - ERR_FAIL_COND_V(!joint, 0); - ERR_FAIL_COND_V(joint->get_type() != JOINT_PIN, 0); - PinJointBullet *pin_joint = static_cast<PinJointBullet *>(joint); - return pin_joint->get_param(p_param); -} - -void BulletPhysicsServer3D::pin_joint_set_local_a(RID p_joint, const Vector3 &p_A) { - JointBullet *joint = joint_owner.get_or_null(p_joint); - ERR_FAIL_COND(!joint); - ERR_FAIL_COND(joint->get_type() != JOINT_PIN); - PinJointBullet *pin_joint = static_cast<PinJointBullet *>(joint); - pin_joint->setPivotInA(p_A); -} - -Vector3 BulletPhysicsServer3D::pin_joint_get_local_a(RID p_joint) const { - JointBullet *joint = joint_owner.get_or_null(p_joint); - ERR_FAIL_COND_V(!joint, Vector3()); - ERR_FAIL_COND_V(joint->get_type() != JOINT_PIN, Vector3()); - PinJointBullet *pin_joint = static_cast<PinJointBullet *>(joint); - return pin_joint->getPivotInA(); -} - -void BulletPhysicsServer3D::pin_joint_set_local_b(RID p_joint, const Vector3 &p_B) { - JointBullet *joint = joint_owner.get_or_null(p_joint); - ERR_FAIL_COND(!joint); - ERR_FAIL_COND(joint->get_type() != JOINT_PIN); - PinJointBullet *pin_joint = static_cast<PinJointBullet *>(joint); - pin_joint->setPivotInB(p_B); -} - -Vector3 BulletPhysicsServer3D::pin_joint_get_local_b(RID p_joint) const { - JointBullet *joint = joint_owner.get_or_null(p_joint); - ERR_FAIL_COND_V(!joint, Vector3()); - ERR_FAIL_COND_V(joint->get_type() != JOINT_PIN, Vector3()); - PinJointBullet *pin_joint = static_cast<PinJointBullet *>(joint); - return pin_joint->getPivotInB(); -} - -RID BulletPhysicsServer3D::joint_create_hinge(RID p_body_A, const Transform3D &p_hinge_A, RID p_body_B, const Transform3D &p_hinge_B) { - RigidBodyBullet *body_A = rigid_body_owner.get_or_null(p_body_A); - ERR_FAIL_COND_V(!body_A, RID()); - JointAssertSpace(body_A, "A", RID()); - - RigidBodyBullet *body_B = nullptr; - if (p_body_B.is_valid()) { - body_B = rigid_body_owner.get_or_null(p_body_B); - JointAssertSpace(body_B, "B", RID()); - JointAssertSameSpace(body_A, body_B, RID()); - } - - ERR_FAIL_COND_V(body_A == body_B, RID()); - - JointBullet *joint = bulletnew(HingeJointBullet(body_A, body_B, p_hinge_A, p_hinge_B)); - AddJointToSpace(body_A, joint); - - CreateThenReturnRID(joint_owner, joint); -} - -RID BulletPhysicsServer3D::joint_create_hinge_simple(RID p_body_A, const Vector3 &p_pivot_A, const Vector3 &p_axis_A, RID p_body_B, const Vector3 &p_pivot_B, const Vector3 &p_axis_B) { - RigidBodyBullet *body_A = rigid_body_owner.get_or_null(p_body_A); - ERR_FAIL_COND_V(!body_A, RID()); - JointAssertSpace(body_A, "A", RID()); - - RigidBodyBullet *body_B = nullptr; - if (p_body_B.is_valid()) { - body_B = rigid_body_owner.get_or_null(p_body_B); - JointAssertSpace(body_B, "B", RID()); - JointAssertSameSpace(body_A, body_B, RID()); - } - - ERR_FAIL_COND_V(body_A == body_B, RID()); - - JointBullet *joint = bulletnew(HingeJointBullet(body_A, body_B, p_pivot_A, p_pivot_B, p_axis_A, p_axis_B)); - AddJointToSpace(body_A, joint); - - CreateThenReturnRID(joint_owner, joint); -} - -void BulletPhysicsServer3D::hinge_joint_set_param(RID p_joint, HingeJointParam p_param, real_t p_value) { - JointBullet *joint = joint_owner.get_or_null(p_joint); - ERR_FAIL_COND(!joint); - ERR_FAIL_COND(joint->get_type() != JOINT_HINGE); - HingeJointBullet *hinge_joint = static_cast<HingeJointBullet *>(joint); - hinge_joint->set_param(p_param, p_value); -} - -real_t BulletPhysicsServer3D::hinge_joint_get_param(RID p_joint, HingeJointParam p_param) const { - JointBullet *joint = joint_owner.get_or_null(p_joint); - ERR_FAIL_COND_V(!joint, 0); - ERR_FAIL_COND_V(joint->get_type() != JOINT_HINGE, 0); - HingeJointBullet *hinge_joint = static_cast<HingeJointBullet *>(joint); - return hinge_joint->get_param(p_param); -} - -void BulletPhysicsServer3D::hinge_joint_set_flag(RID p_joint, HingeJointFlag p_flag, bool p_value) { - JointBullet *joint = joint_owner.get_or_null(p_joint); - ERR_FAIL_COND(!joint); - ERR_FAIL_COND(joint->get_type() != JOINT_HINGE); - HingeJointBullet *hinge_joint = static_cast<HingeJointBullet *>(joint); - hinge_joint->set_flag(p_flag, p_value); -} - -bool BulletPhysicsServer3D::hinge_joint_get_flag(RID p_joint, HingeJointFlag p_flag) const { - JointBullet *joint = joint_owner.get_or_null(p_joint); - ERR_FAIL_COND_V(!joint, false); - ERR_FAIL_COND_V(joint->get_type() != JOINT_HINGE, false); - HingeJointBullet *hinge_joint = static_cast<HingeJointBullet *>(joint); - return hinge_joint->get_flag(p_flag); -} - -RID BulletPhysicsServer3D::joint_create_slider(RID p_body_A, const Transform3D &p_local_frame_A, RID p_body_B, const Transform3D &p_local_frame_B) { - RigidBodyBullet *body_A = rigid_body_owner.get_or_null(p_body_A); - ERR_FAIL_COND_V(!body_A, RID()); - JointAssertSpace(body_A, "A", RID()); - - RigidBodyBullet *body_B = nullptr; - if (p_body_B.is_valid()) { - body_B = rigid_body_owner.get_or_null(p_body_B); - JointAssertSpace(body_B, "B", RID()); - JointAssertSameSpace(body_A, body_B, RID()); - } - - ERR_FAIL_COND_V(body_A == body_B, RID()); - - JointBullet *joint = bulletnew(SliderJointBullet(body_A, body_B, p_local_frame_A, p_local_frame_B)); - AddJointToSpace(body_A, joint); - - CreateThenReturnRID(joint_owner, joint); -} - -void BulletPhysicsServer3D::slider_joint_set_param(RID p_joint, SliderJointParam p_param, real_t p_value) { - JointBullet *joint = joint_owner.get_or_null(p_joint); - ERR_FAIL_COND(!joint); - ERR_FAIL_COND(joint->get_type() != JOINT_SLIDER); - SliderJointBullet *slider_joint = static_cast<SliderJointBullet *>(joint); - slider_joint->set_param(p_param, p_value); -} - -real_t BulletPhysicsServer3D::slider_joint_get_param(RID p_joint, SliderJointParam p_param) const { - JointBullet *joint = joint_owner.get_or_null(p_joint); - ERR_FAIL_COND_V(!joint, 0); - ERR_FAIL_COND_V(joint->get_type() != JOINT_SLIDER, 0); - SliderJointBullet *slider_joint = static_cast<SliderJointBullet *>(joint); - return slider_joint->get_param(p_param); -} - -RID BulletPhysicsServer3D::joint_create_cone_twist(RID p_body_A, const Transform3D &p_local_frame_A, RID p_body_B, const Transform3D &p_local_frame_B) { - RigidBodyBullet *body_A = rigid_body_owner.get_or_null(p_body_A); - ERR_FAIL_COND_V(!body_A, RID()); - JointAssertSpace(body_A, "A", RID()); - - RigidBodyBullet *body_B = nullptr; - if (p_body_B.is_valid()) { - body_B = rigid_body_owner.get_or_null(p_body_B); - JointAssertSpace(body_B, "B", RID()); - JointAssertSameSpace(body_A, body_B, RID()); - } - - JointBullet *joint = bulletnew(ConeTwistJointBullet(body_A, body_B, p_local_frame_A, p_local_frame_B)); - AddJointToSpace(body_A, joint); - - CreateThenReturnRID(joint_owner, joint); -} - -void BulletPhysicsServer3D::cone_twist_joint_set_param(RID p_joint, ConeTwistJointParam p_param, real_t p_value) { - JointBullet *joint = joint_owner.get_or_null(p_joint); - ERR_FAIL_COND(!joint); - ERR_FAIL_COND(joint->get_type() != JOINT_CONE_TWIST); - ConeTwistJointBullet *coneTwist_joint = static_cast<ConeTwistJointBullet *>(joint); - coneTwist_joint->set_param(p_param, p_value); -} - -real_t BulletPhysicsServer3D::cone_twist_joint_get_param(RID p_joint, ConeTwistJointParam p_param) const { - JointBullet *joint = joint_owner.get_or_null(p_joint); - ERR_FAIL_COND_V(!joint, 0.); - ERR_FAIL_COND_V(joint->get_type() != JOINT_CONE_TWIST, 0.); - ConeTwistJointBullet *coneTwist_joint = static_cast<ConeTwistJointBullet *>(joint); - return coneTwist_joint->get_param(p_param); -} - -RID BulletPhysicsServer3D::joint_create_generic_6dof(RID p_body_A, const Transform3D &p_local_frame_A, RID p_body_B, const Transform3D &p_local_frame_B) { - RigidBodyBullet *body_A = rigid_body_owner.get_or_null(p_body_A); - ERR_FAIL_COND_V(!body_A, RID()); - JointAssertSpace(body_A, "A", RID()); - - RigidBodyBullet *body_B = nullptr; - if (p_body_B.is_valid()) { - body_B = rigid_body_owner.get_or_null(p_body_B); - JointAssertSpace(body_B, "B", RID()); - JointAssertSameSpace(body_A, body_B, RID()); - } - - ERR_FAIL_COND_V(body_A == body_B, RID()); - - JointBullet *joint = bulletnew(Generic6DOFJointBullet(body_A, body_B, p_local_frame_A, p_local_frame_B)); - AddJointToSpace(body_A, joint); - - CreateThenReturnRID(joint_owner, joint); -} - -void BulletPhysicsServer3D::generic_6dof_joint_set_param(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisParam p_param, real_t p_value) { - JointBullet *joint = joint_owner.get_or_null(p_joint); - ERR_FAIL_COND(!joint); - ERR_FAIL_COND(joint->get_type() != JOINT_6DOF); - Generic6DOFJointBullet *generic_6dof_joint = static_cast<Generic6DOFJointBullet *>(joint); - generic_6dof_joint->set_param(p_axis, p_param, p_value); -} - -real_t BulletPhysicsServer3D::generic_6dof_joint_get_param(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisParam p_param) { - JointBullet *joint = joint_owner.get_or_null(p_joint); - ERR_FAIL_COND_V(!joint, 0); - ERR_FAIL_COND_V(joint->get_type() != JOINT_6DOF, 0); - Generic6DOFJointBullet *generic_6dof_joint = static_cast<Generic6DOFJointBullet *>(joint); - return generic_6dof_joint->get_param(p_axis, p_param); -} - -void BulletPhysicsServer3D::generic_6dof_joint_set_flag(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisFlag p_flag, bool p_enable) { - JointBullet *joint = joint_owner.get_or_null(p_joint); - ERR_FAIL_COND(!joint); - ERR_FAIL_COND(joint->get_type() != JOINT_6DOF); - Generic6DOFJointBullet *generic_6dof_joint = static_cast<Generic6DOFJointBullet *>(joint); - generic_6dof_joint->set_flag(p_axis, p_flag, p_enable); -} - -bool BulletPhysicsServer3D::generic_6dof_joint_get_flag(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisFlag p_flag) { - JointBullet *joint = joint_owner.get_or_null(p_joint); - ERR_FAIL_COND_V(!joint, false); - ERR_FAIL_COND_V(joint->get_type() != JOINT_6DOF, false); - Generic6DOFJointBullet *generic_6dof_joint = static_cast<Generic6DOFJointBullet *>(joint); - return generic_6dof_joint->get_flag(p_axis, p_flag); -} - -void BulletPhysicsServer3D::free(RID p_rid) { - if (shape_owner.owns(p_rid)) { - ShapeBullet *shape = shape_owner.get_or_null(p_rid); - - // Notify the shape is configured - for (const KeyValue<ShapeOwnerBullet *, int> &element : shape->get_owners()) { - static_cast<ShapeOwnerBullet *>(element.key)->remove_shape_full(shape); - } - - shape_owner.free(p_rid); - bulletdelete(shape); - } else if (rigid_body_owner.owns(p_rid)) { - RigidBodyBullet *body = rigid_body_owner.get_or_null(p_rid); - - body->set_space(nullptr); - - body->remove_all_shapes(true, true); - - rigid_body_owner.free(p_rid); - bulletdelete(body); - - } else if (soft_body_owner.owns(p_rid)) { - SoftBodyBullet *body = soft_body_owner.get_or_null(p_rid); - - body->set_space(nullptr); - - soft_body_owner.free(p_rid); - bulletdelete(body); - - } else if (area_owner.owns(p_rid)) { - AreaBullet *area = area_owner.get_or_null(p_rid); - - area->set_space(nullptr); - - area->remove_all_shapes(true, true); - - area_owner.free(p_rid); - bulletdelete(area); - - } else if (joint_owner.owns(p_rid)) { - JointBullet *joint = joint_owner.get_or_null(p_rid); - joint->destroy_internal_constraint(); - joint_owner.free(p_rid); - bulletdelete(joint); - - } else if (space_owner.owns(p_rid)) { - SpaceBullet *space = space_owner.get_or_null(p_rid); - - space->remove_all_collision_objects(); - - space_set_active(p_rid, false); - space_owner.free(p_rid); - bulletdelete(space); - } else { - ERR_FAIL_MSG("Invalid ID."); - } -} - -void BulletPhysicsServer3D::init() { - BulletPhysicsDirectBodyState3D::initSingleton(); -} - -void BulletPhysicsServer3D::step(real_t p_deltaTime) { - if (!active) { - return; - } - - BulletPhysicsDirectBodyState3D::singleton_setDeltaTime(p_deltaTime); - - for (int i = 0; i < active_spaces_count; ++i) { - active_spaces[i]->step(p_deltaTime); - } -} - -void BulletPhysicsServer3D::flush_queries() { - if (!active) { - return; - } - - for (int i = 0; i < active_spaces_count; ++i) { - active_spaces[i]->flush_queries(); - } -} - -void BulletPhysicsServer3D::finish() { - BulletPhysicsDirectBodyState3D::destroySingleton(); -} - -int BulletPhysicsServer3D::get_process_info(ProcessInfo p_info) { - return 0; -} - -SpaceBullet *BulletPhysicsServer3D::get_space(RID p_rid) const { - ERR_FAIL_COND_V_MSG(space_owner.owns(p_rid) == false, nullptr, "The RID is not valid."); - return space_owner.get_or_null(p_rid); -} - -ShapeBullet *BulletPhysicsServer3D::get_shape(RID p_rid) const { - ERR_FAIL_COND_V_MSG(shape_owner.owns(p_rid) == false, nullptr, "The RID is not valid."); - return shape_owner.get_or_null(p_rid); -} - -CollisionObjectBullet *BulletPhysicsServer3D::get_collision_object(RID p_object) const { - if (rigid_body_owner.owns(p_object)) { - return rigid_body_owner.get_or_null(p_object); - } - if (area_owner.owns(p_object)) { - return area_owner.get_or_null(p_object); - } - if (soft_body_owner.owns(p_object)) { - return soft_body_owner.get_or_null(p_object); - } - ERR_FAIL_V_MSG(nullptr, "The RID is no valid."); -} - -RigidCollisionObjectBullet *BulletPhysicsServer3D::get_rigid_collision_object(RID p_object) const { - if (rigid_body_owner.owns(p_object)) { - return rigid_body_owner.get_or_null(p_object); - } - if (area_owner.owns(p_object)) { - return area_owner.get_or_null(p_object); - } - ERR_FAIL_V_MSG(nullptr, "The RID is no valid."); -} - -JointBullet *BulletPhysicsServer3D::get_joint(RID p_rid) const { - ERR_FAIL_COND_V_MSG(joint_owner.owns(p_rid) == false, nullptr, "The RID is not valid."); - return joint_owner.get_or_null(p_rid); -} diff --git a/modules/bullet/bullet_physics_server.h b/modules/bullet/bullet_physics_server.h deleted file mode 100644 index 06a6f62bcd..0000000000 --- a/modules/bullet/bullet_physics_server.h +++ /dev/null @@ -1,394 +0,0 @@ -/*************************************************************************/ -/* bullet_physics_server.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* 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. */ -/*************************************************************************/ - -#ifndef BULLET_PHYSICS_SERVER_H -#define BULLET_PHYSICS_SERVER_H - -#include "area_bullet.h" -#include "core/templates/rid.h" -#include "core/templates/rid_owner.h" -#include "joint_bullet.h" -#include "rigid_body_bullet.h" -#include "servers/physics_server_3d.h" -#include "shape_bullet.h" -#include "soft_body_bullet.h" -#include "space_bullet.h" - -class BulletPhysicsServer3D : public PhysicsServer3D { - GDCLASS(BulletPhysicsServer3D, PhysicsServer3D); - - friend class BulletPhysicsDirectSpaceState; - - bool active = true; - char active_spaces_count = 0; - Vector<SpaceBullet *> active_spaces; - - mutable RID_PtrOwner<SpaceBullet> space_owner; - mutable RID_PtrOwner<ShapeBullet> shape_owner; - mutable RID_PtrOwner<AreaBullet> area_owner; - mutable RID_PtrOwner<RigidBodyBullet> rigid_body_owner; - mutable RID_PtrOwner<SoftBodyBullet> soft_body_owner; - mutable RID_PtrOwner<JointBullet> joint_owner; - -protected: - static void _bind_methods(); - -public: - BulletPhysicsServer3D(); - ~BulletPhysicsServer3D(); - - _FORCE_INLINE_ RID_PtrOwner<SpaceBullet> *get_space_owner() { - return &space_owner; - } - _FORCE_INLINE_ RID_PtrOwner<ShapeBullet> *get_shape_owner() { - return &shape_owner; - } - _FORCE_INLINE_ RID_PtrOwner<AreaBullet> *get_area_owner() { - return &area_owner; - } - _FORCE_INLINE_ RID_PtrOwner<RigidBodyBullet> *get_rigid_body_owner() { - return &rigid_body_owner; - } - _FORCE_INLINE_ RID_PtrOwner<SoftBodyBullet> *get_soft_body_owner() { - return &soft_body_owner; - } - _FORCE_INLINE_ RID_PtrOwner<JointBullet> *get_joint_owner() { - return &joint_owner; - } - - /* SHAPE API */ - virtual RID shape_create(ShapeType p_shape) override; - virtual void shape_set_data(RID p_shape, const Variant &p_data) override; - virtual ShapeType shape_get_type(RID p_shape) const override; - virtual Variant shape_get_data(RID p_shape) const override; - - virtual void shape_set_margin(RID p_shape, real_t p_margin) override; - virtual real_t shape_get_margin(RID p_shape) const override; - - /// Not supported - virtual void shape_set_custom_solver_bias(RID p_shape, real_t p_bias) override; - /// Not supported - virtual real_t shape_get_custom_solver_bias(RID p_shape) const override; - - /* SPACE API */ - - virtual RID space_create() override; - virtual void space_set_active(RID p_space, bool p_active) override; - virtual bool space_is_active(RID p_space) const override; - - /// Not supported - virtual void space_set_param(RID p_space, SpaceParameter p_param, real_t p_value) override; - /// Not supported - virtual real_t space_get_param(RID p_space, SpaceParameter p_param) const override; - - virtual PhysicsDirectSpaceState3D *space_get_direct_state(RID p_space) override; - - virtual void space_set_debug_contacts(RID p_space, int p_max_contacts) override; - virtual Vector<Vector3> space_get_contacts(RID p_space) const override; - virtual int space_get_contact_count(RID p_space) const override; - - /* AREA API */ - - /// Bullet Physics Engine not support "Area", this must be handled by the game developer in another way. - /// Since godot Physics use the concept of area even to define the main world, the API area_set_param is used to set initial physics world information. - /// The API area_set_param is a bit hacky, and allow Godot to set some parameters on Bullet's world, a different use print a warning to console. - /// All other APIs returns a warning message if used - - virtual RID area_create() override; - - virtual void area_set_space(RID p_area, RID p_space) override; - - virtual RID area_get_space(RID p_area) const override; - - virtual void area_set_space_override_mode(RID p_area, AreaSpaceOverrideMode p_mode) override; - virtual AreaSpaceOverrideMode area_get_space_override_mode(RID p_area) const override; - - virtual void area_add_shape(RID p_area, RID p_shape, const Transform3D &p_transform = Transform3D(), bool p_disabled = false) override; - virtual void area_set_shape(RID p_area, int p_shape_idx, RID p_shape) override; - virtual void area_set_shape_transform(RID p_area, int p_shape_idx, const Transform3D &p_transform) override; - virtual int area_get_shape_count(RID p_area) const override; - virtual RID area_get_shape(RID p_area, int p_shape_idx) const override; - virtual Transform3D area_get_shape_transform(RID p_area, int p_shape_idx) const override; - virtual void area_remove_shape(RID p_area, int p_shape_idx) override; - virtual void area_clear_shapes(RID p_area) override; - virtual void area_set_shape_disabled(RID p_area, int p_shape_idx, bool p_disabled) override; - virtual void area_attach_object_instance_id(RID p_area, ObjectID p_id) override; - virtual ObjectID area_get_object_instance_id(RID p_area) const override; - - /// If you pass as p_area the SpaceBullet you can set some parameters as specified below - /// AREA_PARAM_GRAVITY - /// AREA_PARAM_GRAVITY_VECTOR - /// Otherwise you can set area parameters - virtual void area_set_param(RID p_area, AreaParameter p_param, const Variant &p_value) override; - virtual Variant area_get_param(RID p_area, AreaParameter p_param) const override; - - virtual void area_set_transform(RID p_area, const Transform3D &p_transform) override; - virtual Transform3D area_get_transform(RID p_area) const override; - - virtual void area_set_collision_mask(RID p_area, uint32_t p_mask) override; - virtual void area_set_collision_layer(RID p_area, uint32_t p_layer) override; - - virtual void area_set_monitorable(RID p_area, bool p_monitorable) override; - virtual void area_set_monitor_callback(RID p_area, const Callable &p_callback) override; - virtual void area_set_area_monitor_callback(RID p_area, const Callable &p_callback) override; - virtual void area_set_ray_pickable(RID p_area, bool p_enable) override; - - /* RIGID BODY API */ - - virtual RID body_create(BodyMode p_mode = BODY_MODE_DYNAMIC, bool p_init_sleeping = false) override; - - virtual void body_set_space(RID p_body, RID p_space) override; - virtual RID body_get_space(RID p_body) const override; - - virtual void body_set_mode(RID p_body, BodyMode p_mode) override; - virtual BodyMode body_get_mode(RID p_body) const override; - - virtual void body_add_shape(RID p_body, RID p_shape, const Transform3D &p_transform = Transform3D(), bool p_disabled = false) override; - // Not supported, Please remove and add new shape - virtual void body_set_shape(RID p_body, int p_shape_idx, RID p_shape) override; - virtual void body_set_shape_transform(RID p_body, int p_shape_idx, const Transform3D &p_transform) override; - - virtual int body_get_shape_count(RID p_body) const override; - virtual RID body_get_shape(RID p_body, int p_shape_idx) const override; - virtual Transform3D body_get_shape_transform(RID p_body, int p_shape_idx) const override; - - virtual void body_set_shape_disabled(RID p_body, int p_shape_idx, bool p_disabled) override; - - virtual void body_remove_shape(RID p_body, int p_shape_idx) override; - virtual void body_clear_shapes(RID p_body) override; - - // Used for Rigid and Soft Bodies - virtual void body_attach_object_instance_id(RID p_body, ObjectID p_id) override; - virtual ObjectID body_get_object_instance_id(RID p_body) const override; - - virtual void body_set_enable_continuous_collision_detection(RID p_body, bool p_enable) override; - virtual bool body_is_continuous_collision_detection_enabled(RID p_body) const override; - - virtual void body_set_collision_layer(RID p_body, uint32_t p_layer) override; - virtual uint32_t body_get_collision_layer(RID p_body) const override; - - virtual void body_set_collision_mask(RID p_body, uint32_t p_mask) override; - virtual uint32_t body_get_collision_mask(RID p_body) const override; - - /// This is not supported by physics server - virtual void body_set_user_flags(RID p_body, uint32_t p_flags) override; - /// This is not supported by physics server - virtual uint32_t body_get_user_flags(RID p_body) const override; - - virtual void body_set_param(RID p_body, BodyParameter p_param, real_t p_value) override; - virtual real_t body_get_param(RID p_body, BodyParameter p_param) const override; - - virtual void body_set_kinematic_safe_margin(RID p_body, real_t p_margin) override; - virtual real_t body_get_kinematic_safe_margin(RID p_body) const override; - - virtual void body_set_state(RID p_body, BodyState p_state, const Variant &p_variant) override; - virtual Variant body_get_state(RID p_body, BodyState p_state) const override; - - virtual void body_set_applied_force(RID p_body, const Vector3 &p_force) override; - virtual Vector3 body_get_applied_force(RID p_body) const override; - - virtual void body_set_applied_torque(RID p_body, const Vector3 &p_torque) override; - virtual Vector3 body_get_applied_torque(RID p_body) const override; - - virtual void body_add_central_force(RID p_body, const Vector3 &p_force) override; - virtual void body_add_force(RID p_body, const Vector3 &p_force, const Vector3 &p_position = Vector3()) override; - virtual void body_add_torque(RID p_body, const Vector3 &p_torque) override; - - virtual void body_apply_central_impulse(RID p_body, const Vector3 &p_impulse) override; - virtual void body_apply_impulse(RID p_body, const Vector3 &p_impulse, const Vector3 &p_position = Vector3()) override; - virtual void body_apply_torque_impulse(RID p_body, const Vector3 &p_impulse) override; - virtual void body_set_axis_velocity(RID p_body, const Vector3 &p_axis_velocity) override; - - virtual void body_set_axis_lock(RID p_body, BodyAxis p_axis, bool p_lock) override; - virtual bool body_is_axis_locked(RID p_body, BodyAxis p_axis) const override; - - virtual void body_add_collision_exception(RID p_body, RID p_body_b) override; - virtual void body_remove_collision_exception(RID p_body, RID p_body_b) override; - virtual void body_get_collision_exceptions(RID p_body, List<RID> *p_exceptions) override; - - virtual void body_set_max_contacts_reported(RID p_body, int p_contacts) override; - virtual int body_get_max_contacts_reported(RID p_body) const override; - - virtual void body_set_contacts_reported_depth_threshold(RID p_body, real_t p_threshold) override; - virtual real_t body_get_contacts_reported_depth_threshold(RID p_body) const override; - - virtual void body_set_omit_force_integration(RID p_body, bool p_omit) override; - virtual bool body_is_omitting_force_integration(RID p_body) const override; - - virtual void body_set_force_integration_callback(RID p_body, const Callable &p_callable, const Variant &p_udata = Variant()) override; - - virtual void body_set_ray_pickable(RID p_body, bool p_enable) override; - - // this function only works on physics process, errors and returns null otherwise - virtual PhysicsDirectBodyState3D *body_get_direct_state(RID p_body) override; - - virtual bool body_test_motion(RID p_body, const Transform3D &p_from, const Vector3 &p_motion, bool p_infinite_inertia, MotionResult *r_result = nullptr, bool p_exclude_raycast_shapes = true, const Set<RID> &p_exclude = Set<RID>()) override; - virtual int body_test_ray_separation(RID p_body, const Transform3D &p_transform, bool p_infinite_inertia, Vector3 &r_recover_motion, SeparationResult *r_results, int p_result_max, real_t p_margin = 0.001) override; - - /* SOFT BODY API */ - - virtual RID soft_body_create(bool p_init_sleeping = false) override; - - virtual void soft_body_update_rendering_server(RID p_body, RenderingServerHandler *p_rendering_server_handler) override; - - virtual void soft_body_set_space(RID p_body, RID p_space) override; - virtual RID soft_body_get_space(RID p_body) const override; - - virtual void soft_body_set_mesh(RID p_body, RID p_mesh) override; - - virtual AABB soft_body_get_bounds(RID p_body) const override; - - virtual void soft_body_set_collision_layer(RID p_body, uint32_t p_layer) override; - virtual uint32_t soft_body_get_collision_layer(RID p_body) const override; - - virtual void soft_body_set_collision_mask(RID p_body, uint32_t p_mask) override; - virtual uint32_t soft_body_get_collision_mask(RID p_body) const override; - - virtual void soft_body_add_collision_exception(RID p_body, RID p_body_b) override; - virtual void soft_body_remove_collision_exception(RID p_body, RID p_body_b) override; - virtual void soft_body_get_collision_exceptions(RID p_body, List<RID> *p_exceptions) override; - - virtual void soft_body_set_state(RID p_body, BodyState p_state, const Variant &p_variant) override; - virtual Variant soft_body_get_state(RID p_body, BodyState p_state) const override; - - /// Special function. This function has bad performance - virtual void soft_body_set_transform(RID p_body, const Transform3D &p_transform) override; - - virtual void soft_body_set_ray_pickable(RID p_body, bool p_enable) override; - - virtual void soft_body_set_simulation_precision(RID p_body, int p_simulation_precision) override; - virtual int soft_body_get_simulation_precision(RID p_body) const override; - - virtual void soft_body_set_total_mass(RID p_body, real_t p_total_mass) override; - virtual real_t soft_body_get_total_mass(RID p_body) const override; - - virtual void soft_body_set_linear_stiffness(RID p_body, real_t p_stiffness) override; - virtual real_t soft_body_get_linear_stiffness(RID p_body) const override; - - virtual void soft_body_set_pressure_coefficient(RID p_body, real_t p_pressure_coefficient) override; - virtual real_t soft_body_get_pressure_coefficient(RID p_body) const override; - - virtual void soft_body_set_damping_coefficient(RID p_body, real_t p_damping_coefficient) override; - virtual real_t soft_body_get_damping_coefficient(RID p_body) const override; - - virtual void soft_body_set_drag_coefficient(RID p_body, real_t p_drag_coefficient) override; - virtual real_t soft_body_get_drag_coefficient(RID p_body) const override; - - virtual void soft_body_move_point(RID p_body, int p_point_index, const Vector3 &p_global_position) override; - virtual Vector3 soft_body_get_point_global_position(RID p_body, int p_point_index) const override; - - virtual void soft_body_remove_all_pinned_points(RID p_body) override; - virtual void soft_body_pin_point(RID p_body, int p_point_index, bool p_pin) override; - virtual bool soft_body_is_point_pinned(RID p_body, int p_point_index) const override; - - /* JOINT API */ - - virtual JointType joint_get_type(RID p_joint) const override; - - virtual void joint_set_solver_priority(RID p_joint, int p_priority) override; - virtual int joint_get_solver_priority(RID p_joint) const override; - - virtual void joint_disable_collisions_between_bodies(RID p_joint, const bool p_disable) override; - virtual bool joint_is_disabled_collisions_between_bodies(RID p_joint) const override; - - virtual RID joint_create_pin(RID p_body_A, const Vector3 &p_local_A, RID p_body_B, const Vector3 &p_local_B) override; - - virtual void pin_joint_set_param(RID p_joint, PinJointParam p_param, real_t p_value) override; - virtual real_t pin_joint_get_param(RID p_joint, PinJointParam p_param) const override; - - virtual void pin_joint_set_local_a(RID p_joint, const Vector3 &p_A) override; - virtual Vector3 pin_joint_get_local_a(RID p_joint) const override; - - virtual void pin_joint_set_local_b(RID p_joint, const Vector3 &p_B) override; - virtual Vector3 pin_joint_get_local_b(RID p_joint) const override; - - virtual RID joint_create_hinge(RID p_body_A, const Transform3D &p_hinge_A, RID p_body_B, const Transform3D &p_hinge_B) override; - virtual RID joint_create_hinge_simple(RID p_body_A, const Vector3 &p_pivot_A, const Vector3 &p_axis_A, RID p_body_B, const Vector3 &p_pivot_B, const Vector3 &p_axis_B) override; - - virtual void hinge_joint_set_param(RID p_joint, HingeJointParam p_param, real_t p_value) override; - virtual real_t hinge_joint_get_param(RID p_joint, HingeJointParam p_param) const override; - - virtual void hinge_joint_set_flag(RID p_joint, HingeJointFlag p_flag, bool p_value) override; - virtual bool hinge_joint_get_flag(RID p_joint, HingeJointFlag p_flag) const override; - - /// Reference frame is A - virtual RID joint_create_slider(RID p_body_A, const Transform3D &p_local_frame_A, RID p_body_B, const Transform3D &p_local_frame_B) override; - - virtual void slider_joint_set_param(RID p_joint, SliderJointParam p_param, real_t p_value) override; - virtual real_t slider_joint_get_param(RID p_joint, SliderJointParam p_param) const override; - - /// Reference frame is A - virtual RID joint_create_cone_twist(RID p_body_A, const Transform3D &p_local_frame_A, RID p_body_B, const Transform3D &p_local_frame_B) override; - - virtual void cone_twist_joint_set_param(RID p_joint, ConeTwistJointParam p_param, real_t p_value) override; - virtual real_t cone_twist_joint_get_param(RID p_joint, ConeTwistJointParam p_param) const override; - - /// Reference frame is A - virtual RID joint_create_generic_6dof(RID p_body_A, const Transform3D &p_local_frame_A, RID p_body_B, const Transform3D &p_local_frame_B) override; - - virtual void generic_6dof_joint_set_param(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisParam p_param, real_t p_value) override; - virtual real_t generic_6dof_joint_get_param(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisParam p_param) override; - - virtual void generic_6dof_joint_set_flag(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisFlag p_flag, bool p_enable) override; - virtual bool generic_6dof_joint_get_flag(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisFlag p_flag) override; - - /* MISC */ - - virtual void free(RID p_rid) override; - - virtual void set_active(bool p_active) override { - active = p_active; - } - - static bool singleton_isActive() { - return static_cast<BulletPhysicsServer3D *>(get_singleton())->active; - } - - bool isActive() { - return active; - } - - virtual void init() override; - virtual void step(real_t p_deltaTime) override; - virtual void flush_queries() override; - virtual void finish() override; - - virtual bool is_flushing_queries() const override { return false; } - - virtual int get_process_info(ProcessInfo p_info) override; - - SpaceBullet *get_space(RID p_rid) const; - ShapeBullet *get_shape(RID p_rid) const; - CollisionObjectBullet *get_collision_object(RID p_object) const; - RigidCollisionObjectBullet *get_rigid_collision_object(RID p_object) const; - JointBullet *get_joint(RID p_rid) const; -}; - -#endif // BULLET_PHYSICS_SERVER_H diff --git a/modules/bullet/bullet_types_converter.cpp b/modules/bullet/bullet_types_converter.cpp deleted file mode 100644 index a0698683e8..0000000000 --- a/modules/bullet/bullet_types_converter.cpp +++ /dev/null @@ -1,151 +0,0 @@ -/*************************************************************************/ -/* bullet_types_converter.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* 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 "bullet_types_converter.h" - -// ++ BULLET to GODOT ++++++++++ -void B_TO_G(btVector3 const &inVal, Vector3 &outVal) { - outVal[0] = inVal[0]; - outVal[1] = inVal[1]; - outVal[2] = inVal[2]; -} - -void INVERT_B_TO_G(btVector3 const &inVal, Vector3 &outVal) { - outVal[0] = inVal[0] != 0. ? 1. / inVal[0] : 0.; - outVal[1] = inVal[1] != 0. ? 1. / inVal[1] : 0.; - outVal[2] = inVal[2] != 0. ? 1. / inVal[2] : 0.; -} - -void B_TO_G(btMatrix3x3 const &inVal, Basis &outVal) { - B_TO_G(inVal[0], outVal[0]); - B_TO_G(inVal[1], outVal[1]); - B_TO_G(inVal[2], outVal[2]); -} - -void INVERT_B_TO_G(btMatrix3x3 const &inVal, Basis &outVal) { - INVERT_B_TO_G(inVal[0], outVal[0]); - INVERT_B_TO_G(inVal[1], outVal[1]); - INVERT_B_TO_G(inVal[2], outVal[2]); -} - -void B_TO_G(btTransform const &inVal, Transform3D &outVal) { - B_TO_G(inVal.getBasis(), outVal.basis); - B_TO_G(inVal.getOrigin(), outVal.origin); -} - -// ++ GODOT to BULLET ++++++++++ -void G_TO_B(Vector3 const &inVal, btVector3 &outVal) { - outVal[0] = inVal[0]; - outVal[1] = inVal[1]; - outVal[2] = inVal[2]; -} - -void INVERT_G_TO_B(Vector3 const &inVal, btVector3 &outVal) { - outVal[0] = inVal[0] != 0. ? 1. / inVal[0] : 0.; - outVal[1] = inVal[1] != 0. ? 1. / inVal[1] : 0.; - outVal[2] = inVal[2] != 0. ? 1. / inVal[2] : 0.; -} - -void G_TO_B(Basis const &inVal, btMatrix3x3 &outVal) { - G_TO_B(inVal[0], outVal[0]); - G_TO_B(inVal[1], outVal[1]); - G_TO_B(inVal[2], outVal[2]); -} - -void INVERT_G_TO_B(Basis const &inVal, btMatrix3x3 &outVal) { - INVERT_G_TO_B(inVal[0], outVal[0]); - INVERT_G_TO_B(inVal[1], outVal[1]); - INVERT_G_TO_B(inVal[2], outVal[2]); -} - -void G_TO_B(Transform3D const &inVal, btTransform &outVal) { - G_TO_B(inVal.basis, outVal.getBasis()); - G_TO_B(inVal.origin, outVal.getOrigin()); -} - -void UNSCALE_BT_BASIS(btTransform &scaledBasis) { - btMatrix3x3 &basis(scaledBasis.getBasis()); - btVector3 column0 = basis.getColumn(0); - btVector3 column1 = basis.getColumn(1); - btVector3 column2 = basis.getColumn(2); - - // Check for zero scaling. - if (column0.fuzzyZero()) { - if (column1.fuzzyZero()) { - if (column2.fuzzyZero()) { - // All dimensions are fuzzy zero. Create a default basis. - column0 = btVector3(1, 0, 0); - column1 = btVector3(0, 1, 0); - column2 = btVector3(0, 0, 1); - } else { // Column 2 scale not fuzzy zero. - // Create two vectors orthogonal to row 2. - // Ensure that a default basis is created if row 2 = <0, 0, 1> - column1 = btVector3(0, column2[2], -column2[1]); - column0 = column1.cross(column2); - } - } else { // Column 1 scale not fuzzy zero. - if (column2.fuzzyZero()) { - // Create two vectors orthogonal to column 1. - // Ensure that a default basis is created if column 1 = <0, 1, 0> - column0 = btVector3(column1[1], -column1[0], 0); - column2 = column0.cross(column1); - } else { // Column 1 and column 2 scales not fuzzy zero. - // Create column 0 orthogonal to column 1 and column 2. - column0 = column1.cross(column2); - } - } - } else { // Column 0 scale not fuzzy zero. - if (column1.fuzzyZero()) { - if (column2.fuzzyZero()) { - // Create two vectors orthogonal to column 0. - // Ensure that a default basis is created if column 0 = <1, 0, 0> - column2 = btVector3(-column0[2], 0, column0[0]); - column1 = column2.cross(column0); - } else { // Column 0 and column 2 scales not fuzzy zero. - // Create column 1 orthogonal to column 0 and column 2. - column1 = column2.cross(column0); - } - } else { // Column 0 and column 1 scales not fuzzy zero. - if (column2.fuzzyZero()) { - // Create column 2 orthogonal to column 0 and column 1. - column2 = column0.cross(column1); - } - } - } - - // Normalize - column0.normalize(); - column1.normalize(); - column2.normalize(); - - basis.setValue(column0[0], column1[0], column2[0], - column0[1], column1[1], column2[1], - column0[2], column1[2], column2[2]); -} diff --git a/modules/bullet/bullet_types_converter.h b/modules/bullet/bullet_types_converter.h deleted file mode 100644 index 4ee855c266..0000000000 --- a/modules/bullet/bullet_types_converter.h +++ /dev/null @@ -1,59 +0,0 @@ -/*************************************************************************/ -/* bullet_types_converter.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* 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. */ -/*************************************************************************/ - -#ifndef BULLET_TYPES_CONVERTER_H -#define BULLET_TYPES_CONVERTER_H - -#include "core/math/basis.h" -#include "core/math/transform_3d.h" -#include "core/math/vector3.h" -#include "core/typedefs.h" - -#include <LinearMath/btMatrix3x3.h> -#include <LinearMath/btTransform.h> -#include <LinearMath/btVector3.h> - -// Bullet to Godot -extern void B_TO_G(btVector3 const &inVal, Vector3 &outVal); -extern void INVERT_B_TO_G(btVector3 const &inVal, Vector3 &outVal); -extern void B_TO_G(btMatrix3x3 const &inVal, Basis &outVal); -extern void INVERT_B_TO_G(btMatrix3x3 const &inVal, Basis &outVal); -extern void B_TO_G(btTransform const &inVal, Transform3D &outVal); - -// Godot TO Bullet -extern void G_TO_B(Vector3 const &inVal, btVector3 &outVal); -extern void INVERT_G_TO_B(Vector3 const &inVal, btVector3 &outVal); -extern void G_TO_B(Basis const &inVal, btMatrix3x3 &outVal); -extern void INVERT_G_TO_B(Basis const &inVal, btMatrix3x3 &outVal); -extern void G_TO_B(Transform3D const &inVal, btTransform &outVal); - -extern void UNSCALE_BT_BASIS(btTransform &scaledBasis); - -#endif // BULLET_TYPES_CONVERTER_H diff --git a/modules/bullet/bullet_utilities.h b/modules/bullet/bullet_utilities.h deleted file mode 100644 index ab24cb5de6..0000000000 --- a/modules/bullet/bullet_utilities.h +++ /dev/null @@ -1,43 +0,0 @@ -/*************************************************************************/ -/* bullet_utilities.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* 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. */ -/*************************************************************************/ - -#ifndef BULLET_UTILITIES_H -#define BULLET_UTILITIES_H - -#define bulletnew(cl) \ - new cl - -#define bulletdelete(cl) \ - { \ - delete cl; \ - cl = nullptr; \ - } - -#endif // BULLET_UTILITIES_H diff --git a/modules/bullet/collision_object_bullet.cpp b/modules/bullet/collision_object_bullet.cpp deleted file mode 100644 index bc8e1a0718..0000000000 --- a/modules/bullet/collision_object_bullet.cpp +++ /dev/null @@ -1,396 +0,0 @@ -/*************************************************************************/ -/* collision_object_bullet.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* 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 "collision_object_bullet.h" - -#include "area_bullet.h" -#include "bullet_physics_server.h" -#include "bullet_types_converter.h" -#include "bullet_utilities.h" -#include "shape_bullet.h" -#include "space_bullet.h" - -#include <btBulletCollisionCommon.h> - -// We enable dynamic AABB tree so that we can actually perform a broadphase on bodies with compound collision shapes. -// This is crucial for the performance of kinematic bodies and for bodies with transforming shapes. -#define enableDynamicAabbTree true - -CollisionObjectBullet::ShapeWrapper::~ShapeWrapper() {} - -void CollisionObjectBullet::ShapeWrapper::set_transform(const Transform3D &p_transform) { - G_TO_B(p_transform.get_basis().get_scale_abs(), scale); - G_TO_B(p_transform, transform); - UNSCALE_BT_BASIS(transform); -} - -void CollisionObjectBullet::ShapeWrapper::set_transform(const btTransform &p_transform) { - transform = p_transform; -} - -btTransform CollisionObjectBullet::ShapeWrapper::get_adjusted_transform() const { - if (shape->get_type() == PhysicsServer3D::SHAPE_HEIGHTMAP) { - const HeightMapShapeBullet *hm_shape = (const HeightMapShapeBullet *)shape; // should be safe to cast now - btTransform adjusted_transform; - - // Bullet centers our heightmap: - // https://github.com/bulletphysics/bullet3/blob/master/src/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h#L33 - // This is really counter intuitive so we're adjusting for it - - adjusted_transform.setIdentity(); - adjusted_transform.setOrigin(btVector3(0.0, hm_shape->min_height + ((hm_shape->max_height - hm_shape->min_height) * 0.5), 0.0)); - adjusted_transform *= transform; - - return adjusted_transform; - } else { - return transform; - } -} - -void CollisionObjectBullet::ShapeWrapper::claim_bt_shape(const btVector3 &body_scale) { - if (!bt_shape) { - if (active) { - bt_shape = shape->create_bt_shape(scale * body_scale); - } else { - bt_shape = ShapeBullet::create_shape_empty(); - } - } -} - -CollisionObjectBullet::CollisionObjectBullet(Type p_type) : - RIDBullet(), - type(p_type) {} - -CollisionObjectBullet::~CollisionObjectBullet() { - for (int i = 0; i < areasOverlapped.size(); i++) { - areasOverlapped[i]->remove_object_overlaps(this); - } - destroyBulletCollisionObject(); -} - -bool equal(real_t first, real_t second) { - return Math::abs(first - second) <= 0.001f; -} - -void CollisionObjectBullet::set_body_scale(const Vector3 &p_new_scale) { - if (!equal(p_new_scale[0], body_scale[0]) || !equal(p_new_scale[1], body_scale[1]) || !equal(p_new_scale[2], body_scale[2])) { - body_scale = p_new_scale; - body_scale_changed(); - } -} - -btVector3 CollisionObjectBullet::get_bt_body_scale() const { - btVector3 s; - G_TO_B(body_scale, s); - return s; -} - -void CollisionObjectBullet::body_scale_changed() { - force_shape_reset = true; -} - -void CollisionObjectBullet::destroyBulletCollisionObject() { - bulletdelete(bt_collision_object); -} - -void CollisionObjectBullet::setupBulletCollisionObject(btCollisionObject *p_collisionObject) { - bt_collision_object = p_collisionObject; - bt_collision_object->setUserPointer(this); - bt_collision_object->setUserIndex(type); - // Force the enabling of collision and avoid problems - set_collision_enabled(collisionsEnabled); - p_collisionObject->setCollisionFlags(p_collisionObject->getCollisionFlags() | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK); -} - -void CollisionObjectBullet::add_collision_exception(const CollisionObjectBullet *p_ignoreCollisionObject) { - exceptions.insert(p_ignoreCollisionObject->get_self()); - if (!bt_collision_object) { - return; - } - bt_collision_object->setIgnoreCollisionCheck(p_ignoreCollisionObject->bt_collision_object, true); - if (space) { - space->get_broadphase()->getOverlappingPairCache()->cleanProxyFromPairs(bt_collision_object->getBroadphaseHandle(), space->get_dispatcher()); - } -} - -void CollisionObjectBullet::remove_collision_exception(const CollisionObjectBullet *p_ignoreCollisionObject) { - exceptions.erase(p_ignoreCollisionObject->get_self()); - if (!bt_collision_object) { - return; - } - bt_collision_object->setIgnoreCollisionCheck(p_ignoreCollisionObject->bt_collision_object, false); - if (space) { - space->get_broadphase()->getOverlappingPairCache()->cleanProxyFromPairs(bt_collision_object->getBroadphaseHandle(), space->get_dispatcher()); - } -} - -bool CollisionObjectBullet::has_collision_exception(const CollisionObjectBullet *p_otherCollisionObject) const { - return exceptions.has(p_otherCollisionObject->get_self()); -} - -void CollisionObjectBullet::set_collision_enabled(bool p_enabled) { - collisionsEnabled = p_enabled; - if (!bt_collision_object) { - return; - } - if (collisionsEnabled) { - bt_collision_object->setCollisionFlags(bt_collision_object->getCollisionFlags() & (~btCollisionObject::CF_NO_CONTACT_RESPONSE)); - } else { - bt_collision_object->setCollisionFlags(bt_collision_object->getCollisionFlags() | btCollisionObject::CF_NO_CONTACT_RESPONSE); - } -} - -bool CollisionObjectBullet::is_collisions_response_enabled() { - return collisionsEnabled; -} - -void CollisionObjectBullet::notify_new_overlap(AreaBullet *p_area) { - if (areasOverlapped.find(p_area) == -1) { - areasOverlapped.push_back(p_area); - } -} - -void CollisionObjectBullet::on_exit_area(AreaBullet *p_area) { - areasOverlapped.erase(p_area); -} - -void CollisionObjectBullet::set_godot_object_flags(int flags) { - bt_collision_object->setUserIndex2(flags); - updated = true; -} - -int CollisionObjectBullet::get_godot_object_flags() const { - return bt_collision_object->getUserIndex2(); -} - -void CollisionObjectBullet::set_transform(const Transform3D &p_global_transform) { - set_body_scale(p_global_transform.basis.get_scale_abs()); - - btTransform bt_transform; - G_TO_B(p_global_transform, bt_transform); - UNSCALE_BT_BASIS(bt_transform); - - set_transform__bullet(bt_transform); -} - -Transform3D CollisionObjectBullet::get_transform() const { - Transform3D t; - B_TO_G(get_transform__bullet(), t); - t.basis.scale(body_scale); - return t; -} - -void CollisionObjectBullet::set_transform__bullet(const btTransform &p_global_transform) { - bt_collision_object->setWorldTransform(p_global_transform); - notify_transform_changed(); -} - -const btTransform &CollisionObjectBullet::get_transform__bullet() const { - return bt_collision_object->getWorldTransform(); -} - -void CollisionObjectBullet::notify_transform_changed() { - updated = true; -} - -RigidCollisionObjectBullet::~RigidCollisionObjectBullet() { - remove_all_shapes(true, true); - if (mainShape && mainShape->isCompound()) { - bulletdelete(mainShape); - } -} - -void RigidCollisionObjectBullet::add_shape(ShapeBullet *p_shape, const Transform3D &p_transform, bool p_disabled) { - shapes.push_back(ShapeWrapper(p_shape, p_transform, !p_disabled)); - p_shape->add_owner(this); - reload_shapes(); -} - -void RigidCollisionObjectBullet::set_shape(int p_index, ShapeBullet *p_shape) { - ShapeWrapper &shp = shapes.write[p_index]; - shp.shape->remove_owner(this); - p_shape->add_owner(this); - shp.shape = p_shape; - reload_shapes(); -} - -int RigidCollisionObjectBullet::get_shape_count() const { - return shapes.size(); -} - -ShapeBullet *RigidCollisionObjectBullet::get_shape(int p_index) const { - return shapes[p_index].shape; -} - -btCollisionShape *RigidCollisionObjectBullet::get_bt_shape(int p_index) const { - return shapes[p_index].bt_shape; -} - -int RigidCollisionObjectBullet::find_shape(ShapeBullet *p_shape) const { - const int size = shapes.size(); - for (int i = 0; i < size; ++i) { - if (shapes[i].shape == p_shape) { - return i; - } - } - return -1; -} - -void RigidCollisionObjectBullet::remove_shape_full(ShapeBullet *p_shape) { - // Remove the shape, all the times it appears - // Reverse order required for delete. - for (int i = shapes.size() - 1; 0 <= i; --i) { - if (p_shape == shapes[i].shape) { - internal_shape_destroy(i); - shapes.remove_at(i); - } - } - reload_shapes(); -} - -void RigidCollisionObjectBullet::remove_shape_full(int p_index) { - ERR_FAIL_INDEX(p_index, get_shape_count()); - internal_shape_destroy(p_index); - shapes.remove_at(p_index); - reload_shapes(); -} - -void RigidCollisionObjectBullet::remove_all_shapes(bool p_permanentlyFromThisBody, bool p_force_not_reload) { - // Reverse order required for delete. - for (int i = shapes.size() - 1; 0 <= i; --i) { - internal_shape_destroy(i, p_permanentlyFromThisBody); - } - shapes.clear(); - if (!p_force_not_reload) { - reload_shapes(); - } -} - -void RigidCollisionObjectBullet::set_shape_transform(int p_index, const Transform3D &p_transform) { - ERR_FAIL_INDEX(p_index, get_shape_count()); - - shapes.write[p_index].set_transform(p_transform); - shape_changed(p_index); -} - -const btTransform &RigidCollisionObjectBullet::get_bt_shape_transform(int p_index) const { - return shapes[p_index].transform; -} - -Transform3D RigidCollisionObjectBullet::get_shape_transform(int p_index) const { - Transform3D trs; - B_TO_G(shapes[p_index].transform, trs); - return trs; -} - -void RigidCollisionObjectBullet::set_shape_disabled(int p_index, bool p_disabled) { - if (shapes[p_index].active != p_disabled) { - return; - } - shapes.write[p_index].active = !p_disabled; - shape_changed(p_index); -} - -bool RigidCollisionObjectBullet::is_shape_disabled(int p_index) { - return !shapes[p_index].active; -} - -void RigidCollisionObjectBullet::shape_changed(int p_shape_index) { - ShapeWrapper &shp = shapes.write[p_shape_index]; - if (shp.bt_shape == mainShape) { - mainShape = nullptr; - } - bulletdelete(shp.bt_shape); - reload_shapes(); -} - -void RigidCollisionObjectBullet::reload_shapes() { - if (mainShape && mainShape->isCompound()) { - // Destroy compound - bulletdelete(mainShape); - } - - mainShape = nullptr; - - ShapeWrapper *shpWrapper; - const int shape_count = shapes.size(); - - // Reset shape if required - if (force_shape_reset) { - for (int i(0); i < shape_count; ++i) { - shpWrapper = &shapes.write[i]; - bulletdelete(shpWrapper->bt_shape); - } - force_shape_reset = false; - } - - const btVector3 body_scale(get_bt_body_scale()); - - // Try to optimize by not using compound - if (1 == shape_count) { - shpWrapper = &shapes.write[0]; - btTransform transform = shpWrapper->get_adjusted_transform(); - if (transform.getOrigin().isZero() && transform.getBasis() == transform.getBasis().getIdentity()) { - shpWrapper->claim_bt_shape(body_scale); - mainShape = shpWrapper->bt_shape; - main_shape_changed(); - return; - } - } - - // Optimization not possible use a compound shape - btCompoundShape *compoundShape = bulletnew(btCompoundShape(enableDynamicAabbTree, shape_count)); - - for (int i(0); i < shape_count; ++i) { - shpWrapper = &shapes.write[i]; - shpWrapper->claim_bt_shape(body_scale); - btTransform scaled_shape_transform(shpWrapper->get_adjusted_transform()); - scaled_shape_transform.getOrigin() *= body_scale; - compoundShape->addChildShape(scaled_shape_transform, shpWrapper->bt_shape); - } - - compoundShape->recalculateLocalAabb(); - mainShape = compoundShape; - main_shape_changed(); -} - -void RigidCollisionObjectBullet::body_scale_changed() { - CollisionObjectBullet::body_scale_changed(); - reload_shapes(); -} - -void RigidCollisionObjectBullet::internal_shape_destroy(int p_index, bool p_permanentlyFromThisBody) { - ShapeWrapper &shp = shapes.write[p_index]; - shp.shape->remove_owner(this, p_permanentlyFromThisBody); - if (shp.bt_shape == mainShape) { - mainShape = nullptr; - } - bulletdelete(shp.bt_shape); -} diff --git a/modules/bullet/collision_object_bullet.h b/modules/bullet/collision_object_bullet.h deleted file mode 100644 index 8e9c34df27..0000000000 --- a/modules/bullet/collision_object_bullet.h +++ /dev/null @@ -1,255 +0,0 @@ -/*************************************************************************/ -/* collision_object_bullet.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* 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. */ -/*************************************************************************/ - -#ifndef COLLISION_OBJECT_BULLET_H -#define COLLISION_OBJECT_BULLET_H - -#include "core/math/transform_3d.h" -#include "core/math/vector3.h" -#include "core/object/class_db.h" -#include "core/templates/vset.h" -#include "shape_owner_bullet.h" - -#include <LinearMath/btTransform.h> - -class AreaBullet; -class ShapeBullet; -class btCollisionObject; -class btCompoundShape; -class btCollisionShape; -class SpaceBullet; - -class CollisionObjectBullet : public RIDBullet { -public: - enum GodotObjectFlags { - GOF_IS_MONITORING_AREA = 1 << 0 - // FLAG2 = 1 << 1, - // FLAG3 = 1 << 2, - // FLAG4 = 1 << 3, - // FLAG5 = 1 << 4, - // FLAG6 = 1 << 5 - // etc.. - }; - enum Type { - TYPE_AREA = 0, - TYPE_RIGID_BODY, - TYPE_SOFT_BODY, - TYPE_KINEMATIC_GHOST_BODY - }; - - struct ShapeWrapper { - ShapeBullet *shape = nullptr; - btCollisionShape *bt_shape = nullptr; - btTransform transform; - btVector3 scale; - bool active = true; - - ShapeWrapper() {} - - ShapeWrapper(ShapeBullet *p_shape, const btTransform &p_transform, bool p_active) : - shape(p_shape), - active(p_active) { - set_transform(p_transform); - } - - ShapeWrapper(ShapeBullet *p_shape, const Transform3D &p_transform, bool p_active) : - shape(p_shape), - active(p_active) { - set_transform(p_transform); - } - ~ShapeWrapper(); - - ShapeWrapper(const ShapeWrapper &otherShape) { - operator=(otherShape); - } - - void operator=(const ShapeWrapper &otherShape) { - shape = otherShape.shape; - bt_shape = otherShape.bt_shape; - transform = otherShape.transform; - scale = otherShape.scale; - active = otherShape.active; - } - - void set_transform(const Transform3D &p_transform); - void set_transform(const btTransform &p_transform); - btTransform get_adjusted_transform() const; - - void claim_bt_shape(const btVector3 &body_scale); - }; - -protected: - Type type = TYPE_AREA; - ObjectID instance_id; - uint32_t collisionLayer = 0; - uint32_t collisionMask = 0; - bool collisionsEnabled = true; - bool m_isStatic = false; - bool ray_pickable = false; - btCollisionObject *bt_collision_object = nullptr; - Vector3 body_scale = Vector3(1, 1, 1); - bool force_shape_reset = false; - SpaceBullet *space = nullptr; - - VSet<RID> exceptions; - - /// This array is used to know all areas where this Object is overlapped in - /// New area is added when overlap with new area (AreaBullet::addOverlap), then is removed when it exit (CollisionObjectBullet::onExitArea) - /// This array is used mainly to know which area hold the pointer of this object - Vector<AreaBullet *> areasOverlapped; - bool updated = false; - -public: - CollisionObjectBullet(Type p_type); - virtual ~CollisionObjectBullet(); - - Type getType() { return type; } - -protected: - void destroyBulletCollisionObject(); - void setupBulletCollisionObject(btCollisionObject *p_collisionObject); - -public: - _FORCE_INLINE_ btCollisionObject *get_bt_collision_object() { return bt_collision_object; } - - _FORCE_INLINE_ void set_instance_id(const ObjectID &p_instance_id) { instance_id = p_instance_id; } - _FORCE_INLINE_ ObjectID get_instance_id() const { return instance_id; } - - _FORCE_INLINE_ bool is_static() const { return m_isStatic; } - - _FORCE_INLINE_ void set_ray_pickable(bool p_enable) { ray_pickable = p_enable; } - _FORCE_INLINE_ bool is_ray_pickable() const { return ray_pickable; } - - void set_body_scale(const Vector3 &p_new_scale); - const Vector3 &get_body_scale() const { return body_scale; } - btVector3 get_bt_body_scale() const; - virtual void body_scale_changed(); - - void add_collision_exception(const CollisionObjectBullet *p_ignoreCollisionObject); - void remove_collision_exception(const CollisionObjectBullet *p_ignoreCollisionObject); - bool has_collision_exception(const CollisionObjectBullet *p_otherCollisionObject) const; - _FORCE_INLINE_ const VSet<RID> &get_exceptions() const { return exceptions; } - - _FORCE_INLINE_ void set_collision_layer(uint32_t p_layer) { - if (collisionLayer != p_layer) { - collisionLayer = p_layer; - on_collision_filters_change(); - } - } - _FORCE_INLINE_ uint32_t get_collision_layer() const { return collisionLayer; } - - _FORCE_INLINE_ void set_collision_mask(uint32_t p_mask) { - if (collisionMask != p_mask) { - collisionMask = p_mask; - on_collision_filters_change(); - } - } - _FORCE_INLINE_ uint32_t get_collision_mask() const { return collisionMask; } - - virtual void on_collision_filters_change() = 0; - - _FORCE_INLINE_ bool test_collision_mask(CollisionObjectBullet *p_other) const { - return collisionLayer & p_other->collisionMask || p_other->collisionLayer & collisionMask; - } - - virtual void reload_body() = 0; - virtual void set_space(SpaceBullet *p_space) = 0; - _FORCE_INLINE_ SpaceBullet *get_space() const { return space; } - - virtual void on_collision_checker_start() = 0; - virtual void on_collision_checker_end() = 0; - - virtual void dispatch_callbacks() = 0; - - void set_collision_enabled(bool p_enabled); - bool is_collisions_response_enabled(); - - void notify_new_overlap(AreaBullet *p_area); - virtual void on_enter_area(AreaBullet *p_area) = 0; - virtual void on_exit_area(AreaBullet *p_area); - - void set_godot_object_flags(int flags); - int get_godot_object_flags() const; - - void set_transform(const Transform3D &p_global_transform); - Transform3D get_transform() const; - virtual void set_transform__bullet(const btTransform &p_global_transform); - virtual const btTransform &get_transform__bullet() const; - virtual void notify_transform_changed(); - - bool is_updated() const { return updated; } -}; - -class RigidCollisionObjectBullet : public CollisionObjectBullet, public ShapeOwnerBullet { -protected: - btCollisionShape *mainShape = nullptr; - Vector<ShapeWrapper> shapes; - -public: - RigidCollisionObjectBullet(Type p_type) : - CollisionObjectBullet(p_type) {} - ~RigidCollisionObjectBullet(); - - _FORCE_INLINE_ const Vector<ShapeWrapper> &get_shapes_wrappers() const { return shapes; } - - _FORCE_INLINE_ btCollisionShape *get_main_shape() const { return mainShape; } - - void add_shape(ShapeBullet *p_shape, const Transform3D &p_transform = Transform3D(), bool p_disabled = false); - void set_shape(int p_index, ShapeBullet *p_shape); - - int get_shape_count() const; - ShapeBullet *get_shape(int p_index) const; - btCollisionShape *get_bt_shape(int p_index) const; - - int find_shape(ShapeBullet *p_shape) const; - - virtual void remove_shape_full(ShapeBullet *p_shape); - void remove_shape_full(int p_index); - void remove_all_shapes(bool p_permanentlyFromThisBody = false, bool p_force_not_reload = false); - - void set_shape_transform(int p_index, const Transform3D &p_transform); - - const btTransform &get_bt_shape_transform(int p_index) const; - Transform3D get_shape_transform(int p_index) const; - - void set_shape_disabled(int p_index, bool p_disabled); - bool is_shape_disabled(int p_index); - - virtual void shape_changed(int p_shape_index); - virtual void reload_shapes(); - - virtual void main_shape_changed() = 0; - virtual void body_scale_changed(); - -private: - void internal_shape_destroy(int p_index, bool p_permanentlyFromThisBody = false); -}; - -#endif // COLLISION_OBJECT_BULLET_H diff --git a/modules/bullet/cone_twist_joint_bullet.cpp b/modules/bullet/cone_twist_joint_bullet.cpp deleted file mode 100644 index fc73036713..0000000000 --- a/modules/bullet/cone_twist_joint_bullet.cpp +++ /dev/null @@ -1,103 +0,0 @@ -/*************************************************************************/ -/* cone_twist_joint_bullet.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* 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 "cone_twist_joint_bullet.h" - -#include "bullet_types_converter.h" -#include "bullet_utilities.h" -#include "rigid_body_bullet.h" - -#include <BulletDynamics/ConstraintSolver/btConeTwistConstraint.h> - -ConeTwistJointBullet::ConeTwistJointBullet(RigidBodyBullet *rbA, RigidBodyBullet *rbB, const Transform3D &rbAFrame, const Transform3D &rbBFrame) : - JointBullet() { - Transform3D scaled_AFrame(rbAFrame.scaled(rbA->get_body_scale())); - scaled_AFrame.basis.rotref_posscale_decomposition(scaled_AFrame.basis); - - btTransform btFrameA; - G_TO_B(scaled_AFrame, btFrameA); - - if (rbB) { - Transform3D scaled_BFrame(rbBFrame.scaled(rbB->get_body_scale())); - scaled_BFrame.basis.rotref_posscale_decomposition(scaled_BFrame.basis); - - btTransform btFrameB; - G_TO_B(scaled_BFrame, btFrameB); - - coneConstraint = bulletnew(btConeTwistConstraint(*rbA->get_bt_rigid_body(), *rbB->get_bt_rigid_body(), btFrameA, btFrameB)); - } else { - coneConstraint = bulletnew(btConeTwistConstraint(*rbA->get_bt_rigid_body(), btFrameA)); - } - setup(coneConstraint); -} - -void ConeTwistJointBullet::set_param(PhysicsServer3D::ConeTwistJointParam p_param, real_t p_value) { - switch (p_param) { - case PhysicsServer3D::CONE_TWIST_JOINT_SWING_SPAN: - coneConstraint->setLimit(5, p_value); - coneConstraint->setLimit(4, p_value); - break; - case PhysicsServer3D::CONE_TWIST_JOINT_TWIST_SPAN: - coneConstraint->setLimit(3, p_value); - break; - case PhysicsServer3D::CONE_TWIST_JOINT_BIAS: - coneConstraint->setLimit(coneConstraint->getSwingSpan1(), coneConstraint->getSwingSpan2(), coneConstraint->getTwistSpan(), coneConstraint->getLimitSoftness(), p_value, coneConstraint->getRelaxationFactor()); - break; - case PhysicsServer3D::CONE_TWIST_JOINT_SOFTNESS: - coneConstraint->setLimit(coneConstraint->getSwingSpan1(), coneConstraint->getSwingSpan2(), coneConstraint->getTwistSpan(), p_value, coneConstraint->getBiasFactor(), coneConstraint->getRelaxationFactor()); - break; - case PhysicsServer3D::CONE_TWIST_JOINT_RELAXATION: - coneConstraint->setLimit(coneConstraint->getSwingSpan1(), coneConstraint->getSwingSpan2(), coneConstraint->getTwistSpan(), coneConstraint->getLimitSoftness(), coneConstraint->getBiasFactor(), p_value); - break; - case PhysicsServer3D::CONE_TWIST_MAX: - // Internal size value, nothing to do. - break; - } -} - -real_t ConeTwistJointBullet::get_param(PhysicsServer3D::ConeTwistJointParam p_param) const { - switch (p_param) { - case PhysicsServer3D::CONE_TWIST_JOINT_SWING_SPAN: - return coneConstraint->getSwingSpan1(); - case PhysicsServer3D::CONE_TWIST_JOINT_TWIST_SPAN: - return coneConstraint->getTwistSpan(); - case PhysicsServer3D::CONE_TWIST_JOINT_BIAS: - return coneConstraint->getBiasFactor(); - case PhysicsServer3D::CONE_TWIST_JOINT_SOFTNESS: - return coneConstraint->getLimitSoftness(); - case PhysicsServer3D::CONE_TWIST_JOINT_RELAXATION: - return coneConstraint->getRelaxationFactor(); - case PhysicsServer3D::CONE_TWIST_MAX: - // Internal size value, nothing to do. - return 0; - } - // Compiler doesn't seem to notice that all code paths are fulfilled... - return 0; -} diff --git a/modules/bullet/cone_twist_joint_bullet.h b/modules/bullet/cone_twist_joint_bullet.h deleted file mode 100644 index c81e11f144..0000000000 --- a/modules/bullet/cone_twist_joint_bullet.h +++ /dev/null @@ -1,50 +0,0 @@ -/*************************************************************************/ -/* cone_twist_joint_bullet.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* 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. */ -/*************************************************************************/ - -#ifndef CONE_TWIST_JOINT_BULLET_H -#define CONE_TWIST_JOINT_BULLET_H - -#include "joint_bullet.h" - -class RigidBodyBullet; - -class ConeTwistJointBullet : public JointBullet { - class btConeTwistConstraint *coneConstraint; - -public: - ConeTwistJointBullet(RigidBodyBullet *rbA, RigidBodyBullet *rbB, const Transform3D &rbAFrame, const Transform3D &rbBFrame); - - virtual PhysicsServer3D::JointType get_type() const { return PhysicsServer3D::JOINT_CONE_TWIST; } - - void set_param(PhysicsServer3D::ConeTwistJointParam p_param, real_t p_value); - real_t get_param(PhysicsServer3D::ConeTwistJointParam p_param) const; -}; - -#endif // CONE_TWIST_JOINT_BULLET_H diff --git a/modules/bullet/config.py b/modules/bullet/config.py deleted file mode 100644 index 83605f1f9b..0000000000 --- a/modules/bullet/config.py +++ /dev/null @@ -1,8 +0,0 @@ -def can_build(env, platform): - # API Changed and bullet is disabled at the moment - return False - # Later change to return not env["disable_3d"] - - -def configure(env): - pass diff --git a/modules/bullet/constraint_bullet.cpp b/modules/bullet/constraint_bullet.cpp deleted file mode 100644 index c788f09cb9..0000000000 --- a/modules/bullet/constraint_bullet.cpp +++ /dev/null @@ -1,58 +0,0 @@ -/*************************************************************************/ -/* constraint_bullet.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* 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 "constraint_bullet.h" - -#include "collision_object_bullet.h" -#include "space_bullet.h" - -ConstraintBullet::ConstraintBullet() {} - -void ConstraintBullet::setup(btTypedConstraint *p_constraint) { - constraint = p_constraint; - constraint->setUserConstraintPtr(this); -} - -void ConstraintBullet::set_space(SpaceBullet *p_space) { - space = p_space; -} - -void ConstraintBullet::destroy_internal_constraint() { - space->remove_constraint(this); -} - -void ConstraintBullet::disable_collisions_between_bodies(const bool p_disabled) { - disabled_collisions_between_bodies = p_disabled; - - if (space) { - space->remove_constraint(this); - space->add_constraint(this, disabled_collisions_between_bodies); - } -} diff --git a/modules/bullet/constraint_bullet.h b/modules/bullet/constraint_bullet.h deleted file mode 100644 index 5dc3958ee1..0000000000 --- a/modules/bullet/constraint_bullet.h +++ /dev/null @@ -1,68 +0,0 @@ -/*************************************************************************/ -/* constraint_bullet.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* 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. */ -/*************************************************************************/ - -#ifndef CONSTRAINT_BULLET_H -#define CONSTRAINT_BULLET_H - -#include "bullet_utilities.h" -#include "rid_bullet.h" - -#include <BulletDynamics/ConstraintSolver/btTypedConstraint.h> - -class RigidBodyBullet; -class SpaceBullet; -class btTypedConstraint; - -class ConstraintBullet : public RIDBullet { -protected: - SpaceBullet *space = nullptr; - btTypedConstraint *constraint = nullptr; - bool disabled_collisions_between_bodies = true; - -public: - ConstraintBullet(); - - virtual void setup(btTypedConstraint *p_constraint); - virtual void set_space(SpaceBullet *p_space); - virtual void destroy_internal_constraint(); - - void disable_collisions_between_bodies(const bool p_disabled); - _FORCE_INLINE_ bool is_disabled_collisions_between_bodies() const { return disabled_collisions_between_bodies; } - -public: - virtual ~ConstraintBullet() { - bulletdelete(constraint); - constraint = nullptr; - } - - _FORCE_INLINE_ btTypedConstraint *get_bt_constraint() { return constraint; } -}; - -#endif // CONSTRAINT_BULLET_H diff --git a/modules/bullet/generic_6dof_joint_bullet.cpp b/modules/bullet/generic_6dof_joint_bullet.cpp deleted file mode 100644 index 0210064dc8..0000000000 --- a/modules/bullet/generic_6dof_joint_bullet.cpp +++ /dev/null @@ -1,271 +0,0 @@ -/*************************************************************************/ -/* generic_6dof_joint_bullet.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* 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 "generic_6dof_joint_bullet.h" - -#include "bullet_types_converter.h" -#include "bullet_utilities.h" -#include "rigid_body_bullet.h" - -#include <BulletDynamics/ConstraintSolver/btGeneric6DofSpring2Constraint.h> - -Generic6DOFJointBullet::Generic6DOFJointBullet(RigidBodyBullet *rbA, RigidBodyBullet *rbB, const Transform3D &frameInA, const Transform3D &frameInB) : - JointBullet() { - for (int i = 0; i < 3; i++) { - for (int j = 0; j < PhysicsServer3D::G6DOF_JOINT_FLAG_MAX; j++) { - flags[i][j] = false; - } - } - - Transform3D scaled_AFrame(frameInA.scaled(rbA->get_body_scale())); - - scaled_AFrame.basis.rotref_posscale_decomposition(scaled_AFrame.basis); - - btTransform btFrameA; - G_TO_B(scaled_AFrame, btFrameA); - - if (rbB) { - Transform3D scaled_BFrame(frameInB.scaled(rbB->get_body_scale())); - - scaled_BFrame.basis.rotref_posscale_decomposition(scaled_BFrame.basis); - - btTransform btFrameB; - G_TO_B(scaled_BFrame, btFrameB); - - sixDOFConstraint = bulletnew(btGeneric6DofSpring2Constraint(*rbA->get_bt_rigid_body(), *rbB->get_bt_rigid_body(), btFrameA, btFrameB)); - } else { - sixDOFConstraint = bulletnew(btGeneric6DofSpring2Constraint(*rbA->get_bt_rigid_body(), btFrameA)); - } - - setup(sixDOFConstraint); -} - -Transform3D Generic6DOFJointBullet::getFrameOffsetA() const { - btTransform btTrs = sixDOFConstraint->getFrameOffsetA(); - Transform3D gTrs; - B_TO_G(btTrs, gTrs); - return gTrs; -} - -Transform3D Generic6DOFJointBullet::getFrameOffsetB() const { - btTransform btTrs = sixDOFConstraint->getFrameOffsetB(); - Transform3D gTrs; - B_TO_G(btTrs, gTrs); - return gTrs; -} - -Transform3D Generic6DOFJointBullet::getFrameOffsetA() { - btTransform btTrs = sixDOFConstraint->getFrameOffsetA(); - Transform3D gTrs; - B_TO_G(btTrs, gTrs); - return gTrs; -} - -Transform3D Generic6DOFJointBullet::getFrameOffsetB() { - btTransform btTrs = sixDOFConstraint->getFrameOffsetB(); - Transform3D gTrs; - B_TO_G(btTrs, gTrs); - return gTrs; -} - -void Generic6DOFJointBullet::set_linear_lower_limit(const Vector3 &linearLower) { - btVector3 btVec; - G_TO_B(linearLower, btVec); - sixDOFConstraint->setLinearLowerLimit(btVec); -} - -void Generic6DOFJointBullet::set_linear_upper_limit(const Vector3 &linearUpper) { - btVector3 btVec; - G_TO_B(linearUpper, btVec); - sixDOFConstraint->setLinearUpperLimit(btVec); -} - -void Generic6DOFJointBullet::set_angular_lower_limit(const Vector3 &angularLower) { - btVector3 btVec; - G_TO_B(angularLower, btVec); - sixDOFConstraint->setAngularLowerLimit(btVec); -} - -void Generic6DOFJointBullet::set_angular_upper_limit(const Vector3 &angularUpper) { - btVector3 btVec; - G_TO_B(angularUpper, btVec); - sixDOFConstraint->setAngularUpperLimit(btVec); -} - -void Generic6DOFJointBullet::set_param(Vector3::Axis p_axis, PhysicsServer3D::G6DOFJointAxisParam p_param, real_t p_value) { - ERR_FAIL_INDEX(p_axis, 3); - switch (p_param) { - case PhysicsServer3D::G6DOF_JOINT_LINEAR_LOWER_LIMIT: - limits_lower[0][p_axis] = p_value; - set_flag(p_axis, PhysicsServer3D::G6DOF_JOINT_FLAG_ENABLE_LINEAR_LIMIT, flags[p_axis][PhysicsServer3D::G6DOF_JOINT_FLAG_ENABLE_LINEAR_LIMIT]); // Reload bullet parameter - break; - case PhysicsServer3D::G6DOF_JOINT_LINEAR_UPPER_LIMIT: - limits_upper[0][p_axis] = p_value; - set_flag(p_axis, PhysicsServer3D::G6DOF_JOINT_FLAG_ENABLE_LINEAR_LIMIT, flags[p_axis][PhysicsServer3D::G6DOF_JOINT_FLAG_ENABLE_LINEAR_LIMIT]); // Reload bullet parameter - break; - case PhysicsServer3D::G6DOF_JOINT_LINEAR_MOTOR_TARGET_VELOCITY: - sixDOFConstraint->getTranslationalLimitMotor()->m_targetVelocity.m_floats[p_axis] = p_value; - break; - case PhysicsServer3D::G6DOF_JOINT_LINEAR_MOTOR_FORCE_LIMIT: - sixDOFConstraint->getTranslationalLimitMotor()->m_maxMotorForce.m_floats[p_axis] = p_value; - break; - case PhysicsServer3D::G6DOF_JOINT_LINEAR_SPRING_DAMPING: - sixDOFConstraint->getTranslationalLimitMotor()->m_springDamping.m_floats[p_axis] = p_value; - break; - case PhysicsServer3D::G6DOF_JOINT_LINEAR_SPRING_STIFFNESS: - sixDOFConstraint->getTranslationalLimitMotor()->m_springStiffness.m_floats[p_axis] = p_value; - break; - case PhysicsServer3D::G6DOF_JOINT_LINEAR_SPRING_EQUILIBRIUM_POINT: - sixDOFConstraint->getTranslationalLimitMotor()->m_equilibriumPoint.m_floats[p_axis] = p_value; - break; - case PhysicsServer3D::G6DOF_JOINT_ANGULAR_LOWER_LIMIT: - limits_lower[1][p_axis] = p_value; - set_flag(p_axis, PhysicsServer3D::G6DOF_JOINT_FLAG_ENABLE_ANGULAR_LIMIT, flags[p_axis][PhysicsServer3D::G6DOF_JOINT_FLAG_ENABLE_ANGULAR_LIMIT]); // Reload bullet parameter - break; - case PhysicsServer3D::G6DOF_JOINT_ANGULAR_UPPER_LIMIT: - limits_upper[1][p_axis] = p_value; - set_flag(p_axis, PhysicsServer3D::G6DOF_JOINT_FLAG_ENABLE_ANGULAR_LIMIT, flags[p_axis][PhysicsServer3D::G6DOF_JOINT_FLAG_ENABLE_ANGULAR_LIMIT]); // Reload bullet parameter - break; - case PhysicsServer3D::G6DOF_JOINT_ANGULAR_RESTITUTION: - sixDOFConstraint->getRotationalLimitMotor(p_axis)->m_bounce = p_value; - break; - case PhysicsServer3D::G6DOF_JOINT_ANGULAR_ERP: - sixDOFConstraint->getRotationalLimitMotor(p_axis)->m_stopERP = p_value; - break; - case PhysicsServer3D::G6DOF_JOINT_ANGULAR_MOTOR_TARGET_VELOCITY: - sixDOFConstraint->getRotationalLimitMotor(p_axis)->m_targetVelocity = p_value; - break; - case PhysicsServer3D::G6DOF_JOINT_ANGULAR_MOTOR_FORCE_LIMIT: - sixDOFConstraint->getRotationalLimitMotor(p_axis)->m_maxMotorForce = p_value; - break; - case PhysicsServer3D::G6DOF_JOINT_ANGULAR_SPRING_STIFFNESS: - sixDOFConstraint->getRotationalLimitMotor(p_axis)->m_springStiffness = p_value; - break; - case PhysicsServer3D::G6DOF_JOINT_ANGULAR_SPRING_DAMPING: - sixDOFConstraint->getRotationalLimitMotor(p_axis)->m_springDamping = p_value; - break; - case PhysicsServer3D::G6DOF_JOINT_ANGULAR_SPRING_EQUILIBRIUM_POINT: - sixDOFConstraint->getRotationalLimitMotor(p_axis)->m_equilibriumPoint = p_value; - break; - case PhysicsServer3D::G6DOF_JOINT_MAX: - // Internal size value, nothing to do. - break; - default: - WARN_DEPRECATED_MSG("The parameter " + itos(p_param) + " is deprecated."); - break; - } -} - -real_t Generic6DOFJointBullet::get_param(Vector3::Axis p_axis, PhysicsServer3D::G6DOFJointAxisParam p_param) const { - ERR_FAIL_INDEX_V(p_axis, 3, 0.); - switch (p_param) { - case PhysicsServer3D::G6DOF_JOINT_LINEAR_LOWER_LIMIT: - return limits_lower[0][p_axis]; - case PhysicsServer3D::G6DOF_JOINT_LINEAR_UPPER_LIMIT: - return limits_upper[0][p_axis]; - case PhysicsServer3D::G6DOF_JOINT_LINEAR_MOTOR_TARGET_VELOCITY: - return sixDOFConstraint->getTranslationalLimitMotor()->m_targetVelocity.m_floats[p_axis]; - case PhysicsServer3D::G6DOF_JOINT_LINEAR_MOTOR_FORCE_LIMIT: - return sixDOFConstraint->getTranslationalLimitMotor()->m_maxMotorForce.m_floats[p_axis]; - case PhysicsServer3D::G6DOF_JOINT_LINEAR_SPRING_DAMPING: - return sixDOFConstraint->getTranslationalLimitMotor()->m_springDamping.m_floats[p_axis]; - case PhysicsServer3D::G6DOF_JOINT_LINEAR_SPRING_STIFFNESS: - return sixDOFConstraint->getTranslationalLimitMotor()->m_springStiffness.m_floats[p_axis]; - case PhysicsServer3D::G6DOF_JOINT_LINEAR_SPRING_EQUILIBRIUM_POINT: - return sixDOFConstraint->getTranslationalLimitMotor()->m_equilibriumPoint.m_floats[p_axis]; - case PhysicsServer3D::G6DOF_JOINT_ANGULAR_LOWER_LIMIT: - return limits_lower[1][p_axis]; - case PhysicsServer3D::G6DOF_JOINT_ANGULAR_UPPER_LIMIT: - return limits_upper[1][p_axis]; - case PhysicsServer3D::G6DOF_JOINT_ANGULAR_RESTITUTION: - return sixDOFConstraint->getRotationalLimitMotor(p_axis)->m_bounce; - case PhysicsServer3D::G6DOF_JOINT_ANGULAR_ERP: - return sixDOFConstraint->getRotationalLimitMotor(p_axis)->m_stopERP; - case PhysicsServer3D::G6DOF_JOINT_ANGULAR_MOTOR_TARGET_VELOCITY: - return sixDOFConstraint->getRotationalLimitMotor(p_axis)->m_targetVelocity; - case PhysicsServer3D::G6DOF_JOINT_ANGULAR_MOTOR_FORCE_LIMIT: - return sixDOFConstraint->getRotationalLimitMotor(p_axis)->m_maxMotorForce; - case PhysicsServer3D::G6DOF_JOINT_ANGULAR_SPRING_STIFFNESS: - return sixDOFConstraint->getRotationalLimitMotor(p_axis)->m_springStiffness; - case PhysicsServer3D::G6DOF_JOINT_ANGULAR_SPRING_DAMPING: - return sixDOFConstraint->getRotationalLimitMotor(p_axis)->m_springDamping; - case PhysicsServer3D::G6DOF_JOINT_ANGULAR_SPRING_EQUILIBRIUM_POINT: - return sixDOFConstraint->getRotationalLimitMotor(p_axis)->m_equilibriumPoint; - case PhysicsServer3D::G6DOF_JOINT_MAX: - // Internal size value, nothing to do. - return 0; - default: - WARN_DEPRECATED_MSG("The parameter " + itos(p_param) + " is deprecated."); - return 0; - } -} - -void Generic6DOFJointBullet::set_flag(Vector3::Axis p_axis, PhysicsServer3D::G6DOFJointAxisFlag p_flag, bool p_value) { - ERR_FAIL_INDEX(p_axis, 3); - - flags[p_axis][p_flag] = p_value; - - switch (p_flag) { - case PhysicsServer3D::G6DOF_JOINT_FLAG_ENABLE_LINEAR_LIMIT: - if (flags[p_axis][p_flag]) { - sixDOFConstraint->setLimit(p_axis, limits_lower[0][p_axis], limits_upper[0][p_axis]); - } else { - sixDOFConstraint->setLimit(p_axis, 0, -1); // Free - } - break; - case PhysicsServer3D::G6DOF_JOINT_FLAG_ENABLE_ANGULAR_LIMIT: - if (flags[p_axis][p_flag]) { - sixDOFConstraint->setLimit(p_axis + 3, limits_lower[1][p_axis], limits_upper[1][p_axis]); - } else { - sixDOFConstraint->setLimit(p_axis + 3, 0, -1); // Free - } - break; - case PhysicsServer3D::G6DOF_JOINT_FLAG_ENABLE_ANGULAR_SPRING: - sixDOFConstraint->getRotationalLimitMotor(p_axis)->m_enableSpring = p_value; - break; - case PhysicsServer3D::G6DOF_JOINT_FLAG_ENABLE_LINEAR_SPRING: - sixDOFConstraint->getTranslationalLimitMotor()->m_enableSpring[p_axis] = p_value; - break; - case PhysicsServer3D::G6DOF_JOINT_FLAG_ENABLE_MOTOR: - sixDOFConstraint->getRotationalLimitMotor(p_axis)->m_enableMotor = flags[p_axis][p_flag]; - break; - case PhysicsServer3D::G6DOF_JOINT_FLAG_ENABLE_LINEAR_MOTOR: - sixDOFConstraint->getTranslationalLimitMotor()->m_enableMotor[p_axis] = flags[p_axis][p_flag]; - break; - case PhysicsServer3D::G6DOF_JOINT_FLAG_MAX: - // Internal size value, nothing to do. - break; - } -} - -bool Generic6DOFJointBullet::get_flag(Vector3::Axis p_axis, PhysicsServer3D::G6DOFJointAxisFlag p_flag) const { - ERR_FAIL_INDEX_V(p_axis, 3, false); - return flags[p_axis][p_flag]; -} diff --git a/modules/bullet/generic_6dof_joint_bullet.h b/modules/bullet/generic_6dof_joint_bullet.h deleted file mode 100644 index cc4ccf7ac4..0000000000 --- a/modules/bullet/generic_6dof_joint_bullet.h +++ /dev/null @@ -1,69 +0,0 @@ -/*************************************************************************/ -/* generic_6dof_joint_bullet.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* 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. */ -/*************************************************************************/ - -#ifndef GENERIC_6DOF_JOINT_BULLET_H -#define GENERIC_6DOF_JOINT_BULLET_H - -#include "joint_bullet.h" - -class RigidBodyBullet; - -class Generic6DOFJointBullet : public JointBullet { - class btGeneric6DofSpring2Constraint *sixDOFConstraint; - - // First is linear second is angular - Vector3 limits_lower[2]; - Vector3 limits_upper[2]; - bool flags[3][PhysicsServer3D::G6DOF_JOINT_FLAG_MAX]; - -public: - Generic6DOFJointBullet(RigidBodyBullet *rbA, RigidBodyBullet *rbB, const Transform3D &frameInA, const Transform3D &frameInB); - - virtual PhysicsServer3D::JointType get_type() const { return PhysicsServer3D::JOINT_6DOF; } - - Transform3D getFrameOffsetA() const; - Transform3D getFrameOffsetB() const; - Transform3D getFrameOffsetA(); - Transform3D getFrameOffsetB(); - - void set_linear_lower_limit(const Vector3 &linearLower); - void set_linear_upper_limit(const Vector3 &linearUpper); - - void set_angular_lower_limit(const Vector3 &angularLower); - void set_angular_upper_limit(const Vector3 &angularUpper); - - void set_param(Vector3::Axis p_axis, PhysicsServer3D::G6DOFJointAxisParam p_param, real_t p_value); - real_t get_param(Vector3::Axis p_axis, PhysicsServer3D::G6DOFJointAxisParam p_param) const; - - void set_flag(Vector3::Axis p_axis, PhysicsServer3D::G6DOFJointAxisFlag p_flag, bool p_value); - bool get_flag(Vector3::Axis p_axis, PhysicsServer3D::G6DOFJointAxisFlag p_flag) const; -}; - -#endif // GENERIC_6DOF_JOINT_BULLET_H diff --git a/modules/bullet/godot_collision_configuration.cpp b/modules/bullet/godot_collision_configuration.cpp deleted file mode 100644 index 354c4e271b..0000000000 --- a/modules/bullet/godot_collision_configuration.cpp +++ /dev/null @@ -1,126 +0,0 @@ -/*************************************************************************/ -/* godot_collision_configuration.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* 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 "godot_collision_configuration.h" - -#include "godot_ray_world_algorithm.h" - -#include <BulletCollision/BroadphaseCollision/btBroadphaseProxy.h> -#include <BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h> - -GodotCollisionConfiguration::GodotCollisionConfiguration(const btDiscreteDynamicsWorld *world, const btDefaultCollisionConstructionInfo &constructionInfo) : - btDefaultCollisionConfiguration(constructionInfo) { - void *mem = nullptr; - - mem = btAlignedAlloc(sizeof(GodotRayWorldAlgorithm::CreateFunc), 16); - m_rayWorldCF = new (mem) GodotRayWorldAlgorithm::CreateFunc(world); - - mem = btAlignedAlloc(sizeof(GodotRayWorldAlgorithm::SwappedCreateFunc), 16); - m_swappedRayWorldCF = new (mem) GodotRayWorldAlgorithm::SwappedCreateFunc(world); -} - -GodotCollisionConfiguration::~GodotCollisionConfiguration() { - m_rayWorldCF->~btCollisionAlgorithmCreateFunc(); - btAlignedFree(m_rayWorldCF); - - m_swappedRayWorldCF->~btCollisionAlgorithmCreateFunc(); - btAlignedFree(m_swappedRayWorldCF); -} - -btCollisionAlgorithmCreateFunc *GodotCollisionConfiguration::getCollisionAlgorithmCreateFunc(int proxyType0, int proxyType1) { - if (CUSTOM_CONVEX_SHAPE_TYPE == proxyType0 && CUSTOM_CONVEX_SHAPE_TYPE == proxyType1) { - // This collision is not supported - return m_emptyCreateFunc; - } else if (CUSTOM_CONVEX_SHAPE_TYPE == proxyType0) { - return m_rayWorldCF; - } else if (CUSTOM_CONVEX_SHAPE_TYPE == proxyType1) { - return m_swappedRayWorldCF; - } else { - return btDefaultCollisionConfiguration::getCollisionAlgorithmCreateFunc(proxyType0, proxyType1); - } -} - -btCollisionAlgorithmCreateFunc *GodotCollisionConfiguration::getClosestPointsAlgorithmCreateFunc(int proxyType0, int proxyType1) { - if (CUSTOM_CONVEX_SHAPE_TYPE == proxyType0 && CUSTOM_CONVEX_SHAPE_TYPE == proxyType1) { - // This collision is not supported - return m_emptyCreateFunc; - } else if (CUSTOM_CONVEX_SHAPE_TYPE == proxyType0) { - return m_rayWorldCF; - } else if (CUSTOM_CONVEX_SHAPE_TYPE == proxyType1) { - return m_swappedRayWorldCF; - } else { - return btDefaultCollisionConfiguration::getClosestPointsAlgorithmCreateFunc(proxyType0, proxyType1); - } -} - -GodotSoftCollisionConfiguration::GodotSoftCollisionConfiguration(const btDiscreteDynamicsWorld *world, const btDefaultCollisionConstructionInfo &constructionInfo) : - btSoftBodyRigidBodyCollisionConfiguration(constructionInfo) { - void *mem = nullptr; - - mem = btAlignedAlloc(sizeof(GodotRayWorldAlgorithm::CreateFunc), 16); - m_rayWorldCF = new (mem) GodotRayWorldAlgorithm::CreateFunc(world); - - mem = btAlignedAlloc(sizeof(GodotRayWorldAlgorithm::SwappedCreateFunc), 16); - m_swappedRayWorldCF = new (mem) GodotRayWorldAlgorithm::SwappedCreateFunc(world); -} - -GodotSoftCollisionConfiguration::~GodotSoftCollisionConfiguration() { - m_rayWorldCF->~btCollisionAlgorithmCreateFunc(); - btAlignedFree(m_rayWorldCF); - - m_swappedRayWorldCF->~btCollisionAlgorithmCreateFunc(); - btAlignedFree(m_swappedRayWorldCF); -} - -btCollisionAlgorithmCreateFunc *GodotSoftCollisionConfiguration::getCollisionAlgorithmCreateFunc(int proxyType0, int proxyType1) { - if (CUSTOM_CONVEX_SHAPE_TYPE == proxyType0 && CUSTOM_CONVEX_SHAPE_TYPE == proxyType1) { - // This collision is not supported - return m_emptyCreateFunc; - } else if (CUSTOM_CONVEX_SHAPE_TYPE == proxyType0) { - return m_rayWorldCF; - } else if (CUSTOM_CONVEX_SHAPE_TYPE == proxyType1) { - return m_swappedRayWorldCF; - } else { - return btSoftBodyRigidBodyCollisionConfiguration::getCollisionAlgorithmCreateFunc(proxyType0, proxyType1); - } -} - -btCollisionAlgorithmCreateFunc *GodotSoftCollisionConfiguration::getClosestPointsAlgorithmCreateFunc(int proxyType0, int proxyType1) { - if (CUSTOM_CONVEX_SHAPE_TYPE == proxyType0 && CUSTOM_CONVEX_SHAPE_TYPE == proxyType1) { - // This collision is not supported - return m_emptyCreateFunc; - } else if (CUSTOM_CONVEX_SHAPE_TYPE == proxyType0) { - return m_rayWorldCF; - } else if (CUSTOM_CONVEX_SHAPE_TYPE == proxyType1) { - return m_swappedRayWorldCF; - } else { - return btSoftBodyRigidBodyCollisionConfiguration::getClosestPointsAlgorithmCreateFunc(proxyType0, proxyType1); - } -} diff --git a/modules/bullet/godot_collision_configuration.h b/modules/bullet/godot_collision_configuration.h deleted file mode 100644 index 7e29f6e03a..0000000000 --- a/modules/bullet/godot_collision_configuration.h +++ /dev/null @@ -1,63 +0,0 @@ -/*************************************************************************/ -/* godot_collision_configuration.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* 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. */ -/*************************************************************************/ - -#ifndef GODOT_COLLISION_CONFIGURATION_H -#define GODOT_COLLISION_CONFIGURATION_H - -#include <BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.h> -#include <BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h> - -class btDiscreteDynamicsWorld; - -class GodotCollisionConfiguration : public btDefaultCollisionConfiguration { - btCollisionAlgorithmCreateFunc *m_rayWorldCF; - btCollisionAlgorithmCreateFunc *m_swappedRayWorldCF; - -public: - GodotCollisionConfiguration(const btDiscreteDynamicsWorld *world, const btDefaultCollisionConstructionInfo &constructionInfo = btDefaultCollisionConstructionInfo()); - virtual ~GodotCollisionConfiguration(); - - virtual btCollisionAlgorithmCreateFunc *getCollisionAlgorithmCreateFunc(int proxyType0, int proxyType1); - virtual btCollisionAlgorithmCreateFunc *getClosestPointsAlgorithmCreateFunc(int proxyType0, int proxyType1); -}; - -class GodotSoftCollisionConfiguration : public btSoftBodyRigidBodyCollisionConfiguration { - btCollisionAlgorithmCreateFunc *m_rayWorldCF; - btCollisionAlgorithmCreateFunc *m_swappedRayWorldCF; - -public: - GodotSoftCollisionConfiguration(const btDiscreteDynamicsWorld *world, const btDefaultCollisionConstructionInfo &constructionInfo = btDefaultCollisionConstructionInfo()); - virtual ~GodotSoftCollisionConfiguration(); - - virtual btCollisionAlgorithmCreateFunc *getCollisionAlgorithmCreateFunc(int proxyType0, int proxyType1); - virtual btCollisionAlgorithmCreateFunc *getClosestPointsAlgorithmCreateFunc(int proxyType0, int proxyType1); -}; - -#endif // GODOT_COLLISION_CONFIGURATION_H diff --git a/modules/bullet/godot_collision_dispatcher.cpp b/modules/bullet/godot_collision_dispatcher.cpp deleted file mode 100644 index 2ab1c7dd84..0000000000 --- a/modules/bullet/godot_collision_dispatcher.cpp +++ /dev/null @@ -1,54 +0,0 @@ -/*************************************************************************/ -/* godot_collision_dispatcher.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* 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 "godot_collision_dispatcher.h" - -#include "collision_object_bullet.h" - -const int GodotCollisionDispatcher::CASTED_TYPE_AREA = static_cast<int>(CollisionObjectBullet::TYPE_AREA); - -GodotCollisionDispatcher::GodotCollisionDispatcher(btCollisionConfiguration *collisionConfiguration) : - btCollisionDispatcher(collisionConfiguration) {} - -bool GodotCollisionDispatcher::needsCollision(const btCollisionObject *body0, const btCollisionObject *body1) { - if (body0->getUserIndex() == CASTED_TYPE_AREA || body1->getUserIndex() == CASTED_TYPE_AREA) { - // Avoid area narrow phase - return false; - } - return btCollisionDispatcher::needsCollision(body0, body1); -} - -bool GodotCollisionDispatcher::needsResponse(const btCollisionObject *body0, const btCollisionObject *body1) { - if (body0->getUserIndex() == CASTED_TYPE_AREA || body1->getUserIndex() == CASTED_TYPE_AREA) { - // Avoid area narrow phase - return false; - } - return btCollisionDispatcher::needsResponse(body0, body1); -} diff --git a/modules/bullet/godot_collision_dispatcher.h b/modules/bullet/godot_collision_dispatcher.h deleted file mode 100644 index 97cae1ce6a..0000000000 --- a/modules/bullet/godot_collision_dispatcher.h +++ /dev/null @@ -1,47 +0,0 @@ -/*************************************************************************/ -/* godot_collision_dispatcher.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* 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. */ -/*************************************************************************/ - -#ifndef GODOT_COLLISION_DISPATCHER_H -#define GODOT_COLLISION_DISPATCHER_H - -#include <btBulletDynamicsCommon.h> - -/// This class is required to implement custom collision behaviour in the narrowphase -class GodotCollisionDispatcher : public btCollisionDispatcher { -private: - static const int CASTED_TYPE_AREA; - -public: - GodotCollisionDispatcher(btCollisionConfiguration *collisionConfiguration); - virtual bool needsCollision(const btCollisionObject *body0, const btCollisionObject *body1); - virtual bool needsResponse(const btCollisionObject *body0, const btCollisionObject *body1); -}; - -#endif // GODOT_COLLISION_DISPATCHER_H diff --git a/modules/bullet/godot_motion_state.h b/modules/bullet/godot_motion_state.h deleted file mode 100644 index f1a5e0e3b5..0000000000 --- a/modules/bullet/godot_motion_state.h +++ /dev/null @@ -1,96 +0,0 @@ -/*************************************************************************/ -/* godot_motion_state.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* 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. */ -/*************************************************************************/ - -#ifndef GODOT_MOTION_STATE_H -#define GODOT_MOTION_STATE_H - -#include "rigid_body_bullet.h" - -#include <LinearMath/btMotionState.h> - -class RigidBodyBullet; - -// This class is responsible to move kinematic actor -// and sincronize rendering engine with Bullet -/// DOC: -/// http://www.bulletphysics.org/mediawiki-1.5.8/index.php/MotionStates#What.27s_a_MotionState.3F -class GodotMotionState : public btMotionState { - /// This data is used to store the new world position for kinematic body - btTransform bodyKinematicWorldTransf; - /// This data is used to store last world position - btTransform bodyCurrentWorldTransform; - - RigidBodyBullet *owner = nullptr; - -public: - GodotMotionState(RigidBodyBullet *p_owner) : - bodyKinematicWorldTransf(btMatrix3x3(1., 0., 0., 0., 1., 0., 0., 0., 1.), btVector3(0., 0., 0.)), - bodyCurrentWorldTransform(btMatrix3x3(1., 0., 0., 0., 1., 0., 0., 0., 1.), btVector3(0., 0., 0.)), - owner(p_owner) {} - - /// IMPORTANT DON'T USE THIS FUNCTION TO KNOW THE CURRENT BODY TRANSFORM - /// This class is used internally by Bullet - /// Use GodotMotionState::getCurrentWorldTransform to know current position - /// - /// This function is used by Bullet to get the position of object in the world - /// if the body is kinematic Bullet will move the object to this location - /// if the body is static Bullet doesn't move at all - virtual void getWorldTransform(btTransform &worldTrans) const { - worldTrans = bodyKinematicWorldTransf; - } - - /// IMPORTANT: to move the body use: moveBody - /// IMPORTANT: DON'T CALL THIS FUNCTION, IT IS CALLED BY BULLET TO UPDATE RENDERING ENGINE - /// - /// This function is called each time by Bullet and set the current position of body - /// inside the physics world. - /// Don't allow Godot rendering scene takes world transform from this object because - /// the correct transform is set by Bullet only after the last step when there are sub steps - /// This function must update Godot transform rendering scene for this object. - virtual void setWorldTransform(const btTransform &worldTrans) { - bodyCurrentWorldTransform = worldTrans; - - owner->notify_transform_changed(); - } - -public: - /// Use this function to move kinematic body - /// -- or set initial transform before body creation. - void moveBody(const btTransform &newWorldTransform) { - bodyKinematicWorldTransf = newWorldTransform; - } - - /// It returns the current body transform from last Bullet update - const btTransform &getCurrentWorldTransform() const { - return bodyCurrentWorldTransform; - } -}; - -#endif // GODOT_MOTION_STATE_H diff --git a/modules/bullet/godot_ray_world_algorithm.cpp b/modules/bullet/godot_ray_world_algorithm.cpp deleted file mode 100644 index 697ca12e7b..0000000000 --- a/modules/bullet/godot_ray_world_algorithm.cpp +++ /dev/null @@ -1,111 +0,0 @@ -/*************************************************************************/ -/* godot_ray_world_algorithm.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* 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 "godot_ray_world_algorithm.h" - -#include "btRayShape.h" -#include "collision_object_bullet.h" - -#include <BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h> - -// Epsilon to account for floating point inaccuracies -#define RAY_PENETRATION_DEPTH_EPSILON 0.01 - -GodotRayWorldAlgorithm::CreateFunc::CreateFunc(const btDiscreteDynamicsWorld *world) : - m_world(world) {} - -GodotRayWorldAlgorithm::SwappedCreateFunc::SwappedCreateFunc(const btDiscreteDynamicsWorld *world) : - m_world(world) {} - -GodotRayWorldAlgorithm::GodotRayWorldAlgorithm(const btDiscreteDynamicsWorld *world, btPersistentManifold *mf, const btCollisionAlgorithmConstructionInfo &ci, const btCollisionObjectWrapper *body0Wrap, const btCollisionObjectWrapper *body1Wrap, bool isSwapped) : - btActivatingCollisionAlgorithm(ci, body0Wrap, body1Wrap), - m_world(world), - m_manifoldPtr(mf), - m_isSwapped(isSwapped) {} - -GodotRayWorldAlgorithm::~GodotRayWorldAlgorithm() { - if (m_ownManifold && m_manifoldPtr) { - m_dispatcher->releaseManifold(m_manifoldPtr); - } -} - -void GodotRayWorldAlgorithm::processCollision(const btCollisionObjectWrapper *body0Wrap, const btCollisionObjectWrapper *body1Wrap, const btDispatcherInfo &dispatchInfo, btManifoldResult *resultOut) { - if (!m_manifoldPtr) { - if (m_isSwapped) { - m_manifoldPtr = m_dispatcher->getNewManifold(body1Wrap->getCollisionObject(), body0Wrap->getCollisionObject()); - } else { - m_manifoldPtr = m_dispatcher->getNewManifold(body0Wrap->getCollisionObject(), body1Wrap->getCollisionObject()); - } - m_ownManifold = true; - } - m_manifoldPtr->clearManifold(); - resultOut->setPersistentManifold(m_manifoldPtr); - - const btRayShape *ray_shape; - btTransform ray_transform; - - const btCollisionObjectWrapper *other_co_wrapper; - - if (m_isSwapped) { - ray_shape = static_cast<const btRayShape *>(body1Wrap->getCollisionShape()); - ray_transform = body1Wrap->getWorldTransform(); - - other_co_wrapper = body0Wrap; - } else { - ray_shape = static_cast<const btRayShape *>(body0Wrap->getCollisionShape()); - ray_transform = body0Wrap->getWorldTransform(); - - other_co_wrapper = body1Wrap; - } - - btTransform to(ray_transform * ray_shape->getSupportPoint()); - - btCollisionWorld::ClosestRayResultCallback btResult(ray_transform.getOrigin(), to.getOrigin()); - - m_world->rayTestSingleInternal(ray_transform, to, other_co_wrapper, btResult); - - if (btResult.hasHit()) { - btScalar depth(ray_shape->getScaledLength() * (btResult.m_closestHitFraction - 1)); - - if (depth > -RAY_PENETRATION_DEPTH_EPSILON) { - depth = 0.0; - } - - if (ray_shape->getSlipsOnSlope()) { - resultOut->addContactPoint(btResult.m_hitNormalWorld, btResult.m_hitPointWorld, depth); - } else { - resultOut->addContactPoint((ray_transform.getOrigin() - to.getOrigin()).normalize(), btResult.m_hitPointWorld, depth); - } - } -} - -btScalar GodotRayWorldAlgorithm::calculateTimeOfImpact(btCollisionObject *body0, btCollisionObject *body1, const btDispatcherInfo &dispatchInfo, btManifoldResult *resultOut) { - return 1; -} diff --git a/modules/bullet/godot_ray_world_algorithm.h b/modules/bullet/godot_ray_world_algorithm.h deleted file mode 100644 index 94bdefb720..0000000000 --- a/modules/bullet/godot_ray_world_algorithm.h +++ /dev/null @@ -1,80 +0,0 @@ -/*************************************************************************/ -/* godot_ray_world_algorithm.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* 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. */ -/*************************************************************************/ - -#ifndef GODOT_RAY_WORLD_ALGORITHM_H -#define GODOT_RAY_WORLD_ALGORITHM_H - -#include <BulletCollision/CollisionDispatch/btActivatingCollisionAlgorithm.h> -#include <BulletCollision/CollisionDispatch/btCollisionCreateFunc.h> -#include <BulletCollision/CollisionDispatch/btCollisionDispatcher.h> - -class btDiscreteDynamicsWorld; - -class GodotRayWorldAlgorithm : public btActivatingCollisionAlgorithm { - const btDiscreteDynamicsWorld *m_world; - btPersistentManifold *m_manifoldPtr; - bool m_ownManifold = false; - bool m_isSwapped = false; - -public: - GodotRayWorldAlgorithm(const btDiscreteDynamicsWorld *world, btPersistentManifold *mf, const btCollisionAlgorithmConstructionInfo &ci, const btCollisionObjectWrapper *body0Wrap, const btCollisionObjectWrapper *body1Wrap, bool isSwapped); - virtual ~GodotRayWorldAlgorithm(); - - virtual void processCollision(const btCollisionObjectWrapper *body0Wrap, const btCollisionObjectWrapper *body1Wrap, const btDispatcherInfo &dispatchInfo, btManifoldResult *resultOut); - virtual btScalar calculateTimeOfImpact(btCollisionObject *body0, btCollisionObject *body1, const btDispatcherInfo &dispatchInfo, btManifoldResult *resultOut); - - virtual void getAllContactManifolds(btManifoldArray &manifoldArray) { - ///should we use m_ownManifold to avoid adding duplicates? - if (m_manifoldPtr && m_ownManifold) { - manifoldArray.push_back(m_manifoldPtr); - } - } - struct CreateFunc : public btCollisionAlgorithmCreateFunc { - const btDiscreteDynamicsWorld *m_world; - CreateFunc(const btDiscreteDynamicsWorld *world); - - virtual btCollisionAlgorithm *CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo &ci, const btCollisionObjectWrapper *body0Wrap, const btCollisionObjectWrapper *body1Wrap) { - void *mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(GodotRayWorldAlgorithm)); - return new (mem) GodotRayWorldAlgorithm(m_world, ci.m_manifold, ci, body0Wrap, body1Wrap, false); - } - }; - - struct SwappedCreateFunc : public btCollisionAlgorithmCreateFunc { - const btDiscreteDynamicsWorld *m_world; - SwappedCreateFunc(const btDiscreteDynamicsWorld *world); - - virtual btCollisionAlgorithm *CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo &ci, const btCollisionObjectWrapper *body0Wrap, const btCollisionObjectWrapper *body1Wrap) { - void *mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(GodotRayWorldAlgorithm)); - return new (mem) GodotRayWorldAlgorithm(m_world, ci.m_manifold, ci, body0Wrap, body1Wrap, true); - } - }; -}; - -#endif // GODOT_RAY_WORLD_ALGORITHM_H diff --git a/modules/bullet/godot_result_callbacks.cpp b/modules/bullet/godot_result_callbacks.cpp deleted file mode 100644 index 35b26fc2ec..0000000000 --- a/modules/bullet/godot_result_callbacks.cpp +++ /dev/null @@ -1,377 +0,0 @@ -/*************************************************************************/ -/* godot_result_callbacks.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* 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 "godot_result_callbacks.h" - -#include "area_bullet.h" -#include "bullet_types_converter.h" -#include "collision_object_bullet.h" -#include "rigid_body_bullet.h" - -#include <BulletCollision/CollisionDispatch/btInternalEdgeUtility.h> - -bool godotContactAddedCallback(btManifoldPoint &cp, const btCollisionObjectWrapper *colObj0Wrap, int partId0, int index0, const btCollisionObjectWrapper *colObj1Wrap, int partId1, int index1) { - if (!colObj1Wrap->getCollisionObject()->getCollisionShape()->isCompound()) { - btAdjustInternalEdgeContacts(cp, colObj1Wrap, colObj0Wrap, partId1, index1); - } - return true; -} - -bool GodotFilterCallback::needBroadphaseCollision(btBroadphaseProxy *proxy0, btBroadphaseProxy *proxy1) const { - return (proxy0->m_collisionFilterGroup & proxy1->m_collisionFilterMask) || (proxy1->m_collisionFilterGroup & proxy0->m_collisionFilterMask); -} - -bool GodotClosestRayResultCallback::needsCollision(btBroadphaseProxy *proxy0) const { - if (proxy0->m_collisionFilterGroup & m_collisionFilterMask) { - btCollisionObject *btObj = static_cast<btCollisionObject *>(proxy0->m_clientObject); - CollisionObjectBullet *gObj = static_cast<CollisionObjectBullet *>(btObj->getUserPointer()); - - if (CollisionObjectBullet::TYPE_AREA == gObj->getType()) { - if (!collide_with_areas) { - return false; - } - } else { - if (!collide_with_bodies) { - return false; - } - } - - if (m_pickRay && !gObj->is_ray_pickable()) { - return false; - } - - if (m_exclude->has(gObj->get_self())) { - return false; - } - - return true; - } else { - return false; - } -} - -bool GodotAllConvexResultCallback::needsCollision(btBroadphaseProxy *proxy0) const { - if (count >= m_resultMax) { - return false; - } - - if (proxy0->m_collisionFilterGroup & m_collisionFilterMask) { - btCollisionObject *btObj = static_cast<btCollisionObject *>(proxy0->m_clientObject); - CollisionObjectBullet *gObj = static_cast<CollisionObjectBullet *>(btObj->getUserPointer()); - if (m_exclude->has(gObj->get_self())) { - return false; - } - - return true; - } else { - return false; - } -} - -btScalar GodotAllConvexResultCallback::addSingleResult(btCollisionWorld::LocalConvexResult &convexResult, bool normalInWorldSpace) { - if (count >= m_resultMax) { - return 1; // not used by bullet - } - - CollisionObjectBullet *gObj = static_cast<CollisionObjectBullet *>(convexResult.m_hitCollisionObject->getUserPointer()); - - PhysicsDirectSpaceState3D::ShapeResult &result = m_results[count]; - - // Triangle index is an odd name but contains the compound shape ID. - // A shape part of -1 indicates the index is a shape index and not a triangle index. - if (convexResult.m_localShapeInfo && convexResult.m_localShapeInfo->m_shapePart == -1) { - result.shape = convexResult.m_localShapeInfo->m_triangleIndex; - } else { - result.shape = 0; - } - - result.rid = gObj->get_self(); - result.collider_id = gObj->get_instance_id(); - result.collider = result.collider_id.is_null() ? nullptr : ObjectDB::get_instance(result.collider_id); - - ++count; - return 1; // not used by bullet -} - -bool GodotKinClosestConvexResultCallback::needsCollision(btBroadphaseProxy *proxy0) const { - if (proxy0->m_collisionFilterGroup & m_collisionFilterMask) { - btCollisionObject *btObj = static_cast<btCollisionObject *>(proxy0->m_clientObject); - CollisionObjectBullet *gObj = static_cast<CollisionObjectBullet *>(btObj->getUserPointer()); - if (gObj == m_self_object) { - return false; - } else { - // A kinematic body can't be stopped by a rigid body since the mass of kinematic body is infinite - if (m_infinite_inertia && !btObj->isStaticOrKinematicObject()) { - return false; - } - - if (gObj->getType() == CollisionObjectBullet::TYPE_AREA) { - return false; - } - - if (m_self_object->has_collision_exception(gObj) || gObj->has_collision_exception(m_self_object)) { - return false; - } - - if (m_exclude->has(gObj->get_self())) { - return false; - } - } - return true; - } else { - return false; - } -} - -bool GodotClosestConvexResultCallback::needsCollision(btBroadphaseProxy *proxy0) const { - if (proxy0->m_collisionFilterGroup & m_collisionFilterMask) { - btCollisionObject *btObj = static_cast<btCollisionObject *>(proxy0->m_clientObject); - CollisionObjectBullet *gObj = static_cast<CollisionObjectBullet *>(btObj->getUserPointer()); - - if (CollisionObjectBullet::TYPE_AREA == gObj->getType()) { - if (!collide_with_areas) { - return false; - } - } else { - if (!collide_with_bodies) { - return false; - } - } - - if (m_exclude->has(gObj->get_self())) { - return false; - } - return true; - } else { - return false; - } -} - -btScalar GodotClosestConvexResultCallback::addSingleResult(btCollisionWorld::LocalConvexResult &convexResult, bool normalInWorldSpace) { - // Triangle index is an odd name but contains the compound shape ID. - // A shape part of -1 indicates the index is a shape index and not a triangle index. - if (convexResult.m_localShapeInfo && convexResult.m_localShapeInfo->m_shapePart == -1) { - m_shapeId = convexResult.m_localShapeInfo->m_triangleIndex; - } else { - m_shapeId = 0; - } - - return btCollisionWorld::ClosestConvexResultCallback::addSingleResult(convexResult, normalInWorldSpace); -} - -bool GodotAllContactResultCallback::needsCollision(btBroadphaseProxy *proxy0) const { - if (m_count >= m_resultMax) { - return false; - } - - if (proxy0->m_collisionFilterGroup & m_collisionFilterMask) { - btCollisionObject *btObj = static_cast<btCollisionObject *>(proxy0->m_clientObject); - CollisionObjectBullet *gObj = static_cast<CollisionObjectBullet *>(btObj->getUserPointer()); - - if (CollisionObjectBullet::TYPE_AREA == gObj->getType()) { - if (!collide_with_areas) { - return false; - } - } else { - if (!collide_with_bodies) { - return false; - } - } - - if (m_exclude->has(gObj->get_self())) { - return false; - } - return true; - } else { - return false; - } -} - -btScalar GodotAllContactResultCallback::addSingleResult(btManifoldPoint &cp, const btCollisionObjectWrapper *colObj0Wrap, int partId0, int index0, const btCollisionObjectWrapper *colObj1Wrap, int partId1, int index1) { - if (m_count >= m_resultMax) { - return cp.getDistance(); - } - - if (cp.getDistance() <= 0) { - PhysicsDirectSpaceState3D::ShapeResult &result = m_results[m_count]; - // Penetrated - - CollisionObjectBullet *colObj; - if (m_self_object == colObj0Wrap->getCollisionObject()) { - colObj = static_cast<CollisionObjectBullet *>(colObj1Wrap->getCollisionObject()->getUserPointer()); - // Checking for compound shape because the index might be uninitialized otherwise. - // A partId of -1 indicates the index is a shape index and not a triangle index. - if (colObj1Wrap->getCollisionObject()->getCollisionShape()->isCompound() && cp.m_partId1 == -1) { - result.shape = cp.m_index1; - } else { - result.shape = 0; - } - } else { - colObj = static_cast<CollisionObjectBullet *>(colObj0Wrap->getCollisionObject()->getUserPointer()); - // Checking for compound shape because the index might be uninitialized otherwise. - // A partId of -1 indicates the index is a shape index and not a triangle index. - if (colObj0Wrap->getCollisionObject()->getCollisionShape()->isCompound() && cp.m_partId0 == -1) { - result.shape = cp.m_index0; - } else { - result.shape = 0; - } - } - - result.collider_id = colObj->get_instance_id(); - result.collider = result.collider_id.is_null() ? nullptr : ObjectDB::get_instance(result.collider_id); - result.rid = colObj->get_self(); - ++m_count; - } - - return cp.getDistance(); -} - -bool GodotContactPairContactResultCallback::needsCollision(btBroadphaseProxy *proxy0) const { - if (m_count >= m_resultMax) { - return false; - } - - if (proxy0->m_collisionFilterGroup & m_collisionFilterMask) { - btCollisionObject *btObj = static_cast<btCollisionObject *>(proxy0->m_clientObject); - CollisionObjectBullet *gObj = static_cast<CollisionObjectBullet *>(btObj->getUserPointer()); - - if (CollisionObjectBullet::TYPE_AREA == gObj->getType()) { - if (!collide_with_areas) { - return false; - } - } else { - if (!collide_with_bodies) { - return false; - } - } - - if (m_exclude->has(gObj->get_self())) { - return false; - } - return true; - } else { - return false; - } -} - -btScalar GodotContactPairContactResultCallback::addSingleResult(btManifoldPoint &cp, const btCollisionObjectWrapper *colObj0Wrap, int partId0, int index0, const btCollisionObjectWrapper *colObj1Wrap, int partId1, int index1) { - if (m_count >= m_resultMax) { - return 1; // not used by bullet - } - - if (m_self_object == colObj0Wrap->getCollisionObject()) { - B_TO_G(cp.m_localPointA, m_results[m_count * 2 + 0]); // Local contact - B_TO_G(cp.m_localPointB, m_results[m_count * 2 + 1]); - } else { - B_TO_G(cp.m_localPointB, m_results[m_count * 2 + 0]); // Local contact - B_TO_G(cp.m_localPointA, m_results[m_count * 2 + 1]); - } - - ++m_count; - - return 1; // Not used by bullet -} - -bool GodotRestInfoContactResultCallback::needsCollision(btBroadphaseProxy *proxy0) const { - if (proxy0->m_collisionFilterGroup & m_collisionFilterMask) { - btCollisionObject *btObj = static_cast<btCollisionObject *>(proxy0->m_clientObject); - CollisionObjectBullet *gObj = static_cast<CollisionObjectBullet *>(btObj->getUserPointer()); - - if (CollisionObjectBullet::TYPE_AREA == gObj->getType()) { - if (!collide_with_areas) { - return false; - } - } else { - if (!collide_with_bodies) { - return false; - } - } - - if (m_exclude->has(gObj->get_self())) { - return false; - } - return true; - } else { - return false; - } -} - -btScalar GodotRestInfoContactResultCallback::addSingleResult(btManifoldPoint &cp, const btCollisionObjectWrapper *colObj0Wrap, int partId0, int index0, const btCollisionObjectWrapper *colObj1Wrap, int partId1, int index1) { - if (cp.getDistance() <= m_min_distance) { - m_min_distance = cp.getDistance(); - - CollisionObjectBullet *colObj; - if (m_self_object == colObj0Wrap->getCollisionObject()) { - colObj = static_cast<CollisionObjectBullet *>(colObj1Wrap->getCollisionObject()->getUserPointer()); - // Checking for compound shape because the index might be uninitialized otherwise. - // A partId of -1 indicates the index is a shape index and not a triangle index. - if (colObj1Wrap->getCollisionObject()->getCollisionShape()->isCompound() && cp.m_partId1 == -1) { - m_result->shape = cp.m_index1; - } else { - m_result->shape = 0; - } - B_TO_G(cp.getPositionWorldOnB(), m_result->point); - B_TO_G(cp.m_normalWorldOnB, m_result->normal); - m_rest_info_bt_point = cp.getPositionWorldOnB(); - m_rest_info_collision_object = colObj1Wrap->getCollisionObject(); - } else { - colObj = static_cast<CollisionObjectBullet *>(colObj0Wrap->getCollisionObject()->getUserPointer()); - // Checking for compound shape because the index might be uninitialized otherwise. - // A partId of -1 indicates the index is a shape index and not a triangle index. - if (colObj0Wrap->getCollisionObject()->getCollisionShape()->isCompound() && cp.m_partId0 == -1) { - m_result->shape = cp.m_index0; - } else { - m_result->shape = 0; - } - B_TO_G(cp.m_normalWorldOnB * -1, m_result->normal); - m_rest_info_bt_point = cp.getPositionWorldOnA(); - m_rest_info_collision_object = colObj0Wrap->getCollisionObject(); - } - - m_result->collider_id = colObj->get_instance_id(); - m_result->rid = colObj->get_self(); - - m_collided = true; - } - - return 1; // Not used by bullet -} - -void GodotDeepPenetrationContactResultCallback::addContactPoint(const btVector3 &normalOnBInWorld, const btVector3 &pointInWorldOnB, btScalar depth) { - if (m_penetration_distance > depth) { // Has penetration? - - const bool isSwapped = m_manifoldPtr->getBody0() != m_body0Wrap->getCollisionObject(); - m_penetration_distance = depth; - m_other_compound_shape_index = isSwapped ? m_index0 : m_index1; - m_pointWorld = isSwapped ? (pointInWorldOnB + (normalOnBInWorld * depth)) : pointInWorldOnB; - - m_pointNormalWorld = isSwapped ? normalOnBInWorld * -1 : normalOnBInWorld; - } -} diff --git a/modules/bullet/godot_result_callbacks.h b/modules/bullet/godot_result_callbacks.h deleted file mode 100644 index dd64762529..0000000000 --- a/modules/bullet/godot_result_callbacks.h +++ /dev/null @@ -1,225 +0,0 @@ -/*************************************************************************/ -/* godot_result_callbacks.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* 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. */ -/*************************************************************************/ - -#ifndef GODOT_RESULT_CALLBACKS_H -#define GODOT_RESULT_CALLBACKS_H - -#include "servers/physics_server_3d.h" - -#include <BulletCollision/BroadphaseCollision/btBroadphaseProxy.h> -#include <btBulletDynamicsCommon.h> - -class RigidBodyBullet; - -/// This callback is injected inside bullet server and allow me to smooth contacts against trimesh -bool godotContactAddedCallback(btManifoldPoint &cp, const btCollisionObjectWrapper *colObj0Wrap, int partId0, int index0, const btCollisionObjectWrapper *colObj1Wrap, int partId1, int index1); - -/// This class is required to implement custom collision behaviour in the broadphase -struct GodotFilterCallback : public btOverlapFilterCallback { - // return true when pairs need collision - virtual bool needBroadphaseCollision(btBroadphaseProxy *proxy0, btBroadphaseProxy *proxy1) const; -}; - -/// It performs an additional check allow exclusions. -struct GodotClosestRayResultCallback : public btCollisionWorld::ClosestRayResultCallback { - const Set<RID> *m_exclude; - bool m_pickRay = false; - int m_shapeId = 0; - - bool collide_with_bodies = false; - bool collide_with_areas = false; - -public: - GodotClosestRayResultCallback(const btVector3 &rayFromWorld, const btVector3 &rayToWorld, const Set<RID> *p_exclude, bool p_collide_with_bodies, bool p_collide_with_areas) : - btCollisionWorld::ClosestRayResultCallback(rayFromWorld, rayToWorld), - m_exclude(p_exclude), - collide_with_bodies(p_collide_with_bodies), - collide_with_areas(p_collide_with_areas) {} - - virtual bool needsCollision(btBroadphaseProxy *proxy0) const; - - virtual btScalar addSingleResult(btCollisionWorld::LocalRayResult &rayResult, bool normalInWorldSpace) { - // Triangle index is an odd name but contains the compound shape ID. - // A shape part of -1 indicates the index is a shape index and not a triangle index. - if (rayResult.m_localShapeInfo && rayResult.m_localShapeInfo->m_shapePart == -1) { - m_shapeId = rayResult.m_localShapeInfo->m_triangleIndex; - } else { - m_shapeId = 0; - } - return btCollisionWorld::ClosestRayResultCallback::addSingleResult(rayResult, normalInWorldSpace); - } -}; - -// store all colliding object -struct GodotAllConvexResultCallback : public btCollisionWorld::ConvexResultCallback { -public: - PhysicsDirectSpaceState3D::ShapeResult *m_results = nullptr; - int m_resultMax = 0; - const Set<RID> *m_exclude; - int count = 0; - - GodotAllConvexResultCallback(PhysicsDirectSpaceState3D::ShapeResult *p_results, int p_resultMax, const Set<RID> *p_exclude) : - m_results(p_results), - m_resultMax(p_resultMax), - m_exclude(p_exclude) {} - - virtual bool needsCollision(btBroadphaseProxy *proxy0) const; - - virtual btScalar addSingleResult(btCollisionWorld::LocalConvexResult &convexResult, bool normalInWorldSpace); -}; - -struct GodotKinClosestConvexResultCallback : public btCollisionWorld::ClosestConvexResultCallback { -public: - const RigidBodyBullet *m_self_object; - const Set<RID> *m_exclude; - const bool m_infinite_inertia; - - GodotKinClosestConvexResultCallback(const btVector3 &convexFromWorld, const btVector3 &convexToWorld, const RigidBodyBullet *p_self_object, bool p_infinite_inertia, const Set<RID> *p_exclude) : - btCollisionWorld::ClosestConvexResultCallback(convexFromWorld, convexToWorld), - m_self_object(p_self_object), - m_exclude(p_exclude), - m_infinite_inertia(p_infinite_inertia) {} - - virtual bool needsCollision(btBroadphaseProxy *proxy0) const; -}; - -struct GodotClosestConvexResultCallback : public btCollisionWorld::ClosestConvexResultCallback { -public: - const Set<RID> *m_exclude; - int m_shapeId = 0; - - bool collide_with_bodies = false; - bool collide_with_areas = false; - - GodotClosestConvexResultCallback(const btVector3 &convexFromWorld, const btVector3 &convexToWorld, const Set<RID> *p_exclude, bool p_collide_with_bodies, bool p_collide_with_areas) : - btCollisionWorld::ClosestConvexResultCallback(convexFromWorld, convexToWorld), - m_exclude(p_exclude), - collide_with_bodies(p_collide_with_bodies), - collide_with_areas(p_collide_with_areas) {} - - virtual bool needsCollision(btBroadphaseProxy *proxy0) const; - - virtual btScalar addSingleResult(btCollisionWorld::LocalConvexResult &convexResult, bool normalInWorldSpace); -}; - -struct GodotAllContactResultCallback : public btCollisionWorld::ContactResultCallback { -public: - const btCollisionObject *m_self_object; - PhysicsDirectSpaceState3D::ShapeResult *m_results = nullptr; - int m_resultMax = 0; - const Set<RID> *m_exclude; - int m_count = 0; - - bool collide_with_bodies = false; - bool collide_with_areas = false; - - GodotAllContactResultCallback(btCollisionObject *p_self_object, PhysicsDirectSpaceState3D::ShapeResult *p_results, int p_resultMax, const Set<RID> *p_exclude, bool p_collide_with_bodies, bool p_collide_with_areas) : - m_self_object(p_self_object), - m_results(p_results), - m_resultMax(p_resultMax), - m_exclude(p_exclude), - collide_with_bodies(p_collide_with_bodies), - collide_with_areas(p_collide_with_areas) {} - - virtual bool needsCollision(btBroadphaseProxy *proxy0) const; - - virtual btScalar addSingleResult(btManifoldPoint &cp, const btCollisionObjectWrapper *colObj0Wrap, int partId0, int index0, const btCollisionObjectWrapper *colObj1Wrap, int partId1, int index1); -}; - -/// Returns the list of contacts pairs in this order: Local contact, other body contact -struct GodotContactPairContactResultCallback : public btCollisionWorld::ContactResultCallback { -public: - const btCollisionObject *m_self_object; - Vector3 *m_results = nullptr; - int m_resultMax = 0; - const Set<RID> *m_exclude; - int m_count = 0; - - bool collide_with_bodies = false; - bool collide_with_areas = false; - - GodotContactPairContactResultCallback(btCollisionObject *p_self_object, Vector3 *p_results, int p_resultMax, const Set<RID> *p_exclude, bool p_collide_with_bodies, bool p_collide_with_areas) : - m_self_object(p_self_object), - m_results(p_results), - m_resultMax(p_resultMax), - m_exclude(p_exclude), - collide_with_bodies(p_collide_with_bodies), - collide_with_areas(p_collide_with_areas) {} - - virtual bool needsCollision(btBroadphaseProxy *proxy0) const; - - virtual btScalar addSingleResult(btManifoldPoint &cp, const btCollisionObjectWrapper *colObj0Wrap, int partId0, int index0, const btCollisionObjectWrapper *colObj1Wrap, int partId1, int index1); -}; - -struct GodotRestInfoContactResultCallback : public btCollisionWorld::ContactResultCallback { -public: - const btCollisionObject *m_self_object; - PhysicsDirectSpaceState3D::ShapeRestInfo *m_result = nullptr; - const Set<RID> *m_exclude; - bool m_collided = false; - real_t m_min_distance = 0.0; - const btCollisionObject *m_rest_info_collision_object = nullptr; - btVector3 m_rest_info_bt_point; - bool collide_with_bodies = false; - bool collide_with_areas = false; - - GodotRestInfoContactResultCallback(btCollisionObject *p_self_object, PhysicsDirectSpaceState3D::ShapeRestInfo *p_result, const Set<RID> *p_exclude, bool p_collide_with_bodies, bool p_collide_with_areas) : - m_self_object(p_self_object), - m_result(p_result), - m_exclude(p_exclude), - collide_with_bodies(p_collide_with_bodies), - collide_with_areas(p_collide_with_areas) {} - - virtual bool needsCollision(btBroadphaseProxy *proxy0) const; - - virtual btScalar addSingleResult(btManifoldPoint &cp, const btCollisionObjectWrapper *colObj0Wrap, int partId0, int index0, const btCollisionObjectWrapper *colObj1Wrap, int partId1, int index1); -}; - -struct GodotDeepPenetrationContactResultCallback : public btManifoldResult { - btVector3 m_pointNormalWorld; - btVector3 m_pointWorld; - btScalar m_penetration_distance = 0; - int m_other_compound_shape_index = 0; - - GodotDeepPenetrationContactResultCallback(const btCollisionObjectWrapper *body0Wrap, const btCollisionObjectWrapper *body1Wrap) : - btManifoldResult(body0Wrap, body1Wrap) {} - - void reset() { - m_penetration_distance = 0; - } - - bool hasHit() { - return m_penetration_distance < 0; - } - - virtual void addContactPoint(const btVector3 &normalOnBInWorld, const btVector3 &pointInWorldOnB, btScalar depth); -}; - -#endif // GODOT_RESULT_CALLBACKS_H diff --git a/modules/bullet/hinge_joint_bullet.cpp b/modules/bullet/hinge_joint_bullet.cpp deleted file mode 100644 index 0b1bb7890d..0000000000 --- a/modules/bullet/hinge_joint_bullet.cpp +++ /dev/null @@ -1,170 +0,0 @@ -/*************************************************************************/ -/* hinge_joint_bullet.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* 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 "hinge_joint_bullet.h" - -#include "bullet_types_converter.h" -#include "bullet_utilities.h" -#include "rigid_body_bullet.h" - -#include <BulletDynamics/ConstraintSolver/btHingeConstraint.h> - -HingeJointBullet::HingeJointBullet(RigidBodyBullet *rbA, RigidBodyBullet *rbB, const Transform3D &frameA, const Transform3D &frameB) : - JointBullet() { - Transform3D scaled_AFrame(frameA.scaled(rbA->get_body_scale())); - scaled_AFrame.basis.rotref_posscale_decomposition(scaled_AFrame.basis); - - btTransform btFrameA; - G_TO_B(scaled_AFrame, btFrameA); - - if (rbB) { - Transform3D scaled_BFrame(frameB.scaled(rbB->get_body_scale())); - scaled_BFrame.basis.rotref_posscale_decomposition(scaled_BFrame.basis); - - btTransform btFrameB; - G_TO_B(scaled_BFrame, btFrameB); - - hingeConstraint = bulletnew(btHingeConstraint(*rbA->get_bt_rigid_body(), *rbB->get_bt_rigid_body(), btFrameA, btFrameB)); - } else { - hingeConstraint = bulletnew(btHingeConstraint(*rbA->get_bt_rigid_body(), btFrameA)); - } - - setup(hingeConstraint); -} - -HingeJointBullet::HingeJointBullet(RigidBodyBullet *rbA, RigidBodyBullet *rbB, const Vector3 &pivotInA, const Vector3 &pivotInB, const Vector3 &axisInA, const Vector3 &axisInB) : - JointBullet() { - btVector3 btPivotA; - btVector3 btAxisA; - G_TO_B(pivotInA * rbA->get_body_scale(), btPivotA); - G_TO_B(axisInA * rbA->get_body_scale(), btAxisA); - - if (rbB) { - btVector3 btPivotB; - btVector3 btAxisB; - G_TO_B(pivotInB * rbB->get_body_scale(), btPivotB); - G_TO_B(axisInB * rbB->get_body_scale(), btAxisB); - - hingeConstraint = bulletnew(btHingeConstraint(*rbA->get_bt_rigid_body(), *rbB->get_bt_rigid_body(), btPivotA, btPivotB, btAxisA, btAxisB)); - } else { - hingeConstraint = bulletnew(btHingeConstraint(*rbA->get_bt_rigid_body(), btPivotA, btAxisA)); - } - - setup(hingeConstraint); -} - -real_t HingeJointBullet::get_hinge_angle() { - return hingeConstraint->getHingeAngle(); -} - -void HingeJointBullet::set_param(PhysicsServer3D::HingeJointParam p_param, real_t p_value) { - switch (p_param) { - case PhysicsServer3D::HINGE_JOINT_BIAS: - WARN_DEPRECATED_MSG("The HingeJoint3D parameter \"bias\" is deprecated."); - break; - case PhysicsServer3D::HINGE_JOINT_LIMIT_UPPER: - hingeConstraint->setLimit(hingeConstraint->getLowerLimit(), p_value, hingeConstraint->getLimitSoftness(), hingeConstraint->getLimitBiasFactor(), hingeConstraint->getLimitRelaxationFactor()); - break; - case PhysicsServer3D::HINGE_JOINT_LIMIT_LOWER: - hingeConstraint->setLimit(p_value, hingeConstraint->getUpperLimit(), hingeConstraint->getLimitSoftness(), hingeConstraint->getLimitBiasFactor(), hingeConstraint->getLimitRelaxationFactor()); - break; - case PhysicsServer3D::HINGE_JOINT_LIMIT_BIAS: - hingeConstraint->setLimit(hingeConstraint->getLowerLimit(), hingeConstraint->getUpperLimit(), hingeConstraint->getLimitSoftness(), p_value, hingeConstraint->getLimitRelaxationFactor()); - break; - case PhysicsServer3D::HINGE_JOINT_LIMIT_SOFTNESS: - hingeConstraint->setLimit(hingeConstraint->getLowerLimit(), hingeConstraint->getUpperLimit(), p_value, hingeConstraint->getLimitBiasFactor(), hingeConstraint->getLimitRelaxationFactor()); - break; - case PhysicsServer3D::HINGE_JOINT_LIMIT_RELAXATION: - hingeConstraint->setLimit(hingeConstraint->getLowerLimit(), hingeConstraint->getUpperLimit(), hingeConstraint->getLimitSoftness(), hingeConstraint->getLimitBiasFactor(), p_value); - break; - case PhysicsServer3D::HINGE_JOINT_MOTOR_TARGET_VELOCITY: - hingeConstraint->setMotorTargetVelocity(p_value); - break; - case PhysicsServer3D::HINGE_JOINT_MOTOR_MAX_IMPULSE: - hingeConstraint->setMaxMotorImpulse(p_value); - break; - case PhysicsServer3D::HINGE_JOINT_MAX: - // Internal size value, nothing to do. - break; - } -} - -real_t HingeJointBullet::get_param(PhysicsServer3D::HingeJointParam p_param) const { - switch (p_param) { - case PhysicsServer3D::HINGE_JOINT_BIAS: - WARN_DEPRECATED_MSG("The HingeJoint3D parameter \"bias\" is deprecated."); - return 0; - case PhysicsServer3D::HINGE_JOINT_LIMIT_UPPER: - return hingeConstraint->getUpperLimit(); - case PhysicsServer3D::HINGE_JOINT_LIMIT_LOWER: - return hingeConstraint->getLowerLimit(); - case PhysicsServer3D::HINGE_JOINT_LIMIT_BIAS: - return hingeConstraint->getLimitBiasFactor(); - case PhysicsServer3D::HINGE_JOINT_LIMIT_SOFTNESS: - return hingeConstraint->getLimitSoftness(); - case PhysicsServer3D::HINGE_JOINT_LIMIT_RELAXATION: - return hingeConstraint->getLimitRelaxationFactor(); - case PhysicsServer3D::HINGE_JOINT_MOTOR_TARGET_VELOCITY: - return hingeConstraint->getMotorTargetVelocity(); - case PhysicsServer3D::HINGE_JOINT_MOTOR_MAX_IMPULSE: - return hingeConstraint->getMaxMotorImpulse(); - case PhysicsServer3D::HINGE_JOINT_MAX: - // Internal size value, nothing to do. - return 0; - } - // Compiler doesn't seem to notice that all code paths are fulfilled... - return 0; -} - -void HingeJointBullet::set_flag(PhysicsServer3D::HingeJointFlag p_flag, bool p_value) { - switch (p_flag) { - case PhysicsServer3D::HINGE_JOINT_FLAG_USE_LIMIT: - if (!p_value) { - hingeConstraint->setLimit(-Math_PI, Math_PI); - } - break; - case PhysicsServer3D::HINGE_JOINT_FLAG_ENABLE_MOTOR: - hingeConstraint->enableMotor(p_value); - break; - case PhysicsServer3D::HINGE_JOINT_FLAG_MAX: - break; // Can't happen, but silences warning - } -} - -bool HingeJointBullet::get_flag(PhysicsServer3D::HingeJointFlag p_flag) const { - switch (p_flag) { - case PhysicsServer3D::HINGE_JOINT_FLAG_USE_LIMIT: - return true; - case PhysicsServer3D::HINGE_JOINT_FLAG_ENABLE_MOTOR: - return hingeConstraint->getEnableAngularMotor(); - default: - return false; - } -} diff --git a/modules/bullet/hinge_joint_bullet.h b/modules/bullet/hinge_joint_bullet.h deleted file mode 100644 index 5575be564f..0000000000 --- a/modules/bullet/hinge_joint_bullet.h +++ /dev/null @@ -1,54 +0,0 @@ -/*************************************************************************/ -/* hinge_joint_bullet.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* 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. */ -/*************************************************************************/ - -#ifndef HINGE_JOINT_BULLET_H -#define HINGE_JOINT_BULLET_H - -#include "joint_bullet.h" - -class HingeJointBullet : public JointBullet { - class btHingeConstraint *hingeConstraint; - -public: - HingeJointBullet(RigidBodyBullet *rbA, RigidBodyBullet *rbB, const Transform3D &frameA, const Transform3D &frameB); - HingeJointBullet(RigidBodyBullet *rbA, RigidBodyBullet *rbB, const Vector3 &pivotInA, const Vector3 &pivotInB, const Vector3 &axisInA, const Vector3 &axisInB); - - virtual PhysicsServer3D::JointType get_type() const { return PhysicsServer3D::JOINT_HINGE; } - - real_t get_hinge_angle(); - - void set_param(PhysicsServer3D::HingeJointParam p_param, real_t p_value); - real_t get_param(PhysicsServer3D::HingeJointParam p_param) const; - - void set_flag(PhysicsServer3D::HingeJointFlag p_flag, bool p_value); - bool get_flag(PhysicsServer3D::HingeJointFlag p_flag) const; -}; - -#endif // HINGE_JOINT_BULLET_H diff --git a/modules/bullet/joint_bullet.h b/modules/bullet/joint_bullet.h deleted file mode 100644 index 427221dd77..0000000000 --- a/modules/bullet/joint_bullet.h +++ /dev/null @@ -1,48 +0,0 @@ -/*************************************************************************/ -/* joint_bullet.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* 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. */ -/*************************************************************************/ - -#ifndef JOINT_BULLET_H -#define JOINT_BULLET_H - -#include "constraint_bullet.h" -#include "servers/physics_server_3d.h" - -class RigidBodyBullet; -class btTypedConstraint; - -class JointBullet : public ConstraintBullet { -public: - JointBullet() {} - virtual ~JointBullet() {} - - virtual PhysicsServer3D::JointType get_type() const = 0; -}; - -#endif // JOINT_BULLET_H diff --git a/modules/bullet/pin_joint_bullet.cpp b/modules/bullet/pin_joint_bullet.cpp deleted file mode 100644 index 72fdd5c408..0000000000 --- a/modules/bullet/pin_joint_bullet.cpp +++ /dev/null @@ -1,111 +0,0 @@ -/*************************************************************************/ -/* pin_joint_bullet.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* 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 "pin_joint_bullet.h" - -#include "bullet_types_converter.h" -#include "rigid_body_bullet.h" - -#include <BulletDynamics/ConstraintSolver/btPoint2PointConstraint.h> - -PinJointBullet::PinJointBullet(RigidBodyBullet *p_body_a, const Vector3 &p_pos_a, RigidBodyBullet *p_body_b, const Vector3 &p_pos_b) : - JointBullet() { - if (p_body_b) { - btVector3 btPivotA; - btVector3 btPivotB; - G_TO_B(p_pos_a * p_body_a->get_body_scale(), btPivotA); - G_TO_B(p_pos_b * p_body_b->get_body_scale(), btPivotB); - p2pConstraint = bulletnew(btPoint2PointConstraint(*p_body_a->get_bt_rigid_body(), - *p_body_b->get_bt_rigid_body(), - btPivotA, - btPivotB)); - } else { - btVector3 btPivotA; - G_TO_B(p_pos_a, btPivotA); - p2pConstraint = bulletnew(btPoint2PointConstraint(*p_body_a->get_bt_rigid_body(), btPivotA)); - } - - setup(p2pConstraint); -} - -PinJointBullet::~PinJointBullet() {} - -void PinJointBullet::set_param(PhysicsServer3D::PinJointParam p_param, real_t p_value) { - switch (p_param) { - case PhysicsServer3D::PIN_JOINT_BIAS: - p2pConstraint->m_setting.m_tau = p_value; - break; - case PhysicsServer3D::PIN_JOINT_DAMPING: - p2pConstraint->m_setting.m_damping = p_value; - break; - case PhysicsServer3D::PIN_JOINT_IMPULSE_CLAMP: - p2pConstraint->m_setting.m_impulseClamp = p_value; - break; - } -} - -real_t PinJointBullet::get_param(PhysicsServer3D::PinJointParam p_param) const { - switch (p_param) { - case PhysicsServer3D::PIN_JOINT_BIAS: - return p2pConstraint->m_setting.m_tau; - case PhysicsServer3D::PIN_JOINT_DAMPING: - return p2pConstraint->m_setting.m_damping; - case PhysicsServer3D::PIN_JOINT_IMPULSE_CLAMP: - return p2pConstraint->m_setting.m_impulseClamp; - } - // Compiler doesn't seem to notice that all code paths are fulfilled... - return 0; -} - -void PinJointBullet::setPivotInA(const Vector3 &p_pos) { - btVector3 btVec; - G_TO_B(p_pos, btVec); - p2pConstraint->setPivotA(btVec); -} - -void PinJointBullet::setPivotInB(const Vector3 &p_pos) { - btVector3 btVec; - G_TO_B(p_pos, btVec); - p2pConstraint->setPivotB(btVec); -} - -Vector3 PinJointBullet::getPivotInA() { - btVector3 vec = p2pConstraint->getPivotInA(); - Vector3 gVec; - B_TO_G(vec, gVec); - return gVec; -} - -Vector3 PinJointBullet::getPivotInB() { - btVector3 vec = p2pConstraint->getPivotInB(); - Vector3 gVec; - B_TO_G(vec, gVec); - return gVec; -} diff --git a/modules/bullet/pin_joint_bullet.h b/modules/bullet/pin_joint_bullet.h deleted file mode 100644 index 0a688d55f9..0000000000 --- a/modules/bullet/pin_joint_bullet.h +++ /dev/null @@ -1,57 +0,0 @@ -/*************************************************************************/ -/* pin_joint_bullet.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* 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. */ -/*************************************************************************/ - -#ifndef PIN_JOINT_BULLET_H -#define PIN_JOINT_BULLET_H - -#include "joint_bullet.h" - -class RigidBodyBullet; - -class PinJointBullet : public JointBullet { - class btPoint2PointConstraint *p2pConstraint; - -public: - PinJointBullet(RigidBodyBullet *p_body_a, const Vector3 &p_pos_a, RigidBodyBullet *p_body_b, const Vector3 &p_pos_b); - ~PinJointBullet(); - - virtual PhysicsServer3D::JointType get_type() const { return PhysicsServer3D::JOINT_PIN; } - - void set_param(PhysicsServer3D::PinJointParam p_param, real_t p_value); - real_t get_param(PhysicsServer3D::PinJointParam p_param) const; - - void setPivotInA(const Vector3 &p_pos); - void setPivotInB(const Vector3 &p_pos); - - Vector3 getPivotInA(); - Vector3 getPivotInB(); -}; - -#endif // PIN_JOINT_BULLET_H diff --git a/modules/bullet/register_types.cpp b/modules/bullet/register_types.cpp deleted file mode 100644 index d5d0ee2cf4..0000000000 --- a/modules/bullet/register_types.cpp +++ /dev/null @@ -1,54 +0,0 @@ -/*************************************************************************/ -/* register_types.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* 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 "register_types.h" - -#include "bullet_physics_server.h" -#include "core/config/project_settings.h" -#include "core/object/class_db.h" - -#ifndef _3D_DISABLED -PhysicsServer3D *_createBulletPhysicsCallback() { - return memnew(BulletPhysicsServer3D); -} -#endif - -void register_bullet_types() { -#ifndef _3D_DISABLED - PhysicsServer3DManager::register_server("Bullet", &_createBulletPhysicsCallback); - PhysicsServer3DManager::set_default_server("Bullet", 1); - - GLOBAL_DEF("physics/3d/active_soft_world", true); - ProjectSettings::get_singleton()->set_custom_property_info("physics/3d/active_soft_world", PropertyInfo(Variant::BOOL, "physics/3d/active_soft_world")); -#endif -} - -void unregister_bullet_types() { -} diff --git a/modules/bullet/register_types.h b/modules/bullet/register_types.h deleted file mode 100644 index 93847d6dc3..0000000000 --- a/modules/bullet/register_types.h +++ /dev/null @@ -1,37 +0,0 @@ -/*************************************************************************/ -/* register_types.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* 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. */ -/*************************************************************************/ - -#ifndef REGISTER_BULLET_TYPES_H -#define REGISTER_BULLET_TYPES_H - -void register_bullet_types(); -void unregister_bullet_types(); - -#endif // REGISTER_BULLET_TYPES_H diff --git a/modules/bullet/rid_bullet.h b/modules/bullet/rid_bullet.h deleted file mode 100644 index 260d303cac..0000000000 --- a/modules/bullet/rid_bullet.h +++ /dev/null @@ -1,50 +0,0 @@ -/*************************************************************************/ -/* rid_bullet.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* 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. */ -/*************************************************************************/ - -#ifndef RID_BULLET_H -#define RID_BULLET_H - -#include "core/templates/rid.h" - -class BulletPhysicsServer3D; - -class RIDBullet { - RID self; - BulletPhysicsServer3D *physicsServer = nullptr; - -public: - _FORCE_INLINE_ void set_self(const RID &p_self) { self = p_self; } - _FORCE_INLINE_ RID get_self() const { return self; } - - _FORCE_INLINE_ void _set_physics_server(BulletPhysicsServer3D *p_physicsServer) { physicsServer = p_physicsServer; } - _FORCE_INLINE_ BulletPhysicsServer3D *get_physics_server() const { return physicsServer; } -}; - -#endif // RID_BULLET_H diff --git a/modules/bullet/rigid_body_bullet.cpp b/modules/bullet/rigid_body_bullet.cpp deleted file mode 100644 index 0603963332..0000000000 --- a/modules/bullet/rigid_body_bullet.cpp +++ /dev/null @@ -1,1050 +0,0 @@ -/*************************************************************************/ -/* rigid_body_bullet.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* 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 "rigid_body_bullet.h" - -#include "btRayShape.h" -#include "bullet_physics_server.h" -#include "bullet_types_converter.h" -#include "bullet_utilities.h" -#include "godot_motion_state.h" -#include "joint_bullet.h" - -#include <BulletCollision/CollisionDispatch/btGhostObject.h> -#include <BulletCollision/CollisionShapes/btConvexPointCloudShape.h> -#include <BulletDynamics/Dynamics/btRigidBody.h> -#include <btBulletCollisionCommon.h> - -BulletPhysicsDirectBodyState3D *BulletPhysicsDirectBodyState3D::singleton = nullptr; - -Vector3 BulletPhysicsDirectBodyState3D::get_total_gravity() const { - Vector3 gVec; - B_TO_G(body->btBody->getGravity(), gVec); - return gVec; -} - -real_t BulletPhysicsDirectBodyState3D::get_total_angular_damp() const { - return body->btBody->getAngularDamping(); -} - -real_t BulletPhysicsDirectBodyState3D::get_total_linear_damp() const { - return body->btBody->getLinearDamping(); -} - -Vector3 BulletPhysicsDirectBodyState3D::get_center_of_mass() const { - Vector3 gVec; - B_TO_G(body->btBody->getCenterOfMassPosition(), gVec); - return gVec; -} - -Basis BulletPhysicsDirectBodyState3D::get_principal_inertia_axes() const { - return Basis(); -} - -real_t BulletPhysicsDirectBodyState3D::get_inverse_mass() const { - return body->btBody->getInvMass(); -} - -Vector3 BulletPhysicsDirectBodyState3D::get_inverse_inertia() const { - Vector3 gVec; - B_TO_G(body->btBody->getInvInertiaDiagLocal(), gVec); - return gVec; -} - -Basis BulletPhysicsDirectBodyState3D::get_inverse_inertia_tensor() const { - Basis gInertia; - B_TO_G(body->btBody->getInvInertiaTensorWorld(), gInertia); - return gInertia; -} - -void BulletPhysicsDirectBodyState3D::set_linear_velocity(const Vector3 &p_velocity) { - body->set_linear_velocity(p_velocity); -} - -Vector3 BulletPhysicsDirectBodyState3D::get_linear_velocity() const { - return body->get_linear_velocity(); -} - -void BulletPhysicsDirectBodyState3D::set_angular_velocity(const Vector3 &p_velocity) { - body->set_angular_velocity(p_velocity); -} - -Vector3 BulletPhysicsDirectBodyState3D::get_angular_velocity() const { - return body->get_angular_velocity(); -} - -void BulletPhysicsDirectBodyState3D::set_transform(const Transform3D &p_transform) { - body->set_transform(p_transform); -} - -Transform3D BulletPhysicsDirectBodyState3D::get_transform() const { - return body->get_transform(); -} - -Vector3 BulletPhysicsDirectBodyState3D::get_velocity_at_local_position(const Vector3 &p_position) const { - btVector3 local_position; - G_TO_B(p_position, local_position); - - Vector3 velocity; - B_TO_G(body->btBody->getVelocityInLocalPoint(local_position), velocity); - - return velocity; -} - -void BulletPhysicsDirectBodyState3D::add_central_force(const Vector3 &p_force) { - body->apply_central_force(p_force); -} - -void BulletPhysicsDirectBodyState3D::add_force(const Vector3 &p_force, const Vector3 &p_position) { - body->apply_force(p_force, p_position); -} - -void BulletPhysicsDirectBodyState3D::add_torque(const Vector3 &p_torque) { - body->apply_torque(p_torque); -} - -void BulletPhysicsDirectBodyState3D::apply_central_impulse(const Vector3 &p_impulse) { - body->apply_central_impulse(p_impulse); -} - -void BulletPhysicsDirectBodyState3D::apply_impulse(const Vector3 &p_impulse, const Vector3 &p_position) { - body->apply_impulse(p_impulse, p_position); -} - -void BulletPhysicsDirectBodyState3D::apply_torque_impulse(const Vector3 &p_impulse) { - body->apply_torque_impulse(p_impulse); -} - -void BulletPhysicsDirectBodyState3D::set_sleep_state(bool p_sleep) { - body->set_activation_state(!p_sleep); -} - -bool BulletPhysicsDirectBodyState3D::is_sleeping() const { - return !body->is_active(); -} - -int BulletPhysicsDirectBodyState3D::get_contact_count() const { - return body->collisionsCount; -} - -Vector3 BulletPhysicsDirectBodyState3D::get_contact_local_position(int p_contact_idx) const { - return body->collisions[p_contact_idx].hitLocalLocation; -} - -Vector3 BulletPhysicsDirectBodyState3D::get_contact_local_normal(int p_contact_idx) const { - return body->collisions[p_contact_idx].hitNormal; -} - -real_t BulletPhysicsDirectBodyState3D::get_contact_impulse(int p_contact_idx) const { - return body->collisions[p_contact_idx].appliedImpulse; -} - -int BulletPhysicsDirectBodyState3D::get_contact_local_shape(int p_contact_idx) const { - return body->collisions[p_contact_idx].local_shape; -} - -RID BulletPhysicsDirectBodyState3D::get_contact_collider(int p_contact_idx) const { - return body->collisions[p_contact_idx].otherObject->get_self(); -} - -Vector3 BulletPhysicsDirectBodyState3D::get_contact_collider_position(int p_contact_idx) const { - return body->collisions[p_contact_idx].hitWorldLocation; -} - -ObjectID BulletPhysicsDirectBodyState3D::get_contact_collider_id(int p_contact_idx) const { - return body->collisions[p_contact_idx].otherObject->get_instance_id(); -} - -int BulletPhysicsDirectBodyState3D::get_contact_collider_shape(int p_contact_idx) const { - return body->collisions[p_contact_idx].other_object_shape; -} - -Vector3 BulletPhysicsDirectBodyState3D::get_contact_collider_velocity_at_position(int p_contact_idx) const { - RigidBodyBullet::CollisionData &colDat = body->collisions.write[p_contact_idx]; - - btVector3 hitLocation; - G_TO_B(colDat.hitLocalLocation, hitLocation); - - Vector3 velocityAtPoint; - B_TO_G(colDat.otherObject->get_bt_rigid_body()->getVelocityInLocalPoint(hitLocation), velocityAtPoint); - - return velocityAtPoint; -} - -PhysicsDirectSpaceState3D *BulletPhysicsDirectBodyState3D::get_space_state() { - return body->get_space()->get_direct_state(); -} - -RigidBodyBullet::KinematicUtilities::KinematicUtilities(RigidBodyBullet *p_owner) : - owner(p_owner), - safe_margin(0.001) { -} - -RigidBodyBullet::KinematicUtilities::~KinematicUtilities() { - just_delete_shapes(shapes.size()); // don't need to resize -} - -void RigidBodyBullet::KinematicUtilities::setSafeMargin(btScalar p_margin) { - safe_margin = p_margin; - copyAllOwnerShapes(); -} - -void RigidBodyBullet::KinematicUtilities::copyAllOwnerShapes() { - const Vector<CollisionObjectBullet::ShapeWrapper> &shapes_wrappers(owner->get_shapes_wrappers()); - const int shapes_count = shapes_wrappers.size(); - - just_delete_shapes(shapes_count); - - const CollisionObjectBullet::ShapeWrapper *shape_wrapper; - - btVector3 owner_scale(owner->get_bt_body_scale()); - - for (int i = shapes_count - 1; 0 <= i; --i) { - shape_wrapper = &shapes_wrappers[i]; - if (!shape_wrapper->active) { - continue; - } - - shapes.write[i].transform = shape_wrapper->transform; - shapes.write[i].transform.getOrigin() *= owner_scale; - switch (shape_wrapper->shape->get_type()) { - case PhysicsServer3D::SHAPE_SPHERE: - case PhysicsServer3D::SHAPE_BOX: - case PhysicsServer3D::SHAPE_CAPSULE: - case PhysicsServer3D::SHAPE_CYLINDER: - case PhysicsServer3D::SHAPE_CONVEX_POLYGON: - case PhysicsServer3D::SHAPE_RAY: { - shapes.write[i].shape = static_cast<btConvexShape *>(shape_wrapper->shape->create_bt_shape(owner_scale * shape_wrapper->scale, safe_margin)); - } break; - default: - WARN_PRINT("This shape is not supported for kinematic collision."); - shapes.write[i].shape = nullptr; - } - } -} - -void RigidBodyBullet::KinematicUtilities::just_delete_shapes(int new_size) { - for (int i = shapes.size() - 1; 0 <= i; --i) { - if (shapes[i].shape) { - bulletdelete(shapes.write[i].shape); - } - } - shapes.resize(new_size); -} - -RigidBodyBullet::RigidBodyBullet() : - RigidCollisionObjectBullet(CollisionObjectBullet::TYPE_RIGID_BODY) { - godotMotionState = bulletnew(GodotMotionState(this)); - - // Initial properties - const btVector3 localInertia(0, 0, 0); - btRigidBody::btRigidBodyConstructionInfo cInfo(mass, godotMotionState, nullptr, localInertia); - - btBody = bulletnew(btRigidBody(cInfo)); - btBody->setFriction(1.0); - reload_shapes(); - setupBulletCollisionObject(btBody); - - set_mode(PhysicsServer3D::BODY_MODE_DYNAMIC); - reload_axis_lock(); - - areasWhereIam.resize(maxAreasWhereIam); - for (int i = areasWhereIam.size() - 1; 0 <= i; --i) { - areasWhereIam.write[i] = nullptr; - } - btBody->setSleepingThresholds(0.2, 0.2); - - prev_collision_traces = &collision_traces_1; - curr_collision_traces = &collision_traces_2; -} - -RigidBodyBullet::~RigidBodyBullet() { - bulletdelete(godotMotionState); - - if (force_integration_callback) { - memdelete(force_integration_callback); - } - - destroy_kinematic_utilities(); -} - -void RigidBodyBullet::init_kinematic_utilities() { - kinematic_utilities = memnew(KinematicUtilities(this)); - reload_kinematic_shapes(); -} - -void RigidBodyBullet::destroy_kinematic_utilities() { - if (kinematic_utilities) { - memdelete(kinematic_utilities); - kinematic_utilities = nullptr; - } -} - -void RigidBodyBullet::main_shape_changed() { - CRASH_COND(!get_main_shape()); - btBody->setCollisionShape(get_main_shape()); - set_continuous_collision_detection(is_continuous_collision_detection_enabled()); // Reset -} - -void RigidBodyBullet::reload_body() { - if (space) { - space->remove_rigid_body(this); - if (get_main_shape()) { - space->add_rigid_body(this); - } - } -} - -void RigidBodyBullet::set_space(SpaceBullet *p_space) { - // Clear the old space if there is one - if (space) { - can_integrate_forces = false; - isScratchedSpaceOverrideModificator = false; - // Remove any constraints - space->remove_rigid_body_constraints(this); - // Remove this object form the physics world - space->remove_rigid_body(this); - } - - space = p_space; - - if (space) { - space->add_rigid_body(this); - } -} - -void RigidBodyBullet::dispatch_callbacks() { - /// The check isFirstTransformChanged is necessary in order to call integrated forces only when the first transform is sent - if ((btBody->isKinematicObject() || btBody->isActive() || previousActiveState != btBody->isActive()) && force_integration_callback && can_integrate_forces) { - if (omit_forces_integration) { - btBody->clearForces(); - } - - BulletPhysicsDirectBodyState3D *bodyDirect = BulletPhysicsDirectBodyState3D::get_singleton(this); - - Variant variantBodyDirect = bodyDirect; - - Object *obj = force_integration_callback->callable.get_object(); - if (!obj) { - // Remove integration callback - set_force_integration_callback(Callable()); - } else { - const Variant *vp[2] = { &variantBodyDirect, &force_integration_callback->udata }; - - Callable::CallError responseCallError; - int argc = (force_integration_callback->udata.get_type() == Variant::NIL) ? 1 : 2; - Variant rv; - force_integration_callback->callable.call(vp, argc, rv, responseCallError); - } - } - - if (isScratchedSpaceOverrideModificator || 0 < countGravityPointSpaces) { - isScratchedSpaceOverrideModificator = false; - reload_space_override_modificator(); - } - - /// Lock axis - btBody->setLinearVelocity(btBody->getLinearVelocity() * btBody->getLinearFactor()); - btBody->setAngularVelocity(btBody->getAngularVelocity() * btBody->getAngularFactor()); - - previousActiveState = btBody->isActive(); -} - -void RigidBodyBullet::set_force_integration_callback(const Callable &p_callable, const Variant &p_udata) { - if (force_integration_callback) { - memdelete(force_integration_callback); - force_integration_callback = nullptr; - } - - if (p_callable.get_object()) { - force_integration_callback = memnew(ForceIntegrationCallback); - force_integration_callback->callable = p_callable; - force_integration_callback->udata = p_udata; - } -} - -void RigidBodyBullet::scratch_space_override_modificator() { - isScratchedSpaceOverrideModificator = true; -} - -void RigidBodyBullet::on_collision_filters_change() { - if (space) { - space->reload_collision_filters(this); - } - - set_activation_state(true); -} - -void RigidBodyBullet::on_collision_checker_start() { - prev_collision_count = collisionsCount; - collisionsCount = 0; - - // Swap array - Vector<RigidBodyBullet *> *s = prev_collision_traces; - prev_collision_traces = curr_collision_traces; - curr_collision_traces = s; -} - -void RigidBodyBullet::on_collision_checker_end() { - // Always true if active and not a static or kinematic body - updated = btBody->isActive() && !btBody->isStaticOrKinematicObject(); -} - -bool RigidBodyBullet::add_collision_object(RigidBodyBullet *p_otherObject, const Vector3 &p_hitWorldLocation, const Vector3 &p_hitLocalLocation, const Vector3 &p_hitNormal, const real_t &p_appliedImpulse, int p_other_shape_index, int p_local_shape_index) { - if (collisionsCount >= maxCollisionsDetection) { - return false; - } - - CollisionData &cd = collisions.write[collisionsCount]; - cd.hitLocalLocation = p_hitLocalLocation; - cd.otherObject = p_otherObject; - cd.hitWorldLocation = p_hitWorldLocation; - cd.hitNormal = p_hitNormal; - cd.appliedImpulse = p_appliedImpulse; - cd.other_object_shape = p_other_shape_index; - cd.local_shape = p_local_shape_index; - - curr_collision_traces->write[collisionsCount] = p_otherObject; - - ++collisionsCount; - return true; -} - -bool RigidBodyBullet::was_colliding(RigidBodyBullet *p_other_object) { - for (int i = prev_collision_count - 1; 0 <= i; --i) { - if ((*prev_collision_traces)[i] == p_other_object) { - return true; - } - } - return false; -} - -void RigidBodyBullet::set_activation_state(bool p_active) { - if (p_active) { - btBody->activate(); - } else { - btBody->setActivationState(WANTS_DEACTIVATION); - } -} - -bool RigidBodyBullet::is_active() const { - return btBody->isActive(); -} - -void RigidBodyBullet::set_omit_forces_integration(bool p_omit) { - omit_forces_integration = p_omit; -} - -void RigidBodyBullet::set_param(PhysicsServer3D::BodyParameter p_param, real_t p_value) { - switch (p_param) { - case PhysicsServer3D::BODY_PARAM_BOUNCE: - btBody->setRestitution(p_value); - break; - case PhysicsServer3D::BODY_PARAM_FRICTION: - btBody->setFriction(p_value); - break; - case PhysicsServer3D::BODY_PARAM_MASS: { - ERR_FAIL_COND(p_value < 0); - mass = p_value; - _internal_set_mass(p_value); - break; - } - case PhysicsServer3D::BODY_PARAM_LINEAR_DAMP: - linearDamp = p_value; - // Mark for updating total linear damping. - scratch_space_override_modificator(); - break; - case PhysicsServer3D::BODY_PARAM_ANGULAR_DAMP: - angularDamp = p_value; - // Mark for updating total angular damping. - scratch_space_override_modificator(); - break; - case PhysicsServer3D::BODY_PARAM_GRAVITY_SCALE: - gravity_scale = p_value; - // The Bullet gravity will be is set by reload_space_override_modificator. - // Mark for updating total gravity scale. - scratch_space_override_modificator(); - break; - default: - WARN_PRINT("Parameter " + itos(p_param) + " not supported by bullet. Value: " + itos(p_value)); - } -} - -real_t RigidBodyBullet::get_param(PhysicsServer3D::BodyParameter p_param) const { - switch (p_param) { - case PhysicsServer3D::BODY_PARAM_BOUNCE: - return btBody->getRestitution(); - case PhysicsServer3D::BODY_PARAM_FRICTION: - return btBody->getFriction(); - case PhysicsServer3D::BODY_PARAM_MASS: { - const btScalar invMass = btBody->getInvMass(); - return 0 == invMass ? 0 : 1 / invMass; - } - case PhysicsServer3D::BODY_PARAM_LINEAR_DAMP: - return linearDamp; - case PhysicsServer3D::BODY_PARAM_ANGULAR_DAMP: - return angularDamp; - case PhysicsServer3D::BODY_PARAM_GRAVITY_SCALE: - return gravity_scale; - default: - WARN_PRINT("Parameter " + itos(p_param) + " not supported by bullet"); - return 0; - } -} - -void RigidBodyBullet::set_mode(PhysicsServer3D::BodyMode p_mode) { - // This is necessary to block force_integration until next move - can_integrate_forces = false; - destroy_kinematic_utilities(); - // The mode change is relevant to its mass - mode = p_mode; - switch (p_mode) { - case PhysicsServer3D::BODY_MODE_KINEMATIC: - reload_axis_lock(); - _internal_set_mass(0); - init_kinematic_utilities(); - break; - case PhysicsServer3D::BODY_MODE_STATIC: - reload_axis_lock(); - _internal_set_mass(0); - break; - case PhysicsServer3D::BODY_MODE_DYNAMIC: - reload_axis_lock(); - _internal_set_mass(0 == mass ? 1 : mass); - scratch_space_override_modificator(); - break; - case PhysicsServer3D::MODE_DYNAMIC_LINEAR: - reload_axis_lock(); - _internal_set_mass(0 == mass ? 1 : mass); - scratch_space_override_modificator(); - break; - } - - btBody->setAngularVelocity(btVector3(0, 0, 0)); - btBody->setLinearVelocity(btVector3(0, 0, 0)); -} - -PhysicsServer3D::BodyMode RigidBodyBullet::get_mode() const { - return mode; -} - -void RigidBodyBullet::set_state(PhysicsServer3D::BodyState p_state, const Variant &p_variant) { - switch (p_state) { - case PhysicsServer3D::BODY_STATE_TRANSFORM: - set_transform(p_variant); - break; - case PhysicsServer3D::BODY_STATE_LINEAR_VELOCITY: - set_linear_velocity(p_variant); - break; - case PhysicsServer3D::BODY_STATE_ANGULAR_VELOCITY: - set_angular_velocity(p_variant); - break; - case PhysicsServer3D::BODY_STATE_SLEEPING: - set_activation_state(!bool(p_variant)); - break; - case PhysicsServer3D::BODY_STATE_CAN_SLEEP: - can_sleep = bool(p_variant); - if (!can_sleep) { - // Can't sleep - btBody->forceActivationState(DISABLE_DEACTIVATION); - } else { - btBody->forceActivationState(ACTIVE_TAG); - } - break; - } -} - -Variant RigidBodyBullet::get_state(PhysicsServer3D::BodyState p_state) const { - switch (p_state) { - case PhysicsServer3D::BODY_STATE_TRANSFORM: - return get_transform(); - case PhysicsServer3D::BODY_STATE_LINEAR_VELOCITY: - return get_linear_velocity(); - case PhysicsServer3D::BODY_STATE_ANGULAR_VELOCITY: - return get_angular_velocity(); - case PhysicsServer3D::BODY_STATE_SLEEPING: - return !is_active(); - case PhysicsServer3D::BODY_STATE_CAN_SLEEP: - return can_sleep; - default: - WARN_PRINT("This state " + itos(p_state) + " is not supported by Bullet"); - return Variant(); - } -} - -void RigidBodyBullet::apply_central_impulse(const Vector3 &p_impulse) { - btVector3 btImpulse; - G_TO_B(p_impulse, btImpulse); - if (Vector3() != p_impulse) { - btBody->activate(); - } - btBody->applyCentralImpulse(btImpulse); -} - -void RigidBodyBullet::apply_impulse(const Vector3 &p_impulse, const Vector3 &p_position) { - btVector3 btImpulse; - btVector3 btPosition; - G_TO_B(p_impulse, btImpulse); - G_TO_B(p_position, btPosition); - if (Vector3() != p_impulse) { - btBody->activate(); - } - btBody->applyImpulse(btImpulse, btPosition); -} - -void RigidBodyBullet::apply_torque_impulse(const Vector3 &p_impulse) { - btVector3 btImp; - G_TO_B(p_impulse, btImp); - if (Vector3() != p_impulse) { - btBody->activate(); - } - btBody->applyTorqueImpulse(btImp); -} - -void RigidBodyBullet::apply_force(const Vector3 &p_force, const Vector3 &p_position) { - btVector3 btForce; - btVector3 btPosition; - G_TO_B(p_force, btForce); - G_TO_B(p_position, btPosition); - if (Vector3() != p_force) { - btBody->activate(); - } - btBody->applyForce(btForce, btPosition); -} - -void RigidBodyBullet::apply_central_force(const Vector3 &p_force) { - btVector3 btForce; - G_TO_B(p_force, btForce); - if (Vector3() != p_force) { - btBody->activate(); - } - btBody->applyCentralForce(btForce); -} - -void RigidBodyBullet::apply_torque(const Vector3 &p_torque) { - btVector3 btTorq; - G_TO_B(p_torque, btTorq); - if (Vector3() != p_torque) { - btBody->activate(); - } - btBody->applyTorque(btTorq); -} - -void RigidBodyBullet::set_applied_force(const Vector3 &p_force) { - btVector3 btVec = btBody->getTotalTorque(); - - if (Vector3() != p_force) { - btBody->activate(); - } - - btBody->clearForces(); - btBody->applyTorque(btVec); - - G_TO_B(p_force, btVec); - btBody->applyCentralForce(btVec); -} - -Vector3 RigidBodyBullet::get_applied_force() const { - Vector3 gTotForc; - B_TO_G(btBody->getTotalForce(), gTotForc); - return gTotForc; -} - -void RigidBodyBullet::set_applied_torque(const Vector3 &p_torque) { - btVector3 btVec = btBody->getTotalForce(); - - if (Vector3() != p_torque) { - btBody->activate(); - } - - btBody->clearForces(); - btBody->applyCentralForce(btVec); - - G_TO_B(p_torque, btVec); - btBody->applyTorque(btVec); -} - -Vector3 RigidBodyBullet::get_applied_torque() const { - Vector3 gTotTorq; - B_TO_G(btBody->getTotalTorque(), gTotTorq); - return gTotTorq; -} - -void RigidBodyBullet::set_axis_lock(PhysicsServer3D::BodyAxis p_axis, bool lock) { - if (lock) { - locked_axis |= p_axis; - } else { - locked_axis &= ~p_axis; - } - - reload_axis_lock(); -} - -bool RigidBodyBullet::is_axis_locked(PhysicsServer3D::BodyAxis p_axis) const { - return locked_axis & p_axis; -} - -void RigidBodyBullet::reload_axis_lock() { - btBody->setLinearFactor(btVector3(btScalar(!is_axis_locked(PhysicsServer3D::BODY_AXIS_LINEAR_X)), btScalar(!is_axis_locked(PhysicsServer3D::BODY_AXIS_LINEAR_Y)), btScalar(!is_axis_locked(PhysicsServer3D::BODY_AXIS_LINEAR_Z)))); - if (PhysicsServer3D::MODE_DYNAMIC_LINEAR == mode) { - /// When character angular is always locked - btBody->setAngularFactor(btVector3(0., 0., 0.)); - } else { - btBody->setAngularFactor(btVector3(btScalar(!is_axis_locked(PhysicsServer3D::BODY_AXIS_ANGULAR_X)), btScalar(!is_axis_locked(PhysicsServer3D::BODY_AXIS_ANGULAR_Y)), btScalar(!is_axis_locked(PhysicsServer3D::BODY_AXIS_ANGULAR_Z)))); - } -} - -void RigidBodyBullet::set_continuous_collision_detection(bool p_enable) { - if (p_enable) { - // This threshold enable CCD if the object moves more than - // 1 meter in one simulation frame - btBody->setCcdMotionThreshold(1e-7); - - /// Calculate using the rule write below the CCD swept sphere radius - /// CCD works on an embedded sphere of radius, make sure this radius - /// is embedded inside the convex objects, preferably smaller: - /// for an object of dimensions 1 meter, try 0.2 - btScalar radius(1.0); - if (btBody->getCollisionShape()) { - btVector3 center; - btBody->getCollisionShape()->getBoundingSphere(center, radius); - } - btBody->setCcdSweptSphereRadius(radius * 0.2); - } else { - btBody->setCcdMotionThreshold(0.); - btBody->setCcdSweptSphereRadius(0.); - } -} - -bool RigidBodyBullet::is_continuous_collision_detection_enabled() const { - return 0. < btBody->getCcdMotionThreshold(); -} - -void RigidBodyBullet::set_linear_velocity(const Vector3 &p_velocity) { - btVector3 btVec; - G_TO_B(p_velocity, btVec); - if (Vector3() != p_velocity) { - btBody->activate(); - } - btBody->setLinearVelocity(btVec); -} - -Vector3 RigidBodyBullet::get_linear_velocity() const { - Vector3 gVec; - B_TO_G(btBody->getLinearVelocity(), gVec); - return gVec; -} - -void RigidBodyBullet::set_angular_velocity(const Vector3 &p_velocity) { - btVector3 btVec; - G_TO_B(p_velocity, btVec); - if (Vector3() != p_velocity) { - btBody->activate(); - } - btBody->setAngularVelocity(btVec); -} - -Vector3 RigidBodyBullet::get_angular_velocity() const { - Vector3 gVec; - B_TO_G(btBody->getAngularVelocity(), gVec); - return gVec; -} - -void RigidBodyBullet::set_transform__bullet(const btTransform &p_global_transform) { - if (mode == PhysicsServer3D::BODY_MODE_KINEMATIC) { - if (space && space->get_delta_time() != 0) { - btBody->setLinearVelocity((p_global_transform.getOrigin() - btBody->getWorldTransform().getOrigin()) / space->get_delta_time()); - } - // The kinematic use MotionState class - godotMotionState->moveBody(p_global_transform); - } else { - // Is necessary to avoid wrong location on the rendering side on the next frame - godotMotionState->setWorldTransform(p_global_transform); - } - CollisionObjectBullet::set_transform__bullet(p_global_transform); -} - -const btTransform &RigidBodyBullet::get_transform__bullet() const { - if (is_static()) { - return RigidCollisionObjectBullet::get_transform__bullet(); - } else { - return godotMotionState->getCurrentWorldTransform(); - } -} - -void RigidBodyBullet::reload_shapes() { - RigidCollisionObjectBullet::reload_shapes(); - - const btScalar invMass = btBody->getInvMass(); - const btScalar mass = invMass == 0 ? 0 : 1 / invMass; - - if (mainShape) { - // inertia initialised zero here because some of bullet's collision - // shapes incorrectly do not set the vector in calculateLocalIntertia. - // Arbitrary zero is preferable to undefined behaviour. - btVector3 inertia(0, 0, 0); - if (EMPTY_SHAPE_PROXYTYPE != mainShape->getShapeType()) { // Necessary to avoid assertion of the empty shape - mainShape->calculateLocalInertia(mass, inertia); - } - btBody->setMassProps(mass, inertia); - } - btBody->updateInertiaTensor(); - - reload_kinematic_shapes(); - set_continuous_collision_detection(is_continuous_collision_detection_enabled()); - reload_body(); -} - -void RigidBodyBullet::on_enter_area(AreaBullet *p_area) { - /// Add this area to the array in an ordered way - ++areaWhereIamCount; - if (areaWhereIamCount >= maxAreasWhereIam) { - --areaWhereIamCount; - return; - } - for (int i = 0; i < areaWhereIamCount; ++i) { - if (nullptr == areasWhereIam[i]) { - // This area has the highest priority - areasWhereIam.write[i] = p_area; - break; - } else { - if (areasWhereIam[i]->get_spOv_priority() > p_area->get_spOv_priority()) { - // The position was found, just shift all elements - for (int j = areaWhereIamCount; j > i; j--) { - areasWhereIam.write[j] = areasWhereIam[j - 1]; - } - areasWhereIam.write[i] = p_area; - break; - } - } - } - if (PhysicsServer3D::AREA_SPACE_OVERRIDE_DISABLED != p_area->get_spOv_mode()) { - scratch_space_override_modificator(); - } - - if (p_area->is_spOv_gravityPoint()) { - ++countGravityPointSpaces; - ERR_FAIL_COND(countGravityPointSpaces <= 0); - } -} - -void RigidBodyBullet::on_exit_area(AreaBullet *p_area) { - RigidCollisionObjectBullet::on_exit_area(p_area); - /// Remove this area and keep the order - /// N.B. Since I don't want resize the array I can't use the "erase" function - bool wasTheAreaFound = false; - for (int i = 0; i < areaWhereIamCount; ++i) { - if (p_area == areasWhereIam[i]) { - // The area was found, just shift down all elements - for (int j = i; j < areaWhereIamCount; ++j) { - areasWhereIam.write[j] = areasWhereIam[j + 1]; - } - wasTheAreaFound = true; - break; - } - } - if (wasTheAreaFound) { - if (p_area->is_spOv_gravityPoint()) { - --countGravityPointSpaces; - ERR_FAIL_COND(countGravityPointSpaces < 0); - } - - --areaWhereIamCount; - areasWhereIam.write[areaWhereIamCount] = nullptr; // Even if this is not required, I clear the last element to be safe - if (PhysicsServer3D::AREA_SPACE_OVERRIDE_DISABLED != p_area->get_spOv_mode()) { - scratch_space_override_modificator(); - } - } -} - -void RigidBodyBullet::reload_space_override_modificator() { - if (mode == PhysicsServer3D::BODY_MODE_STATIC) { - return; - } - - Vector3 newGravity(0.0, 0.0, 0.0); - real_t newLinearDamp = MAX(0.0, linearDamp); - real_t newAngularDamp = MAX(0.0, angularDamp); - - AreaBullet *currentArea; - // Variable used to calculate new gravity for gravity point areas, it is pointed by currentGravity pointer - Vector3 support_gravity(0, 0, 0); - - bool stopped = false; - for (int i = areaWhereIamCount - 1; (0 <= i) && !stopped; --i) { - currentArea = areasWhereIam[i]; - - if (!currentArea || PhysicsServer3D::AREA_SPACE_OVERRIDE_DISABLED == currentArea->get_spOv_mode()) { - continue; - } - - /// Here is calculated the gravity - if (currentArea->is_spOv_gravityPoint()) { - /// It calculates the direction of new gravity - support_gravity = currentArea->get_transform().xform(currentArea->get_spOv_gravityVec()) - get_transform().get_origin(); - real_t distanceMag = support_gravity.length(); - // Normalized in this way to avoid the double call of function "length()" - if (distanceMag == 0) { - support_gravity.x = 0; - support_gravity.y = 0; - support_gravity.z = 0; - } else { - support_gravity.x /= distanceMag; - support_gravity.y /= distanceMag; - support_gravity.z /= distanceMag; - } - - /// Here is calculated the final gravity - if (currentArea->get_spOv_gravityPointDistanceScale() > 0) { - // Scaled gravity by distance - support_gravity *= currentArea->get_spOv_gravityMag() / Math::pow(distanceMag * currentArea->get_spOv_gravityPointDistanceScale() + 1, 2); - } else { - // Unscaled gravity - support_gravity *= currentArea->get_spOv_gravityMag(); - } - } else { - support_gravity = currentArea->get_spOv_gravityVec() * currentArea->get_spOv_gravityMag(); - } - - switch (currentArea->get_spOv_mode()) { - case PhysicsServer3D::AREA_SPACE_OVERRIDE_DISABLED: - /// This area does not affect gravity/damp. These are generally areas - /// that exist only to detect collisions, and objects entering or exiting them. - break; - case PhysicsServer3D::AREA_SPACE_OVERRIDE_COMBINE: - /// This area adds its gravity/damp values to whatever has been - /// calculated so far. This way, many overlapping areas can combine - /// their physics to make interesting - newGravity += support_gravity; - newLinearDamp += currentArea->get_spOv_linearDamp(); - newAngularDamp += currentArea->get_spOv_angularDamp(); - break; - case PhysicsServer3D::AREA_SPACE_OVERRIDE_COMBINE_REPLACE: - /// This area adds its gravity/damp values to whatever has been calculated - /// so far. Then stops taking into account the rest of the areas, even the - /// default one. - newGravity += support_gravity; - newLinearDamp += currentArea->get_spOv_linearDamp(); - newAngularDamp += currentArea->get_spOv_angularDamp(); - stopped = true; - break; - case PhysicsServer3D::AREA_SPACE_OVERRIDE_REPLACE: - /// This area replaces any gravity/damp, even the default one, and - /// stops taking into account the rest of the areas. - newGravity = support_gravity; - newLinearDamp = currentArea->get_spOv_linearDamp(); - newAngularDamp = currentArea->get_spOv_angularDamp(); - stopped = true; - break; - case PhysicsServer3D::AREA_SPACE_OVERRIDE_REPLACE_COMBINE: - /// This area replaces any gravity/damp calculated so far, but keeps - /// calculating the rest of the areas, down to the default one. - newGravity = support_gravity; - newLinearDamp = currentArea->get_spOv_linearDamp(); - newAngularDamp = currentArea->get_spOv_angularDamp(); - break; - } - } - - // Add default gravity and damping from space. - if (!stopped) { - newGravity += space->get_gravity_direction() * space->get_gravity_magnitude(); - newLinearDamp += space->get_linear_damp(); - newAngularDamp += space->get_angular_damp(); - } - - btVector3 newBtGravity; - G_TO_B(newGravity * gravity_scale, newBtGravity); - - btBody->setGravity(newBtGravity); - btBody->setDamping(newLinearDamp, newAngularDamp); -} - -void RigidBodyBullet::reload_kinematic_shapes() { - if (!kinematic_utilities) { - return; - } - kinematic_utilities->copyAllOwnerShapes(); -} - -void RigidBodyBullet::notify_transform_changed() { - RigidCollisionObjectBullet::notify_transform_changed(); - can_integrate_forces = true; -} - -void RigidBodyBullet::_internal_set_mass(real_t p_mass) { - btVector3 localInertia(0, 0, 0); - - int clearedCurrentFlags = btBody->getCollisionFlags(); - clearedCurrentFlags &= ~(btCollisionObject::CF_KINEMATIC_OBJECT | btCollisionObject::CF_STATIC_OBJECT | btCollisionObject::CF_CHARACTER_OBJECT); - - // Rigidbody is dynamic if and only if mass is non Zero, otherwise static - const bool isDynamic = p_mass != 0.f; - if (isDynamic) { - if (PhysicsServer3D::BODY_MODE_DYNAMIC != mode && PhysicsServer3D::MODE_DYNAMIC_LINEAR != mode) { - return; - } - - m_isStatic = false; - if (mainShape) { - mainShape->calculateLocalInertia(p_mass, localInertia); - } - - if (PhysicsServer3D::BODY_MODE_DYNAMIC == mode) { - btBody->setCollisionFlags(clearedCurrentFlags); // Just set the flags without Kin and Static - } else { - btBody->setCollisionFlags(clearedCurrentFlags | btCollisionObject::CF_CHARACTER_OBJECT); - } - - if (can_sleep) { - btBody->forceActivationState(ACTIVE_TAG); // ACTIVE_TAG 1 - } else { - btBody->forceActivationState(DISABLE_DEACTIVATION); // DISABLE_DEACTIVATION 4 - } - } else { - if (PhysicsServer3D::BODY_MODE_STATIC != mode && PhysicsServer3D::BODY_MODE_KINEMATIC != mode) { - return; - } - - m_isStatic = true; - if (PhysicsServer3D::BODY_MODE_STATIC == mode) { - btBody->setCollisionFlags(clearedCurrentFlags | btCollisionObject::CF_STATIC_OBJECT); - } else { - btBody->setCollisionFlags(clearedCurrentFlags | btCollisionObject::CF_KINEMATIC_OBJECT); - set_transform__bullet(btBody->getWorldTransform()); // Set current Transform using kinematic method - } - btBody->forceActivationState(DISABLE_SIMULATION); // DISABLE_SIMULATION 5 - } - - btBody->setMassProps(p_mass, localInertia); - btBody->updateInertiaTensor(); - - reload_body(); -} diff --git a/modules/bullet/rigid_body_bullet.h b/modules/bullet/rigid_body_bullet.h deleted file mode 100644 index cd433c968f..0000000000 --- a/modules/bullet/rigid_body_bullet.h +++ /dev/null @@ -1,328 +0,0 @@ -/*************************************************************************/ -/* rigid_body_bullet.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* 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. */ -/*************************************************************************/ - -#ifndef RIGID_BODY_BULLET_H -#define RIGID_BODY_BULLET_H - -#include "collision_object_bullet.h" -#include "space_bullet.h" - -#include <BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h> -#include <LinearMath/btTransform.h> - -class AreaBullet; -class SpaceBullet; -class btRigidBody; -class GodotMotionState; -class BulletPhysicsDirectBodyState3D; - -/// This class could be used in multi thread with few changes but currently -/// is set to be only in one single thread. -/// -/// In the system there is only one object at a time that manage all bodies and is -/// created by BulletPhysicsServer3D and is held by the "singleton" variable of this class -/// Each time something require it, the body must be set again. -class BulletPhysicsDirectBodyState3D : public PhysicsDirectBodyState3D { - GDCLASS(BulletPhysicsDirectBodyState3D, PhysicsDirectBodyState3D); - - static BulletPhysicsDirectBodyState3D *singleton; - -public: - /// This class avoid the creation of more object of this class - static void initSingleton() { - if (!singleton) { - singleton = memnew(BulletPhysicsDirectBodyState3D); - } - } - - static void destroySingleton() { - memdelete(singleton); - singleton = nullptr; - } - - static void singleton_setDeltaTime(real_t p_deltaTime) { - singleton->deltaTime = p_deltaTime; - } - - static BulletPhysicsDirectBodyState3D *get_singleton(RigidBodyBullet *p_body) { - singleton->body = p_body; - return singleton; - } - -public: - RigidBodyBullet *body = nullptr; - real_t deltaTime = 0.0; - -private: - BulletPhysicsDirectBodyState3D() {} - -public: - virtual Vector3 get_total_gravity() const override; - virtual real_t get_total_angular_damp() const override; - virtual real_t get_total_linear_damp() const override; - - virtual Vector3 get_center_of_mass() const override; - virtual Basis get_principal_inertia_axes() const override; - // get the mass - virtual real_t get_inverse_mass() const override; - // get density of this body space - virtual Vector3 get_inverse_inertia() const override; - // get density of this body space - virtual Basis get_inverse_inertia_tensor() const override; - - virtual void set_linear_velocity(const Vector3 &p_velocity) override; - virtual Vector3 get_linear_velocity() const override; - - virtual void set_angular_velocity(const Vector3 &p_velocity) override; - virtual Vector3 get_angular_velocity() const override; - - virtual void set_transform(const Transform3D &p_transform) override; - virtual Transform3D get_transform() const override; - - virtual Vector3 get_velocity_at_local_position(const Vector3 &p_position) const override; - - virtual void add_central_force(const Vector3 &p_force) override; - virtual void add_force(const Vector3 &p_force, const Vector3 &p_position = Vector3()) override; - virtual void add_torque(const Vector3 &p_torque) override; - virtual void apply_central_impulse(const Vector3 &p_impulse) override; - virtual void apply_impulse(const Vector3 &p_impulse, const Vector3 &p_position = Vector3()) override; - virtual void apply_torque_impulse(const Vector3 &p_impulse) override; - - virtual void set_sleep_state(bool p_sleep) override; - virtual bool is_sleeping() const override; - - virtual int get_contact_count() const override; - - virtual Vector3 get_contact_local_position(int p_contact_idx) const override; - virtual Vector3 get_contact_local_normal(int p_contact_idx) const override; - virtual real_t get_contact_impulse(int p_contact_idx) const override; - virtual int get_contact_local_shape(int p_contact_idx) const override; - - virtual RID get_contact_collider(int p_contact_idx) const override; - virtual Vector3 get_contact_collider_position(int p_contact_idx) const override; - virtual ObjectID get_contact_collider_id(int p_contact_idx) const override; - virtual int get_contact_collider_shape(int p_contact_idx) const override; - virtual Vector3 get_contact_collider_velocity_at_position(int p_contact_idx) const override; - - virtual real_t get_step() const override { return deltaTime; } - virtual void integrate_forces() override { - // Skip the execution of this function - } - - virtual PhysicsDirectSpaceState3D *get_space_state() override; -}; - -class RigidBodyBullet : public RigidCollisionObjectBullet { -public: - struct CollisionData { - RigidBodyBullet *otherObject = nullptr; - int other_object_shape = 0; - int local_shape = 0; - Vector3 hitLocalLocation; - Vector3 hitWorldLocation; - Vector3 hitNormal; - real_t appliedImpulse = 0.0; - }; - - struct ForceIntegrationCallback { - Callable callable; - Variant udata; - }; - - /// Used to hold shapes - struct KinematicShape { - class btConvexShape *shape = nullptr; - btTransform transform; - - KinematicShape() {} - bool is_active() const { return shape; } - }; - - struct KinematicUtilities { - RigidBodyBullet *owner = nullptr; - btScalar safe_margin; - Vector<KinematicShape> shapes; - - KinematicUtilities(RigidBodyBullet *p_owner); - ~KinematicUtilities(); - - void setSafeMargin(btScalar p_margin); - /// Used to set the default shape to ghost - void copyAllOwnerShapes(); - - private: - void just_delete_shapes(int new_size); - }; - -private: - friend class BulletPhysicsDirectBodyState3D; - - // This is required only for Kinematic movement - KinematicUtilities *kinematic_utilities = nullptr; - - PhysicsServer3D::BodyMode mode; - GodotMotionState *godotMotionState; - btRigidBody *btBody; - uint16_t locked_axis = 0; - real_t mass = 1.0; - real_t gravity_scale = 1.0; - real_t linearDamp = 0.0; - real_t angularDamp = 0.0; - bool can_sleep = true; - bool omit_forces_integration = false; - bool can_integrate_forces = false; - - Vector<CollisionData> collisions; - Vector<RigidBodyBullet *> collision_traces_1; - Vector<RigidBodyBullet *> collision_traces_2; - Vector<RigidBodyBullet *> *prev_collision_traces; - Vector<RigidBodyBullet *> *curr_collision_traces; - - // these parameters are used to avoid vector resize - int maxCollisionsDetection = 0; - int collisionsCount = 0; - int prev_collision_count = 0; - - Vector<AreaBullet *> areasWhereIam; - // these parameters are used to avoid vector resize - int maxAreasWhereIam = 10; - int areaWhereIamCount = 0; - // Used to know if the area is used as gravity point - int countGravityPointSpaces = 0; - bool isScratchedSpaceOverrideModificator = false; - - bool previousActiveState = true; // Last check state - - ForceIntegrationCallback *force_integration_callback = nullptr; - -public: - RigidBodyBullet(); - ~RigidBodyBullet(); - - void init_kinematic_utilities(); - void destroy_kinematic_utilities(); - _FORCE_INLINE_ KinematicUtilities *get_kinematic_utilities() const { return kinematic_utilities; } - - _FORCE_INLINE_ btRigidBody *get_bt_rigid_body() { return btBody; } - - virtual void main_shape_changed(); - virtual void reload_body(); - virtual void set_space(SpaceBullet *p_space); - - virtual void dispatch_callbacks(); - void set_force_integration_callback(const Callable &p_callable, const Variant &p_udata = Variant()); - void scratch_space_override_modificator(); - - virtual void on_collision_filters_change(); - virtual void on_collision_checker_start(); - virtual void on_collision_checker_end(); - - void set_max_collisions_detection(int p_maxCollisionsDetection) { - ERR_FAIL_COND(0 > p_maxCollisionsDetection); - - maxCollisionsDetection = p_maxCollisionsDetection; - - collisions.resize(p_maxCollisionsDetection); - collision_traces_1.resize(p_maxCollisionsDetection); - collision_traces_2.resize(p_maxCollisionsDetection); - - collisionsCount = 0; - prev_collision_count = MIN(prev_collision_count, p_maxCollisionsDetection); - } - int get_max_collisions_detection() { - return maxCollisionsDetection; - } - - bool can_add_collision() { return collisionsCount < maxCollisionsDetection; } - bool add_collision_object(RigidBodyBullet *p_otherObject, const Vector3 &p_hitWorldLocation, const Vector3 &p_hitLocalLocation, const Vector3 &p_hitNormal, const real_t &p_appliedImpulse, int p_other_shape_index, int p_local_shape_index); - bool was_colliding(RigidBodyBullet *p_other_object); - - void set_activation_state(bool p_active); - bool is_active() const; - - void set_omit_forces_integration(bool p_omit); - _FORCE_INLINE_ bool get_omit_forces_integration() const { return omit_forces_integration; } - - void set_param(PhysicsServer3D::BodyParameter p_param, real_t); - real_t get_param(PhysicsServer3D::BodyParameter p_param) const; - - void set_mode(PhysicsServer3D::BodyMode p_mode); - PhysicsServer3D::BodyMode get_mode() const; - - void set_state(PhysicsServer3D::BodyState p_state, const Variant &p_variant); - Variant get_state(PhysicsServer3D::BodyState p_state) const; - - void apply_central_impulse(const Vector3 &p_impulse); - void apply_impulse(const Vector3 &p_impulse, const Vector3 &p_position = Vector3()); - void apply_torque_impulse(const Vector3 &p_impulse); - - void apply_central_force(const Vector3 &p_force); - void apply_force(const Vector3 &p_force, const Vector3 &p_position = Vector3()); - void apply_torque(const Vector3 &p_torque); - - void set_applied_force(const Vector3 &p_force); - Vector3 get_applied_force() const; - void set_applied_torque(const Vector3 &p_torque); - Vector3 get_applied_torque() const; - - void set_axis_lock(PhysicsServer3D::BodyAxis p_axis, bool lock); - bool is_axis_locked(PhysicsServer3D::BodyAxis p_axis) const; - void reload_axis_lock(); - - /// Doc: - /// https://web.archive.org/web/20180404091446/https://www.bulletphysics.org/mediawiki-1.5.8/index.php/Anti_tunneling_by_Motion_Clamping - void set_continuous_collision_detection(bool p_enable); - bool is_continuous_collision_detection_enabled() const; - - void set_linear_velocity(const Vector3 &p_velocity); - Vector3 get_linear_velocity() const; - - void set_angular_velocity(const Vector3 &p_velocity); - Vector3 get_angular_velocity() const; - - virtual void set_transform__bullet(const btTransform &p_global_transform); - virtual const btTransform &get_transform__bullet() const; - - virtual void reload_shapes(); - - virtual void on_enter_area(AreaBullet *p_area); - virtual void on_exit_area(AreaBullet *p_area); - void reload_space_override_modificator(); - - /// Kinematic - void reload_kinematic_shapes(); - - virtual void notify_transform_changed(); - -private: - void _internal_set_mass(real_t p_mass); -}; - -#endif // RIGID_BODY_BULLET_H diff --git a/modules/bullet/shape_bullet.cpp b/modules/bullet/shape_bullet.cpp deleted file mode 100644 index cf6bcb6c85..0000000000 --- a/modules/bullet/shape_bullet.cpp +++ /dev/null @@ -1,595 +0,0 @@ -/*************************************************************************/ -/* shape_bullet.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* 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 "shape_bullet.h" - -#include "btRayShape.h" -#include "bullet_physics_server.h" -#include "bullet_types_converter.h" -#include "bullet_utilities.h" -#include "core/config/project_settings.h" -#include "shape_owner_bullet.h" - -#include <BulletCollision/CollisionDispatch/btInternalEdgeUtility.h> -#include <BulletCollision/CollisionShapes/btConvexPointCloudShape.h> -#include <BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h> -#include <btBulletCollisionCommon.h> - -ShapeBullet::ShapeBullet() {} - -ShapeBullet::~ShapeBullet() {} - -btCollisionShape *ShapeBullet::create_bt_shape(const Vector3 &p_implicit_scale, real_t p_extra_edge) { - btVector3 s; - G_TO_B(p_implicit_scale, s); - return create_bt_shape(s, p_extra_edge); -} - -btCollisionShape *ShapeBullet::prepare(btCollisionShape *p_btShape) const { - p_btShape->setUserPointer(const_cast<ShapeBullet *>(this)); - p_btShape->setMargin(margin); - return p_btShape; -} - -void ShapeBullet::notifyShapeChanged() { - for (const KeyValue<ShapeOwnerBullet *, int> &E : owners) { - ShapeOwnerBullet *owner = static_cast<ShapeOwnerBullet *>(E.key); - owner->shape_changed(owner->find_shape(this)); - } -} - -void ShapeBullet::add_owner(ShapeOwnerBullet *p_owner) { - Map<ShapeOwnerBullet *, int>::Element *E = owners.find(p_owner); - if (E) { - E->get()++; - } else { - owners[p_owner] = 1; // add new owner - } -} - -void ShapeBullet::remove_owner(ShapeOwnerBullet *p_owner, bool p_permanentlyFromThisBody) { - Map<ShapeOwnerBullet *, int>::Element *E = owners.find(p_owner); - if (!E) { - return; - } - E->get()--; - if (p_permanentlyFromThisBody || 0 >= E->get()) { - owners.erase(E); - } -} - -bool ShapeBullet::is_owner(ShapeOwnerBullet *p_owner) const { - return owners.has(p_owner); -} - -const Map<ShapeOwnerBullet *, int> &ShapeBullet::get_owners() const { - return owners; -} - -void ShapeBullet::set_margin(real_t p_margin) { - margin = p_margin; - notifyShapeChanged(); -} - -real_t ShapeBullet::get_margin() const { - return margin; -} - -btEmptyShape *ShapeBullet::create_shape_empty() { - return bulletnew(btEmptyShape); -} - -btStaticPlaneShape *ShapeBullet::create_shape_world_boundary(const btVector3 &planeNormal, btScalar planeConstant) { - return bulletnew(btStaticPlaneShape(planeNormal, planeConstant)); -} - -btSphereShape *ShapeBullet::create_shape_sphere(btScalar radius) { - return bulletnew(btSphereShape(radius)); -} - -btBoxShape *ShapeBullet::create_shape_box(const btVector3 &boxHalfExtents) { - return bulletnew(btBoxShape(boxHalfExtents)); -} - -btCapsuleShape *ShapeBullet::create_shape_capsule(btScalar radius, btScalar height) { - return bulletnew(btCapsuleShape(radius, height)); -} - -btCylinderShape *ShapeBullet::create_shape_cylinder(btScalar radius, btScalar height) { - return bulletnew(btCylinderShape(btVector3(radius, height / 2.0, radius))); -} - -btConvexPointCloudShape *ShapeBullet::create_shape_convex(btAlignedObjectArray<btVector3> &p_vertices, const btVector3 &p_local_scaling) { - return bulletnew(btConvexPointCloudShape(&p_vertices[0], p_vertices.size(), p_local_scaling)); -} - -btScaledBvhTriangleMeshShape *ShapeBullet::create_shape_concave(btBvhTriangleMeshShape *p_mesh_shape, const btVector3 &p_local_scaling) { - if (p_mesh_shape) { - return bulletnew(btScaledBvhTriangleMeshShape(p_mesh_shape, p_local_scaling)); - } else { - return nullptr; - } -} - -btHeightfieldTerrainShape *ShapeBullet::create_shape_height_field(Vector<float> &p_heights, int p_width, int p_depth, real_t p_min_height, real_t p_max_height) { - const btScalar ignoredHeightScale(1); - const int YAxis = 1; // 0=X, 1=Y, 2=Z - const bool flipQuadEdges = false; - const void *heightsPtr = p_heights.ptr(); - - btHeightfieldTerrainShape *heightfield = bulletnew(btHeightfieldTerrainShape(p_width, p_depth, heightsPtr, ignoredHeightScale, p_min_height, p_max_height, YAxis, PHY_FLOAT, flipQuadEdges)); - - // The shape can be created without params when you do PhysicsServer3D.shape_create(PhysicsServer3D.SHAPE_HEIGHTMAP) - if (heightsPtr) { - heightfield->buildAccelerator(16); - } - - return heightfield; -} - -btRayShape *ShapeBullet::create_shape_ray(real_t p_length, bool p_slips_on_slope) { - btRayShape *r(bulletnew(btRayShape(p_length))); - r->setSlipsOnSlope(p_slips_on_slope); - return r; -} - -/* World boundary */ - -WorldBoundaryShapeBullet::WorldBoundaryShapeBullet() : - ShapeBullet() {} - -void WorldBoundaryShapeBullet::set_data(const Variant &p_data) { - setup(p_data); -} - -Variant WorldBoundaryShapeBullet::get_data() const { - return plane; -} - -PhysicsServer3D::ShapeType WorldBoundaryShapeBullet::get_type() const { - return PhysicsServer3D::SHAPE_WORLD_BOUNDARY; -} - -void WorldBoundaryShapeBullet::setup(const Plane &p_plane) { - plane = p_plane; - notifyShapeChanged(); -} - -btCollisionShape *WorldBoundaryShapeBullet::create_bt_shape(const btVector3 &p_implicit_scale, real_t p_extra_edge) { - btVector3 btPlaneNormal; - G_TO_B(plane.normal, btPlaneNormal); - return prepare(WorldBoundaryShapeBullet::create_shape_world_boundary(btPlaneNormal, plane.d)); -} - -/* Sphere */ - -SphereShapeBullet::SphereShapeBullet() : - ShapeBullet() {} - -void SphereShapeBullet::set_data(const Variant &p_data) { - setup(p_data); -} - -Variant SphereShapeBullet::get_data() const { - return radius; -} - -PhysicsServer3D::ShapeType SphereShapeBullet::get_type() const { - return PhysicsServer3D::SHAPE_SPHERE; -} - -void SphereShapeBullet::setup(real_t p_radius) { - radius = p_radius; - notifyShapeChanged(); -} - -btCollisionShape *SphereShapeBullet::create_bt_shape(const btVector3 &p_implicit_scale, real_t p_extra_edge) { - return prepare(ShapeBullet::create_shape_sphere(radius * p_implicit_scale[0] + p_extra_edge)); -} - -/* Box */ -BoxShapeBullet::BoxShapeBullet() : - ShapeBullet() {} - -void BoxShapeBullet::set_data(const Variant &p_data) { - setup(p_data); -} - -Variant BoxShapeBullet::get_data() const { - Vector3 g_half_extents; - B_TO_G(half_extents, g_half_extents); - return g_half_extents; -} - -PhysicsServer3D::ShapeType BoxShapeBullet::get_type() const { - return PhysicsServer3D::SHAPE_BOX; -} - -void BoxShapeBullet::setup(const Vector3 &p_half_extents) { - G_TO_B(p_half_extents, half_extents); - notifyShapeChanged(); -} - -btCollisionShape *BoxShapeBullet::create_bt_shape(const btVector3 &p_implicit_scale, real_t p_extra_edge) { - return prepare(ShapeBullet::create_shape_box((half_extents * p_implicit_scale) + btVector3(p_extra_edge, p_extra_edge, p_extra_edge))); -} - -/* Capsule */ - -CapsuleShapeBullet::CapsuleShapeBullet() : - ShapeBullet() {} - -void CapsuleShapeBullet::set_data(const Variant &p_data) { - Dictionary d = p_data; - ERR_FAIL_COND(!d.has("radius")); - ERR_FAIL_COND(!d.has("height")); - setup(d["height"], d["radius"]); -} - -Variant CapsuleShapeBullet::get_data() const { - Dictionary d; - d["radius"] = radius; - d["height"] = height; - return d; -} - -PhysicsServer3D::ShapeType CapsuleShapeBullet::get_type() const { - return PhysicsServer3D::SHAPE_CAPSULE; -} - -void CapsuleShapeBullet::setup(real_t p_height, real_t p_radius) { - radius = p_radius; - height = p_height; - notifyShapeChanged(); -} - -btCollisionShape *CapsuleShapeBullet::create_bt_shape(const btVector3 &p_implicit_scale, real_t p_extra_edge) { - return prepare(ShapeBullet::create_shape_capsule(radius * p_implicit_scale[0] + p_extra_edge, height * p_implicit_scale[1])); -} - -/* Cylinder */ - -CylinderShapeBullet::CylinderShapeBullet() : - ShapeBullet() {} - -void CylinderShapeBullet::set_data(const Variant &p_data) { - Dictionary d = p_data; - ERR_FAIL_COND(!d.has("radius")); - ERR_FAIL_COND(!d.has("height")); - setup(d["height"], d["radius"]); -} - -Variant CylinderShapeBullet::get_data() const { - Dictionary d; - d["radius"] = radius; - d["height"] = height; - return d; -} - -PhysicsServer3D::ShapeType CylinderShapeBullet::get_type() const { - return PhysicsServer3D::SHAPE_CYLINDER; -} - -void CylinderShapeBullet::setup(real_t p_height, real_t p_radius) { - radius = p_radius; - height = p_height; - notifyShapeChanged(); -} - -btCollisionShape *CylinderShapeBullet::create_bt_shape(const btVector3 &p_implicit_scale, real_t p_margin) { - return prepare(ShapeBullet::create_shape_cylinder(radius * p_implicit_scale[0] + p_margin, height * p_implicit_scale[1] + p_margin)); -} - -/* Convex polygon */ - -ConvexPolygonShapeBullet::ConvexPolygonShapeBullet() : - ShapeBullet() {} - -void ConvexPolygonShapeBullet::set_data(const Variant &p_data) { - setup(p_data); -} - -void ConvexPolygonShapeBullet::get_vertices(Vector<Vector3> &out_vertices) { - const int n_of_vertices = vertices.size(); - out_vertices.resize(n_of_vertices); - for (int i = n_of_vertices - 1; 0 <= i; --i) { - B_TO_G(vertices[i], out_vertices.write[i]); - } -} - -Variant ConvexPolygonShapeBullet::get_data() const { - ConvexPolygonShapeBullet *variable_self = const_cast<ConvexPolygonShapeBullet *>(this); - Vector<Vector3> out_vertices; - variable_self->get_vertices(out_vertices); - return out_vertices; -} - -PhysicsServer3D::ShapeType ConvexPolygonShapeBullet::get_type() const { - return PhysicsServer3D::SHAPE_CONVEX_POLYGON; -} - -void ConvexPolygonShapeBullet::setup(const Vector<Vector3> &p_vertices) { - // Make a copy of vertices - const int n_of_vertices = p_vertices.size(); - vertices.resize(n_of_vertices); - for (int i = n_of_vertices - 1; 0 <= i; --i) { - G_TO_B(p_vertices[i], vertices[i]); - } - notifyShapeChanged(); -} - -btCollisionShape *ConvexPolygonShapeBullet::create_bt_shape(const btVector3 &p_implicit_scale, real_t p_extra_edge) { - if (!vertices.size()) { - // This is necessary since 0 vertices - return prepare(ShapeBullet::create_shape_empty()); - } - btCollisionShape *cs(ShapeBullet::create_shape_convex(vertices)); - cs->setLocalScaling(p_implicit_scale); - prepare(cs); - return cs; -} - -/* Concave polygon */ - -ConcavePolygonShapeBullet::ConcavePolygonShapeBullet() : - ShapeBullet() {} - -ConcavePolygonShapeBullet::~ConcavePolygonShapeBullet() { - if (meshShape) { - delete meshShape->getMeshInterface(); - delete meshShape->getTriangleInfoMap(); - bulletdelete(meshShape); - } - faces = Vector<Vector3>(); -} - -void ConcavePolygonShapeBullet::set_data(const Variant &p_data) { - Dictionary d = p_data; - ERR_FAIL_COND(!d.has("faces")); - - setup(d["faces"]); -} - -Variant ConcavePolygonShapeBullet::get_data() const { - Dictionary d; - d["faces"] = faces; - - return d; -} - -PhysicsServer3D::ShapeType ConcavePolygonShapeBullet::get_type() const { - return PhysicsServer3D::SHAPE_CONCAVE_POLYGON; -} - -void ConcavePolygonShapeBullet::setup(Vector<Vector3> p_faces) { - faces = p_faces; - if (meshShape) { - /// Clear previous created shape - delete meshShape->getMeshInterface(); - delete meshShape->getTriangleInfoMap(); - bulletdelete(meshShape); - } - int src_face_count = faces.size(); - if (0 < src_face_count) { - // It counts the faces and assert the array contains the correct number of vertices. - ERR_FAIL_COND(src_face_count % 3); - - btTriangleMesh *shapeInterface = bulletnew(btTriangleMesh); - src_face_count /= 3; - const Vector3 *r = p_faces.ptr(); - const Vector3 *facesr = r; - - btVector3 supVec_0; - btVector3 supVec_1; - btVector3 supVec_2; - for (int i = 0; i < src_face_count; ++i) { - G_TO_B(facesr[i * 3 + 0], supVec_0); - G_TO_B(facesr[i * 3 + 1], supVec_1); - G_TO_B(facesr[i * 3 + 2], supVec_2); - - // Inverted from standard godot otherwise btGenerateInternalEdgeInfo generates wrong edge info - shapeInterface->addTriangle(supVec_2, supVec_1, supVec_0); - } - - const bool useQuantizedAabbCompression = true; - - meshShape = bulletnew(btBvhTriangleMeshShape(shapeInterface, useQuantizedAabbCompression)); - - if (GLOBAL_GET("physics/3d/smooth_trimesh_collision")) { - btTriangleInfoMap *triangleInfoMap = new btTriangleInfoMap(); - btGenerateInternalEdgeInfo(meshShape, triangleInfoMap); - } - } else { - meshShape = nullptr; - ERR_PRINT("The faces count are 0, the mesh shape cannot be created"); - } - notifyShapeChanged(); -} - -btCollisionShape *ConcavePolygonShapeBullet::create_bt_shape(const btVector3 &p_implicit_scale, real_t p_extra_edge) { - btCollisionShape *cs = ShapeBullet::create_shape_concave(meshShape); - if (!cs) { - // This is necessary since if 0 faces the creation of concave return null - cs = ShapeBullet::create_shape_empty(); - } - cs->setLocalScaling(p_implicit_scale); - prepare(cs); - cs->setMargin(0); - return cs; -} - -/* Height map shape */ - -HeightMapShapeBullet::HeightMapShapeBullet() : - ShapeBullet() {} - -void HeightMapShapeBullet::set_data(const Variant &p_data) { - ERR_FAIL_COND(p_data.get_type() != Variant::DICTIONARY); - Dictionary d = p_data; - ERR_FAIL_COND(!d.has("width")); - ERR_FAIL_COND(!d.has("depth")); - ERR_FAIL_COND(!d.has("heights")); - - real_t l_min_height = 0.0; - real_t l_max_height = 0.0; - - // If specified, min and max height will be used as precomputed values - if (d.has("min_height")) { - l_min_height = d["min_height"]; - } - if (d.has("max_height")) { - l_max_height = d["max_height"]; - } - - ERR_FAIL_COND(l_min_height > l_max_height); - - int l_width = d["width"]; - int l_depth = d["depth"]; - - ERR_FAIL_COND_MSG(l_width < 2, "Map width must be at least 2."); - ERR_FAIL_COND_MSG(l_depth < 2, "Map depth must be at least 2."); - - Vector<float> l_heights; - Variant l_heights_v = d["heights"]; - - if (l_heights_v.get_type() == Variant::PACKED_FLOAT32_ARRAY) { - // Ready-to-use heights can be passed - - l_heights = l_heights_v; - - } else if (l_heights_v.get_type() == Variant::OBJECT) { - // If an image is passed, we have to convert it to a format Bullet supports. - // this would be expensive to do with a script, so it's nice to have it here. - - Ref<Image> l_image = l_heights_v; - ERR_FAIL_COND(l_image.is_null()); - - // Float is the only common format between Godot and Bullet that can be used for decent collision. - // (Int16 would be nice too but we still don't have it) - // We could convert here automatically but it's better to not be intrusive and let the caller do it if necessary. - ERR_FAIL_COND(l_image->get_format() != Image::FORMAT_RF); - - PackedByteArray im_data = l_image->get_data(); - - l_heights.resize(l_image->get_width() * l_image->get_height()); - - float *w = l_heights.ptrw(); - const uint8_t *r = im_data.ptr(); - float *rp = (float *)r; - // At this point, `rp` could be used directly for Bullet, but I don't know how safe it would be. - - for (int i = 0; i < l_heights.size(); ++i) { - w[i] = rp[i]; - } - - } else { - ERR_FAIL_MSG("Expected PackedFloat32Array or float Image."); - } - - ERR_FAIL_COND(l_width <= 0); - ERR_FAIL_COND(l_depth <= 0); - ERR_FAIL_COND(l_heights.size() != (l_width * l_depth)); - - // Compute min and max heights if not specified. - if (!d.has("min_height") && !d.has("max_height")) { - const float *r = l_heights.ptr(); - int heights_size = l_heights.size(); - - for (int i = 0; i < heights_size; ++i) { - float h = r[i]; - - if (h < l_min_height) { - l_min_height = h; - } else if (h > l_max_height) { - l_max_height = h; - } - } - } - - setup(l_heights, l_width, l_depth, l_min_height, l_max_height); -} - -Variant HeightMapShapeBullet::get_data() const { - ERR_FAIL_V(Variant()); -} - -PhysicsServer3D::ShapeType HeightMapShapeBullet::get_type() const { - return PhysicsServer3D::SHAPE_HEIGHTMAP; -} - -void HeightMapShapeBullet::setup(Vector<float> &p_heights, int p_width, int p_depth, real_t p_min_height, real_t p_max_height) { - // TODO cell size must be tweaked using localScaling, which is a shared property for all Bullet shapes - - // If this array is resized outside of here, it should be preserved due to CoW - heights = p_heights; - - width = p_width; - depth = p_depth; - min_height = p_min_height; - max_height = p_max_height; - notifyShapeChanged(); -} - -btCollisionShape *HeightMapShapeBullet::create_bt_shape(const btVector3 &p_implicit_scale, real_t p_extra_edge) { - btCollisionShape *cs(ShapeBullet::create_shape_height_field(heights, width, depth, min_height, max_height)); - cs->setLocalScaling(p_implicit_scale); - prepare(cs); - return cs; -} - -/* Ray shape */ -RayShapeBullet::RayShapeBullet() : - ShapeBullet() {} - -void RayShapeBullet::set_data(const Variant &p_data) { - Dictionary d = p_data; - setup(d["length"], d["slips_on_slope"]); -} - -Variant RayShapeBullet::get_data() const { - Dictionary d; - d["length"] = length; - d["slips_on_slope"] = slips_on_slope; - return d; -} - -PhysicsServer3D::ShapeType RayShapeBullet::get_type() const { - return PhysicsServer3D::SHAPE_RAY; -} - -void RayShapeBullet::setup(real_t p_length, bool p_slips_on_slope) { - length = p_length; - slips_on_slope = p_slips_on_slope; - notifyShapeChanged(); -} - -btCollisionShape *RayShapeBullet::create_bt_shape(const btVector3 &p_implicit_scale, real_t p_extra_edge) { - return prepare(ShapeBullet::create_shape_ray(length * p_implicit_scale[1] + p_extra_edge, slips_on_slope)); -} diff --git a/modules/bullet/shape_bullet.h b/modules/bullet/shape_bullet.h deleted file mode 100644 index dffcadbcdc..0000000000 --- a/modules/bullet/shape_bullet.h +++ /dev/null @@ -1,244 +0,0 @@ -/*************************************************************************/ -/* shape_bullet.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* 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. */ -/*************************************************************************/ - -#ifndef SHAPE_BULLET_H -#define SHAPE_BULLET_H - -#include "core/math/geometry_3d.h" -#include "core/variant/variant.h" -#include "rid_bullet.h" -#include "servers/physics_server_3d.h" - -#include <LinearMath/btAlignedObjectArray.h> -#include <LinearMath/btScalar.h> -#include <LinearMath/btVector3.h> - -class ShapeBullet; -class btCollisionShape; -class ShapeOwnerBullet; -class btBvhTriangleMeshShape; - -class ShapeBullet : public RIDBullet { - Map<ShapeOwnerBullet *, int> owners; - real_t margin = 0.04; - -protected: - /// return self - btCollisionShape *prepare(btCollisionShape *p_btShape) const; - void notifyShapeChanged(); - -public: - ShapeBullet(); - virtual ~ShapeBullet(); - - btCollisionShape *create_bt_shape(const Vector3 &p_implicit_scale, real_t p_extra_edge = 0); - virtual btCollisionShape *create_bt_shape(const btVector3 &p_implicit_scale, real_t p_extra_edge = 0) = 0; - - void add_owner(ShapeOwnerBullet *p_owner); - void remove_owner(ShapeOwnerBullet *p_owner, bool p_permanentlyFromThisBody = false); - bool is_owner(ShapeOwnerBullet *p_owner) const; - const Map<ShapeOwnerBullet *, int> &get_owners() const; - - void set_margin(real_t p_margin); - real_t get_margin() const; - - /// Setup the shape - virtual void set_data(const Variant &p_data) = 0; - virtual Variant get_data() const = 0; - - virtual PhysicsServer3D::ShapeType get_type() const = 0; - -public: - static class btEmptyShape *create_shape_empty(); - static class btStaticPlaneShape *create_shape_world_boundary(const btVector3 &planeNormal, btScalar planeConstant); - static class btSphereShape *create_shape_sphere(btScalar radius); - static class btBoxShape *create_shape_box(const btVector3 &boxHalfExtents); - static class btCapsuleShape *create_shape_capsule(btScalar radius, btScalar height); - static class btCylinderShape *create_shape_cylinder(btScalar radius, btScalar height); - /// IMPORTANT: Remember to delete the shape interface by calling: delete my_shape->getMeshInterface(); - static class btConvexPointCloudShape *create_shape_convex(btAlignedObjectArray<btVector3> &p_vertices, const btVector3 &p_local_scaling = btVector3(1, 1, 1)); - static class btScaledBvhTriangleMeshShape *create_shape_concave(btBvhTriangleMeshShape *p_mesh_shape, const btVector3 &p_local_scaling = btVector3(1, 1, 1)); - static class btHeightfieldTerrainShape *create_shape_height_field(Vector<float> &p_heights, int p_width, int p_depth, real_t p_min_height, real_t p_max_height); - static class btRayShape *create_shape_ray(real_t p_length, bool p_slips_on_slope); -}; - -class WorldBoundaryShapeBullet : public ShapeBullet { - Plane plane; - -public: - WorldBoundaryShapeBullet(); - - virtual void set_data(const Variant &p_data); - virtual Variant get_data() const; - virtual PhysicsServer3D::ShapeType get_type() const; - virtual btCollisionShape *create_bt_shape(const btVector3 &p_implicit_scale, real_t p_extra_edge = 0); - -private: - void setup(const Plane &p_plane); -}; - -class SphereShapeBullet : public ShapeBullet { - real_t radius = 0.0; - -public: - SphereShapeBullet(); - - _FORCE_INLINE_ real_t get_radius() { return radius; } - virtual void set_data(const Variant &p_data); - virtual Variant get_data() const; - virtual PhysicsServer3D::ShapeType get_type() const; - virtual btCollisionShape *create_bt_shape(const btVector3 &p_implicit_scale, real_t p_extra_edge = 0); - -private: - void setup(real_t p_radius); -}; - -class BoxShapeBullet : public ShapeBullet { - btVector3 half_extents; - -public: - BoxShapeBullet(); - - _FORCE_INLINE_ const btVector3 &get_half_extents() { return half_extents; } - virtual void set_data(const Variant &p_data); - virtual Variant get_data() const; - virtual PhysicsServer3D::ShapeType get_type() const; - virtual btCollisionShape *create_bt_shape(const btVector3 &p_implicit_scale, real_t p_extra_edge = 0); - -private: - void setup(const Vector3 &p_half_extents); -}; - -class CapsuleShapeBullet : public ShapeBullet { - real_t height = 0.0; - real_t radius = 0.0; - -public: - CapsuleShapeBullet(); - - _FORCE_INLINE_ real_t get_height() { return height; } - _FORCE_INLINE_ real_t get_radius() { return radius; } - virtual void set_data(const Variant &p_data); - virtual Variant get_data() const; - virtual PhysicsServer3D::ShapeType get_type() const; - virtual btCollisionShape *create_bt_shape(const btVector3 &p_implicit_scale, real_t p_extra_edge = 0); - -private: - void setup(real_t p_height, real_t p_radius); -}; - -class CylinderShapeBullet : public ShapeBullet { - real_t height = 0.0; - real_t radius = 0.0; - -public: - CylinderShapeBullet(); - - _FORCE_INLINE_ real_t get_height() { return height; } - _FORCE_INLINE_ real_t get_radius() { return radius; } - virtual void set_data(const Variant &p_data); - virtual Variant get_data() const; - virtual PhysicsServer3D::ShapeType get_type() const; - virtual btCollisionShape *create_bt_shape(const btVector3 &p_implicit_scale, real_t p_margin = 0); - -private: - void setup(real_t p_height, real_t p_radius); -}; - -class ConvexPolygonShapeBullet : public ShapeBullet { -public: - btAlignedObjectArray<btVector3> vertices; - - ConvexPolygonShapeBullet(); - - virtual void set_data(const Variant &p_data); - void get_vertices(Vector<Vector3> &out_vertices); - virtual Variant get_data() const; - virtual PhysicsServer3D::ShapeType get_type() const; - virtual btCollisionShape *create_bt_shape(const btVector3 &p_implicit_scale, real_t p_extra_edge = 0); - -private: - void setup(const Vector<Vector3> &p_vertices); -}; - -class ConcavePolygonShapeBullet : public ShapeBullet { - class btBvhTriangleMeshShape *meshShape = nullptr; - -public: - Vector<Vector3> faces; - - ConcavePolygonShapeBullet(); - virtual ~ConcavePolygonShapeBullet(); - - virtual void set_data(const Variant &p_data); - virtual Variant get_data() const; - virtual PhysicsServer3D::ShapeType get_type() const; - virtual btCollisionShape *create_bt_shape(const btVector3 &p_implicit_scale, real_t p_extra_edge = 0); - -private: - void setup(Vector<Vector3> p_faces); -}; - -class HeightMapShapeBullet : public ShapeBullet { -public: - Vector<float> heights; - int width = 0; - int depth = 0; - real_t min_height = 0.0; - real_t max_height = 0.0; - - HeightMapShapeBullet(); - - virtual void set_data(const Variant &p_data); - virtual Variant get_data() const; - virtual PhysicsServer3D::ShapeType get_type() const; - virtual btCollisionShape *create_bt_shape(const btVector3 &p_implicit_scale, real_t p_extra_edge = 0); - -private: - void setup(Vector<float> &p_heights, int p_width, int p_depth, real_t p_min_height, real_t p_max_height); -}; - -class RayShapeBullet : public ShapeBullet { -public: - real_t length = 1.0; - bool slips_on_slope = false; - - RayShapeBullet(); - - virtual void set_data(const Variant &p_data); - virtual Variant get_data() const; - virtual PhysicsServer3D::ShapeType get_type() const; - virtual btCollisionShape *create_bt_shape(const btVector3 &p_implicit_scale, real_t p_extra_edge = 0); - -private: - void setup(real_t p_length, bool p_slips_on_slope); -}; - -#endif // SHAPE_BULLET_H diff --git a/modules/bullet/shape_owner_bullet.h b/modules/bullet/shape_owner_bullet.h deleted file mode 100644 index 11cf1bc2d5..0000000000 --- a/modules/bullet/shape_owner_bullet.h +++ /dev/null @@ -1,51 +0,0 @@ -/*************************************************************************/ -/* shape_owner_bullet.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* 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. */ -/*************************************************************************/ - -#ifndef SHAPE_OWNER_BULLET_H -#define SHAPE_OWNER_BULLET_H - -#include "rid_bullet.h" - -class ShapeBullet; -class btCollisionShape; -class CollisionObjectBullet; - -/// Each class that want to use Shapes must inherit this class -/// E.G. BodyShape is a child of this -class ShapeOwnerBullet { -public: - virtual int find_shape(ShapeBullet *p_shape) const = 0; - virtual void shape_changed(int p_shape_index) = 0; - virtual void reload_shapes() = 0; - virtual void remove_shape_full(class ShapeBullet *p_shape) = 0; - virtual ~ShapeOwnerBullet() {} -}; - -#endif // SHAPE_OWNER_BULLET_H diff --git a/modules/bullet/slider_joint_bullet.cpp b/modules/bullet/slider_joint_bullet.cpp deleted file mode 100644 index b06cdeaa6a..0000000000 --- a/modules/bullet/slider_joint_bullet.cpp +++ /dev/null @@ -1,461 +0,0 @@ -/*************************************************************************/ -/* slider_joint_bullet.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* 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 "slider_joint_bullet.h" - -#include "bullet_types_converter.h" -#include "bullet_utilities.h" -#include "rigid_body_bullet.h" - -#include <BulletDynamics/ConstraintSolver/btSliderConstraint.h> - -SliderJointBullet::SliderJointBullet(RigidBodyBullet *rbA, RigidBodyBullet *rbB, const Transform3D &frameInA, const Transform3D &frameInB) : - JointBullet() { - Transform3D scaled_AFrame(frameInA.scaled(rbA->get_body_scale())); - scaled_AFrame.basis.rotref_posscale_decomposition(scaled_AFrame.basis); - - btTransform btFrameA; - G_TO_B(scaled_AFrame, btFrameA); - - if (rbB) { - Transform3D scaled_BFrame(frameInB.scaled(rbB->get_body_scale())); - scaled_BFrame.basis.rotref_posscale_decomposition(scaled_BFrame.basis); - - btTransform btFrameB; - G_TO_B(scaled_BFrame, btFrameB); - sliderConstraint = bulletnew(btSliderConstraint(*rbA->get_bt_rigid_body(), *rbB->get_bt_rigid_body(), btFrameA, btFrameB, true)); - - } else { - sliderConstraint = bulletnew(btSliderConstraint(*rbA->get_bt_rigid_body(), btFrameA, true)); - } - setup(sliderConstraint); -} - -const RigidBodyBullet *SliderJointBullet::getRigidBodyA() const { - return static_cast<RigidBodyBullet *>(sliderConstraint->getRigidBodyA().getUserPointer()); -} - -const RigidBodyBullet *SliderJointBullet::getRigidBodyB() const { - return static_cast<RigidBodyBullet *>(sliderConstraint->getRigidBodyB().getUserPointer()); -} - -const Transform3D SliderJointBullet::getCalculatedTransformA() const { - btTransform btTransform = sliderConstraint->getCalculatedTransformA(); - Transform3D gTrans; - B_TO_G(btTransform, gTrans); - return gTrans; -} - -const Transform3D SliderJointBullet::getCalculatedTransformB() const { - btTransform btTransform = sliderConstraint->getCalculatedTransformB(); - Transform3D gTrans; - B_TO_G(btTransform, gTrans); - return gTrans; -} - -const Transform3D SliderJointBullet::getFrameOffsetA() const { - btTransform btTransform = sliderConstraint->getFrameOffsetA(); - Transform3D gTrans; - B_TO_G(btTransform, gTrans); - return gTrans; -} - -const Transform3D SliderJointBullet::getFrameOffsetB() const { - btTransform btTransform = sliderConstraint->getFrameOffsetB(); - Transform3D gTrans; - B_TO_G(btTransform, gTrans); - return gTrans; -} - -Transform3D SliderJointBullet::getFrameOffsetA() { - btTransform btTransform = sliderConstraint->getFrameOffsetA(); - Transform3D gTrans; - B_TO_G(btTransform, gTrans); - return gTrans; -} - -Transform3D SliderJointBullet::getFrameOffsetB() { - btTransform btTransform = sliderConstraint->getFrameOffsetB(); - Transform3D gTrans; - B_TO_G(btTransform, gTrans); - return gTrans; -} - -real_t SliderJointBullet::getLowerLinLimit() const { - return sliderConstraint->getLowerLinLimit(); -} - -void SliderJointBullet::setLowerLinLimit(real_t lowerLimit) { - sliderConstraint->setLowerLinLimit(lowerLimit); -} - -real_t SliderJointBullet::getUpperLinLimit() const { - return sliderConstraint->getUpperLinLimit(); -} - -void SliderJointBullet::setUpperLinLimit(real_t upperLimit) { - sliderConstraint->setUpperLinLimit(upperLimit); -} - -real_t SliderJointBullet::getLowerAngLimit() const { - return sliderConstraint->getLowerAngLimit(); -} - -void SliderJointBullet::setLowerAngLimit(real_t lowerLimit) { - sliderConstraint->setLowerAngLimit(lowerLimit); -} - -real_t SliderJointBullet::getUpperAngLimit() const { - return sliderConstraint->getUpperAngLimit(); -} - -void SliderJointBullet::setUpperAngLimit(real_t upperLimit) { - sliderConstraint->setUpperAngLimit(upperLimit); -} - -real_t SliderJointBullet::getSoftnessDirLin() const { - return sliderConstraint->getSoftnessDirLin(); -} - -real_t SliderJointBullet::getRestitutionDirLin() const { - return sliderConstraint->getRestitutionDirLin(); -} - -real_t SliderJointBullet::getDampingDirLin() const { - return sliderConstraint->getDampingDirLin(); -} - -real_t SliderJointBullet::getSoftnessDirAng() const { - return sliderConstraint->getSoftnessDirAng(); -} - -real_t SliderJointBullet::getRestitutionDirAng() const { - return sliderConstraint->getRestitutionDirAng(); -} - -real_t SliderJointBullet::getDampingDirAng() const { - return sliderConstraint->getDampingDirAng(); -} - -real_t SliderJointBullet::getSoftnessLimLin() const { - return sliderConstraint->getSoftnessLimLin(); -} - -real_t SliderJointBullet::getRestitutionLimLin() const { - return sliderConstraint->getRestitutionLimLin(); -} - -real_t SliderJointBullet::getDampingLimLin() const { - return sliderConstraint->getDampingLimLin(); -} - -real_t SliderJointBullet::getSoftnessLimAng() const { - return sliderConstraint->getSoftnessLimAng(); -} - -real_t SliderJointBullet::getRestitutionLimAng() const { - return sliderConstraint->getRestitutionLimAng(); -} - -real_t SliderJointBullet::getDampingLimAng() const { - return sliderConstraint->getDampingLimAng(); -} - -real_t SliderJointBullet::getSoftnessOrthoLin() const { - return sliderConstraint->getSoftnessOrthoLin(); -} - -real_t SliderJointBullet::getRestitutionOrthoLin() const { - return sliderConstraint->getRestitutionOrthoLin(); -} - -real_t SliderJointBullet::getDampingOrthoLin() const { - return sliderConstraint->getDampingOrthoLin(); -} - -real_t SliderJointBullet::getSoftnessOrthoAng() const { - return sliderConstraint->getSoftnessOrthoAng(); -} - -real_t SliderJointBullet::getRestitutionOrthoAng() const { - return sliderConstraint->getRestitutionOrthoAng(); -} - -real_t SliderJointBullet::getDampingOrthoAng() const { - return sliderConstraint->getDampingOrthoAng(); -} - -void SliderJointBullet::setSoftnessDirLin(real_t softnessDirLin) { - sliderConstraint->setSoftnessDirLin(softnessDirLin); -} - -void SliderJointBullet::setRestitutionDirLin(real_t restitutionDirLin) { - sliderConstraint->setRestitutionDirLin(restitutionDirLin); -} - -void SliderJointBullet::setDampingDirLin(real_t dampingDirLin) { - sliderConstraint->setDampingDirLin(dampingDirLin); -} - -void SliderJointBullet::setSoftnessDirAng(real_t softnessDirAng) { - sliderConstraint->setSoftnessDirAng(softnessDirAng); -} - -void SliderJointBullet::setRestitutionDirAng(real_t restitutionDirAng) { - sliderConstraint->setRestitutionDirAng(restitutionDirAng); -} - -void SliderJointBullet::setDampingDirAng(real_t dampingDirAng) { - sliderConstraint->setDampingDirAng(dampingDirAng); -} - -void SliderJointBullet::setSoftnessLimLin(real_t softnessLimLin) { - sliderConstraint->setSoftnessLimLin(softnessLimLin); -} - -void SliderJointBullet::setRestitutionLimLin(real_t restitutionLimLin) { - sliderConstraint->setRestitutionLimLin(restitutionLimLin); -} - -void SliderJointBullet::setDampingLimLin(real_t dampingLimLin) { - sliderConstraint->setDampingLimLin(dampingLimLin); -} - -void SliderJointBullet::setSoftnessLimAng(real_t softnessLimAng) { - sliderConstraint->setSoftnessLimAng(softnessLimAng); -} - -void SliderJointBullet::setRestitutionLimAng(real_t restitutionLimAng) { - sliderConstraint->setRestitutionLimAng(restitutionLimAng); -} - -void SliderJointBullet::setDampingLimAng(real_t dampingLimAng) { - sliderConstraint->setDampingLimAng(dampingLimAng); -} - -void SliderJointBullet::setSoftnessOrthoLin(real_t softnessOrthoLin) { - sliderConstraint->setSoftnessOrthoLin(softnessOrthoLin); -} - -void SliderJointBullet::setRestitutionOrthoLin(real_t restitutionOrthoLin) { - sliderConstraint->setRestitutionOrthoLin(restitutionOrthoLin); -} - -void SliderJointBullet::setDampingOrthoLin(real_t dampingOrthoLin) { - sliderConstraint->setDampingOrthoLin(dampingOrthoLin); -} - -void SliderJointBullet::setSoftnessOrthoAng(real_t softnessOrthoAng) { - sliderConstraint->setSoftnessOrthoAng(softnessOrthoAng); -} - -void SliderJointBullet::setRestitutionOrthoAng(real_t restitutionOrthoAng) { - sliderConstraint->setRestitutionOrthoAng(restitutionOrthoAng); -} - -void SliderJointBullet::setDampingOrthoAng(real_t dampingOrthoAng) { - sliderConstraint->setDampingOrthoAng(dampingOrthoAng); -} - -void SliderJointBullet::setPoweredLinMotor(bool onOff) { - sliderConstraint->setPoweredLinMotor(onOff); -} - -bool SliderJointBullet::getPoweredLinMotor() { - return sliderConstraint->getPoweredLinMotor(); -} - -void SliderJointBullet::setTargetLinMotorVelocity(real_t targetLinMotorVelocity) { - sliderConstraint->setTargetLinMotorVelocity(targetLinMotorVelocity); -} - -real_t SliderJointBullet::getTargetLinMotorVelocity() { - return sliderConstraint->getTargetLinMotorVelocity(); -} - -void SliderJointBullet::setMaxLinMotorForce(real_t maxLinMotorForce) { - sliderConstraint->setMaxLinMotorForce(maxLinMotorForce); -} - -real_t SliderJointBullet::getMaxLinMotorForce() { - return sliderConstraint->getMaxLinMotorForce(); -} - -void SliderJointBullet::setPoweredAngMotor(bool onOff) { - sliderConstraint->setPoweredAngMotor(onOff); -} - -bool SliderJointBullet::getPoweredAngMotor() { - return sliderConstraint->getPoweredAngMotor(); -} - -void SliderJointBullet::setTargetAngMotorVelocity(real_t targetAngMotorVelocity) { - sliderConstraint->setTargetAngMotorVelocity(targetAngMotorVelocity); -} - -real_t SliderJointBullet::getTargetAngMotorVelocity() { - return sliderConstraint->getTargetAngMotorVelocity(); -} - -void SliderJointBullet::setMaxAngMotorForce(real_t maxAngMotorForce) { - sliderConstraint->setMaxAngMotorForce(maxAngMotorForce); -} - -real_t SliderJointBullet::getMaxAngMotorForce() { - return sliderConstraint->getMaxAngMotorForce(); -} - -real_t SliderJointBullet::getLinearPos() { - return sliderConstraint->getLinearPos(); -} - -void SliderJointBullet::set_param(PhysicsServer3D::SliderJointParam p_param, real_t p_value) { - switch (p_param) { - case PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_UPPER: - setUpperLinLimit(p_value); - break; - case PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_LOWER: - setLowerLinLimit(p_value); - break; - case PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_SOFTNESS: - setSoftnessLimLin(p_value); - break; - case PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_RESTITUTION: - setRestitutionLimLin(p_value); - break; - case PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_DAMPING: - setDampingLimLin(p_value); - break; - case PhysicsServer3D::SLIDER_JOINT_LINEAR_MOTION_SOFTNESS: - setSoftnessDirLin(p_value); - break; - case PhysicsServer3D::SLIDER_JOINT_LINEAR_MOTION_RESTITUTION: - setRestitutionDirLin(p_value); - break; - case PhysicsServer3D::SLIDER_JOINT_LINEAR_MOTION_DAMPING: - setDampingDirLin(p_value); - break; - case PhysicsServer3D::SLIDER_JOINT_LINEAR_ORTHOGONAL_SOFTNESS: - setSoftnessOrthoLin(p_value); - break; - case PhysicsServer3D::SLIDER_JOINT_LINEAR_ORTHOGONAL_RESTITUTION: - setRestitutionOrthoLin(p_value); - break; - case PhysicsServer3D::SLIDER_JOINT_LINEAR_ORTHOGONAL_DAMPING: - setDampingOrthoLin(p_value); - break; - case PhysicsServer3D::SLIDER_JOINT_ANGULAR_LIMIT_UPPER: - setUpperAngLimit(p_value); - break; - case PhysicsServer3D::SLIDER_JOINT_ANGULAR_LIMIT_LOWER: - setLowerAngLimit(p_value); - break; - case PhysicsServer3D::SLIDER_JOINT_ANGULAR_LIMIT_SOFTNESS: - setSoftnessLimAng(p_value); - break; - case PhysicsServer3D::SLIDER_JOINT_ANGULAR_LIMIT_RESTITUTION: - setRestitutionLimAng(p_value); - break; - case PhysicsServer3D::SLIDER_JOINT_ANGULAR_LIMIT_DAMPING: - setDampingLimAng(p_value); - break; - case PhysicsServer3D::SLIDER_JOINT_ANGULAR_MOTION_SOFTNESS: - setSoftnessDirAng(p_value); - break; - case PhysicsServer3D::SLIDER_JOINT_ANGULAR_MOTION_RESTITUTION: - setRestitutionDirAng(p_value); - break; - case PhysicsServer3D::SLIDER_JOINT_ANGULAR_MOTION_DAMPING: - setDampingDirAng(p_value); - break; - case PhysicsServer3D::SLIDER_JOINT_ANGULAR_ORTHOGONAL_SOFTNESS: - setSoftnessOrthoAng(p_value); - break; - case PhysicsServer3D::SLIDER_JOINT_ANGULAR_ORTHOGONAL_RESTITUTION: - setRestitutionOrthoAng(p_value); - break; - case PhysicsServer3D::SLIDER_JOINT_ANGULAR_ORTHOGONAL_DAMPING: - setDampingOrthoAng(p_value); - break; - case PhysicsServer3D::SLIDER_JOINT_MAX: - break; // Can't happen, but silences warning - } -} - -real_t SliderJointBullet::get_param(PhysicsServer3D::SliderJointParam p_param) const { - switch (p_param) { - case PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_UPPER: - return getUpperLinLimit(); - case PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_LOWER: - return getLowerLinLimit(); - case PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_SOFTNESS: - return getSoftnessLimLin(); - case PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_RESTITUTION: - return getRestitutionLimLin(); - case PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_DAMPING: - return getDampingLimLin(); - case PhysicsServer3D::SLIDER_JOINT_LINEAR_MOTION_SOFTNESS: - return getSoftnessDirLin(); - case PhysicsServer3D::SLIDER_JOINT_LINEAR_MOTION_RESTITUTION: - return getRestitutionDirLin(); - case PhysicsServer3D::SLIDER_JOINT_LINEAR_MOTION_DAMPING: - return getDampingDirLin(); - case PhysicsServer3D::SLIDER_JOINT_LINEAR_ORTHOGONAL_SOFTNESS: - return getSoftnessOrthoLin(); - case PhysicsServer3D::SLIDER_JOINT_LINEAR_ORTHOGONAL_RESTITUTION: - return getRestitutionOrthoLin(); - case PhysicsServer3D::SLIDER_JOINT_LINEAR_ORTHOGONAL_DAMPING: - return getDampingOrthoLin(); - case PhysicsServer3D::SLIDER_JOINT_ANGULAR_LIMIT_UPPER: - return getUpperAngLimit(); - case PhysicsServer3D::SLIDER_JOINT_ANGULAR_LIMIT_LOWER: - return getLowerAngLimit(); - case PhysicsServer3D::SLIDER_JOINT_ANGULAR_LIMIT_SOFTNESS: - return getSoftnessLimAng(); - case PhysicsServer3D::SLIDER_JOINT_ANGULAR_LIMIT_RESTITUTION: - return getRestitutionLimAng(); - case PhysicsServer3D::SLIDER_JOINT_ANGULAR_LIMIT_DAMPING: - return getDampingLimAng(); - case PhysicsServer3D::SLIDER_JOINT_ANGULAR_MOTION_SOFTNESS: - return getSoftnessDirAng(); - case PhysicsServer3D::SLIDER_JOINT_ANGULAR_MOTION_RESTITUTION: - return getRestitutionDirAng(); - case PhysicsServer3D::SLIDER_JOINT_ANGULAR_MOTION_DAMPING: - return getDampingDirAng(); - case PhysicsServer3D::SLIDER_JOINT_ANGULAR_ORTHOGONAL_SOFTNESS: - return getSoftnessOrthoAng(); - case PhysicsServer3D::SLIDER_JOINT_ANGULAR_ORTHOGONAL_RESTITUTION: - return getRestitutionOrthoAng(); - case PhysicsServer3D::SLIDER_JOINT_ANGULAR_ORTHOGONAL_DAMPING: - return getDampingOrthoAng(); - default: - return 0; - } -} diff --git a/modules/bullet/slider_joint_bullet.h b/modules/bullet/slider_joint_bullet.h deleted file mode 100644 index c355eb340b..0000000000 --- a/modules/bullet/slider_joint_bullet.h +++ /dev/null @@ -1,118 +0,0 @@ -/*************************************************************************/ -/* slider_joint_bullet.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* 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. */ -/*************************************************************************/ - -#ifndef SLIDER_JOINT_BULLET_H -#define SLIDER_JOINT_BULLET_H - -#include "joint_bullet.h" - -class RigidBodyBullet; - -class SliderJointBullet : public JointBullet { - class btSliderConstraint *sliderConstraint; - -public: - /// Reference frame is A - SliderJointBullet(RigidBodyBullet *rbA, RigidBodyBullet *rbB, const Transform3D &frameInA, const Transform3D &frameInB); - - virtual PhysicsServer3D::JointType get_type() const { return PhysicsServer3D::JOINT_SLIDER; } - - const RigidBodyBullet *getRigidBodyA() const; - const RigidBodyBullet *getRigidBodyB() const; - const Transform3D getCalculatedTransformA() const; - const Transform3D getCalculatedTransformB() const; - const Transform3D getFrameOffsetA() const; - const Transform3D getFrameOffsetB() const; - Transform3D getFrameOffsetA(); - Transform3D getFrameOffsetB(); - real_t getLowerLinLimit() const; - void setLowerLinLimit(real_t lowerLimit); - real_t getUpperLinLimit() const; - void setUpperLinLimit(real_t upperLimit); - real_t getLowerAngLimit() const; - void setLowerAngLimit(real_t lowerLimit); - real_t getUpperAngLimit() const; - void setUpperAngLimit(real_t upperLimit); - - real_t getSoftnessDirLin() const; - real_t getRestitutionDirLin() const; - real_t getDampingDirLin() const; - real_t getSoftnessDirAng() const; - real_t getRestitutionDirAng() const; - real_t getDampingDirAng() const; - real_t getSoftnessLimLin() const; - real_t getRestitutionLimLin() const; - real_t getDampingLimLin() const; - real_t getSoftnessLimAng() const; - real_t getRestitutionLimAng() const; - real_t getDampingLimAng() const; - real_t getSoftnessOrthoLin() const; - real_t getRestitutionOrthoLin() const; - real_t getDampingOrthoLin() const; - real_t getSoftnessOrthoAng() const; - real_t getRestitutionOrthoAng() const; - real_t getDampingOrthoAng() const; - void setSoftnessDirLin(real_t softnessDirLin); - void setRestitutionDirLin(real_t restitutionDirLin); - void setDampingDirLin(real_t dampingDirLin); - void setSoftnessDirAng(real_t softnessDirAng); - void setRestitutionDirAng(real_t restitutionDirAng); - void setDampingDirAng(real_t dampingDirAng); - void setSoftnessLimLin(real_t softnessLimLin); - void setRestitutionLimLin(real_t restitutionLimLin); - void setDampingLimLin(real_t dampingLimLin); - void setSoftnessLimAng(real_t softnessLimAng); - void setRestitutionLimAng(real_t restitutionLimAng); - void setDampingLimAng(real_t dampingLimAng); - void setSoftnessOrthoLin(real_t softnessOrthoLin); - void setRestitutionOrthoLin(real_t restitutionOrthoLin); - void setDampingOrthoLin(real_t dampingOrthoLin); - void setSoftnessOrthoAng(real_t softnessOrthoAng); - void setRestitutionOrthoAng(real_t restitutionOrthoAng); - void setDampingOrthoAng(real_t dampingOrthoAng); - void setPoweredLinMotor(bool onOff); - bool getPoweredLinMotor(); - void setTargetLinMotorVelocity(real_t targetLinMotorVelocity); - real_t getTargetLinMotorVelocity(); - void setMaxLinMotorForce(real_t maxLinMotorForce); - real_t getMaxLinMotorForce(); - void setPoweredAngMotor(bool onOff); - bool getPoweredAngMotor(); - void setTargetAngMotorVelocity(real_t targetAngMotorVelocity); - real_t getTargetAngMotorVelocity(); - void setMaxAngMotorForce(real_t maxAngMotorForce); - real_t getMaxAngMotorForce(); - real_t getLinearPos(); - - void set_param(PhysicsServer3D::SliderJointParam p_param, real_t p_value); - real_t get_param(PhysicsServer3D::SliderJointParam p_param) const; -}; - -#endif // SLIDER_JOINT_BULLET_H diff --git a/modules/bullet/soft_body_bullet.cpp b/modules/bullet/soft_body_bullet.cpp deleted file mode 100644 index ea5a059b9e..0000000000 --- a/modules/bullet/soft_body_bullet.cpp +++ /dev/null @@ -1,456 +0,0 @@ -/*************************************************************************/ -/* soft_body_bullet.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* 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 "soft_body_bullet.h" - -#include "bullet_types_converter.h" -#include "bullet_utilities.h" -#include "space_bullet.h" - -#include "servers/rendering_server.h" - -SoftBodyBullet::SoftBodyBullet() : - CollisionObjectBullet(CollisionObjectBullet::TYPE_SOFT_BODY) {} - -SoftBodyBullet::~SoftBodyBullet() { -} - -void SoftBodyBullet::reload_body() { - if (space) { - space->remove_soft_body(this); - space->add_soft_body(this); - } -} - -void SoftBodyBullet::set_space(SpaceBullet *p_space) { - if (space) { - isScratched = false; - space->remove_soft_body(this); - } - - space = p_space; - - if (space) { - space->add_soft_body(this); - } -} - -void SoftBodyBullet::on_enter_area(AreaBullet *p_area) {} - -void SoftBodyBullet::on_exit_area(AreaBullet *p_area) {} - -void SoftBodyBullet::update_rendering_server(RenderingServerHandler *p_rendering_server_handler) { - if (!bt_soft_body) { - return; - } - - /// Update rendering server vertices - const btSoftBody::tNodeArray &nodes(bt_soft_body->m_nodes); - const int nodes_count = nodes.size(); - - const Vector<int> *vs_indices; - const void *vertex_position; - const void *vertex_normal; - - for (int vertex_index = 0; vertex_index < nodes_count; ++vertex_index) { - vertex_position = reinterpret_cast<const void *>(&nodes[vertex_index].m_x); - vertex_normal = reinterpret_cast<const void *>(&nodes[vertex_index].m_n); - - vs_indices = &indices_table[vertex_index]; - - const int vs_indices_size(vs_indices->size()); - for (int x = 0; x < vs_indices_size; ++x) { - p_rendering_server_handler->set_vertex((*vs_indices)[x], vertex_position); - p_rendering_server_handler->set_normal((*vs_indices)[x], vertex_normal); - } - } - - /// Generate AABB - btVector3 aabb_min; - btVector3 aabb_max; - bt_soft_body->getAabb(aabb_min, aabb_max); - - btVector3 size(aabb_max - aabb_min); - - AABB aabb; - B_TO_G(aabb_min, aabb.position); - B_TO_G(size, aabb.size); - - p_rendering_server_handler->set_aabb(aabb); -} - -void SoftBodyBullet::set_soft_mesh(RID p_mesh) { - destroy_soft_body(); - - soft_mesh = p_mesh; - - if (soft_mesh.is_null()) { - return; - } - - Array arrays = RenderingServer::get_singleton()->mesh_surface_get_arrays(soft_mesh, 0); - ERR_FAIL_COND(arrays.is_empty()); - - bool success = set_trimesh_body_shape(arrays[RS::ARRAY_INDEX], arrays[RS::ARRAY_VERTEX]); - if (!success) { - destroy_soft_body(); - } -} - -void SoftBodyBullet::destroy_soft_body() { - soft_mesh = RID(); - - if (!bt_soft_body) { - return; - } - - if (space) { - /// Remove from world before deletion - space->remove_soft_body(this); - } - - destroyBulletCollisionObject(); - bt_soft_body = nullptr; -} - -void SoftBodyBullet::set_soft_transform(const Transform3D &p_transform) { - reset_all_node_positions(); - move_all_nodes(p_transform); -} - -AABB SoftBodyBullet::get_bounds() const { - if (!bt_soft_body) { - return AABB(); - } - - btVector3 aabb_min; - btVector3 aabb_max; - bt_soft_body->getAabb(aabb_min, aabb_max); - - btVector3 size(aabb_max - aabb_min); - - AABB aabb; - B_TO_G(aabb_min, aabb.position); - B_TO_G(size, aabb.size); - - return aabb; -} - -void SoftBodyBullet::move_all_nodes(const Transform3D &p_transform) { - if (!bt_soft_body) { - return; - } - btTransform bt_transf; - G_TO_B(p_transform, bt_transf); - bt_soft_body->transform(bt_transf); -} - -void SoftBodyBullet::set_node_position(int p_node_index, const Vector3 &p_global_position) { - btVector3 bt_pos; - G_TO_B(p_global_position, bt_pos); - set_node_position(p_node_index, bt_pos); -} - -void SoftBodyBullet::set_node_position(int p_node_index, const btVector3 &p_global_position) { - if (bt_soft_body) { - bt_soft_body->m_nodes[p_node_index].m_q = bt_soft_body->m_nodes[p_node_index].m_x; - bt_soft_body->m_nodes[p_node_index].m_x = p_global_position; - } -} - -void SoftBodyBullet::get_node_position(int p_node_index, Vector3 &r_position) const { - if (bt_soft_body) { - B_TO_G(bt_soft_body->m_nodes[p_node_index].m_x, r_position); - } -} - -void SoftBodyBullet::set_node_mass(int p_node_index, btScalar p_mass) { - if (0 >= p_mass) { - pin_node(p_node_index); - } else { - unpin_node(p_node_index); - } - if (bt_soft_body) { - ERR_FAIL_INDEX(p_node_index, bt_soft_body->m_nodes.size()); - bt_soft_body->setMass(p_node_index, p_mass); - } -} - -btScalar SoftBodyBullet::get_node_mass(int p_node_index) const { - if (bt_soft_body) { - ERR_FAIL_INDEX_V(p_node_index, bt_soft_body->m_nodes.size(), 1); - return bt_soft_body->getMass(p_node_index); - } else { - return -1 == search_node_pinned(p_node_index) ? 1 : 0; - } -} - -void SoftBodyBullet::reset_all_node_mass() { - if (bt_soft_body) { - for (int i = pinned_nodes.size() - 1; 0 <= i; --i) { - bt_soft_body->setMass(pinned_nodes[i], 1); - } - } - pinned_nodes.resize(0); -} - -void SoftBodyBullet::reset_all_node_positions() { - if (soft_mesh.is_null()) { - return; - } - - Array arrays = soft_mesh->surface_get_arrays(0); - Vector<Vector3> vs_vertices(arrays[RS::ARRAY_VERTEX]); - const Vector3 *vs_vertices_read = vs_vertices.ptr(); - - for (int vertex_index = bt_soft_body->m_nodes.size() - 1; 0 <= vertex_index; --vertex_index) { - G_TO_B(vs_vertices_read[indices_table[vertex_index][0]], bt_soft_body->m_nodes[vertex_index].m_x); - - bt_soft_body->m_nodes[vertex_index].m_q = bt_soft_body->m_nodes[vertex_index].m_x; - bt_soft_body->m_nodes[vertex_index].m_v = btVector3(0, 0, 0); - bt_soft_body->m_nodes[vertex_index].m_f = btVector3(0, 0, 0); - } -} - -void SoftBodyBullet::set_activation_state(bool p_active) { - if (p_active) { - bt_soft_body->setActivationState(ACTIVE_TAG); - } else { - bt_soft_body->setActivationState(WANTS_DEACTIVATION); - } -} - -void SoftBodyBullet::set_total_mass(real_t p_val) { - if (0 >= p_val) { - p_val = 1; - } - total_mass = p_val; - if (bt_soft_body) { - bt_soft_body->setTotalMass(total_mass); - } -} - -void SoftBodyBullet::set_linear_stiffness(real_t p_val) { - linear_stiffness = p_val; - if (bt_soft_body) { - mat0->m_kLST = linear_stiffness; - } -} - -void SoftBodyBullet::set_simulation_precision(int p_val) { - simulation_precision = p_val; - if (bt_soft_body) { - bt_soft_body->m_cfg.piterations = simulation_precision; - bt_soft_body->m_cfg.viterations = simulation_precision; - bt_soft_body->m_cfg.diterations = simulation_precision; - bt_soft_body->m_cfg.citerations = simulation_precision; - } -} - -void SoftBodyBullet::set_pressure_coefficient(real_t p_val) { - pressure_coefficient = p_val; - if (bt_soft_body) { - bt_soft_body->m_cfg.kPR = pressure_coefficient; - } -} - -void SoftBodyBullet::set_damping_coefficient(real_t p_val) { - damping_coefficient = p_val; - if (bt_soft_body) { - bt_soft_body->m_cfg.kDP = damping_coefficient; - } -} - -void SoftBodyBullet::set_drag_coefficient(real_t p_val) { - drag_coefficient = p_val; - if (bt_soft_body) { - bt_soft_body->m_cfg.kDG = drag_coefficient; - } -} - -bool SoftBodyBullet::set_trimesh_body_shape(Vector<int> p_indices, Vector<Vector3> p_vertices) { - ERR_FAIL_COND_V(p_indices.is_empty(), false); - ERR_FAIL_COND_V(p_vertices.is_empty(), false); - - /// Parse rendering server indices to physical indices. - /// Merge all overlapping vertices and create a map of physical vertices to rendering server - - { - /// This is the map of rendering server indices to physics indices (So it's the inverse of idices_map), Thanks to it I don't need make a heavy search in the indices_map - Vector<int> vs_indices_to_physics_table; - - { // Map vertices - indices_table.resize(0); - - int index = 0; - Map<Vector3, int> unique_vertices; - - const int vs_vertices_size(p_vertices.size()); - - const Vector3 *p_vertices_read = p_vertices.ptr(); - - for (int vs_vertex_index = 0; vs_vertex_index < vs_vertices_size; ++vs_vertex_index) { - Map<Vector3, int>::Element *e = unique_vertices.find(p_vertices_read[vs_vertex_index]); - int vertex_id; - if (e) { - // Already existing - vertex_id = e->value(); - } else { - // Create new one - unique_vertices[p_vertices_read[vs_vertex_index]] = vertex_id = index++; - indices_table.push_back(Vector<int>()); - } - - indices_table.write[vertex_id].push_back(vs_vertex_index); - vs_indices_to_physics_table.push_back(vertex_id); - } - } - - const int indices_map_size(indices_table.size()); - - Vector<btScalar> bt_vertices; - - { // Parse vertices to bullet - - bt_vertices.resize(indices_map_size * 3); - const Vector3 *p_vertices_read = p_vertices.ptr(); - - for (int i = 0; i < indices_map_size; ++i) { - bt_vertices.write[3 * i + 0] = p_vertices_read[indices_table[i][0]].x; - bt_vertices.write[3 * i + 1] = p_vertices_read[indices_table[i][0]].y; - bt_vertices.write[3 * i + 2] = p_vertices_read[indices_table[i][0]].z; - } - } - - Vector<int> bt_triangles; - const int triangles_size(p_indices.size() / 3); - - { // Parse indices - - bt_triangles.resize(triangles_size * 3); - - const int *p_indices_read = p_indices.ptr(); - - for (int i = 0; i < triangles_size; ++i) { - bt_triangles.write[3 * i + 0] = vs_indices_to_physics_table[p_indices_read[3 * i + 2]]; - bt_triangles.write[3 * i + 1] = vs_indices_to_physics_table[p_indices_read[3 * i + 1]]; - bt_triangles.write[3 * i + 2] = vs_indices_to_physics_table[p_indices_read[3 * i + 0]]; - } - } - - btSoftBodyWorldInfo fake_world_info; - bt_soft_body = btSoftBodyHelpers::CreateFromTriMesh(fake_world_info, &bt_vertices[0], &bt_triangles[0], triangles_size, false); - setup_soft_body(); - } - - return true; -} - -void SoftBodyBullet::setup_soft_body() { - if (!bt_soft_body) { - return; - } - - // Soft body setup - setupBulletCollisionObject(bt_soft_body); - bt_soft_body->m_worldInfo = nullptr; // Remove fake world info - bt_soft_body->getCollisionShape()->setMargin(0.01); - bt_soft_body->setCollisionFlags(bt_soft_body->getCollisionFlags() & (~(btCollisionObject::CF_KINEMATIC_OBJECT | btCollisionObject::CF_STATIC_OBJECT))); - - // Space setup - if (space) { - space->add_soft_body(this); - } - - mat0 = bt_soft_body->appendMaterial(); - - // Assign soft body data - bt_soft_body->generateBendingConstraints(2, mat0); - - mat0->m_kLST = linear_stiffness; - - // Clusters allow to have Soft vs Soft collision but doesn't work well right now - - //bt_soft_body->m_cfg.kSRHR_CL = 1;// Soft vs rigid hardness [0,1] (cluster only) - //bt_soft_body->m_cfg.kSKHR_CL = 1;// Soft vs kinematic hardness [0,1] (cluster only) - //bt_soft_body->m_cfg.kSSHR_CL = 1;// Soft vs soft hardness [0,1] (cluster only) - //bt_soft_body->m_cfg.kSR_SPLT_CL = 1; // Soft vs rigid impulse split [0,1] (cluster only) - //bt_soft_body->m_cfg.kSK_SPLT_CL = 1; // Soft vs kinematic impulse split [0,1] (cluster only) - //bt_soft_body->m_cfg.kSS_SPLT_CL = 1; // Soft vs Soft impulse split [0,1] (cluster only) - //bt_soft_body->m_cfg.collisions = btSoftBody::fCollision::CL_SS + btSoftBody::fCollision::CL_RS + btSoftBody::fCollision::VF_SS; - //bt_soft_body->generateClusters(64); - - bt_soft_body->m_cfg.piterations = simulation_precision; - bt_soft_body->m_cfg.viterations = simulation_precision; - bt_soft_body->m_cfg.diterations = simulation_precision; - bt_soft_body->m_cfg.citerations = simulation_precision; - bt_soft_body->m_cfg.kDP = damping_coefficient; - bt_soft_body->m_cfg.kDG = drag_coefficient; - bt_soft_body->m_cfg.kPR = pressure_coefficient; - bt_soft_body->setTotalMass(total_mass); - - btSoftBodyHelpers::ReoptimizeLinkOrder(bt_soft_body); - bt_soft_body->updateBounds(); - - // Set pinned nodes - for (int i = pinned_nodes.size() - 1; 0 <= i; --i) { - const int node_index = pinned_nodes[i]; - ERR_CONTINUE(0 > node_index || bt_soft_body->m_nodes.size() <= node_index); - bt_soft_body->setMass(node_index, 0); - } -} - -void SoftBodyBullet::pin_node(int p_node_index) { - if (bt_soft_body) { - ERR_FAIL_INDEX(p_node_index, bt_soft_body->m_nodes.size()); - } - if (-1 == search_node_pinned(p_node_index)) { - pinned_nodes.push_back(p_node_index); - } -} - -void SoftBodyBullet::unpin_node(int p_node_index) { - if (bt_soft_body) { - ERR_FAIL_INDEX(p_node_index, bt_soft_body->m_nodes.size()); - } - const int id = search_node_pinned(p_node_index); - if (-1 != id) { - pinned_nodes.remove_at(id); - } -} - -int SoftBodyBullet::search_node_pinned(int p_node_index) const { - for (int i = pinned_nodes.size() - 1; 0 <= i; --i) { - if (p_node_index == pinned_nodes[i]) { - return i; - } - } - return -1; -} diff --git a/modules/bullet/soft_body_bullet.h b/modules/bullet/soft_body_bullet.h deleted file mode 100644 index 82a7bb3b0c..0000000000 --- a/modules/bullet/soft_body_bullet.h +++ /dev/null @@ -1,144 +0,0 @@ -/*************************************************************************/ -/* soft_body_bullet.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* 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. */ -/*************************************************************************/ - -#ifndef SOFT_BODY_BULLET_H -#define SOFT_BODY_BULLET_H - -#include "collision_object_bullet.h" - -#ifdef None -/// This is required to remove the macro None defined by x11 compiler because this word "None" is used internally by Bullet -#undef None -#define x11_None 0L -#endif - -#include "BulletSoftBody/btSoftBodyHelpers.h" -#include "collision_object_bullet.h" -#include "servers/physics_server_3d.h" - -#ifdef x11_None -/// This is required to re add the macro None defined by x11 compiler -#undef x11_None -#define None 0L -#endif - -class RenderingServerHandler; - -class SoftBodyBullet : public CollisionObjectBullet { -private: - btSoftBody *bt_soft_body = nullptr; - Vector<Vector<int>> indices_table; - btSoftBody::Material *mat0 = nullptr; // This is just a copy of pointer managed by btSoftBody - bool isScratched = false; - - RID soft_mesh; - - int simulation_precision = 5; - real_t total_mass = 1.; - real_t linear_stiffness = 0.5; // [0,1] - real_t pressure_coefficient = 0.; // [-inf,+inf] - real_t damping_coefficient = 0.01; // [0,1] - real_t drag_coefficient = 0.; // [0,1] - Vector<int> pinned_nodes; - - // Other property to add - //btScalar kVC; // Volume conversation coefficient [0,+inf] - //btScalar kDF; // Dynamic friction coefficient [0,1] - //btScalar kMT; // Pose matching coefficient [0,1] - //btScalar kCHR; // Rigid contacts hardness [0,1] - //btScalar kKHR; // Kinetic contacts hardness [0,1] - //btScalar kSHR; // Soft contacts hardness [0,1] - -public: - SoftBodyBullet(); - ~SoftBodyBullet(); - - virtual void reload_body(); - virtual void set_space(SpaceBullet *p_space); - - virtual void dispatch_callbacks() {} - virtual void on_collision_filters_change() {} - virtual void on_collision_checker_start() {} - virtual void on_collision_checker_end() {} - virtual void on_enter_area(AreaBullet *p_area); - virtual void on_exit_area(AreaBullet *p_area); - - _FORCE_INLINE_ btSoftBody *get_bt_soft_body() const { return bt_soft_body; } - - void update_rendering_server(RenderingServerHandler *p_rendering_server_handler); - - void set_soft_mesh(RID p_mesh); - void destroy_soft_body(); - - // Special function. This function has bad performance - void set_soft_transform(const Transform3D &p_transform); - - AABB get_bounds() const; - - void move_all_nodes(const Transform3D &p_transform); - void set_node_position(int node_index, const Vector3 &p_global_position); - void set_node_position(int node_index, const btVector3 &p_global_position); - void get_node_position(int node_index, Vector3 &r_position) const; - - void set_node_mass(int node_index, btScalar p_mass); - btScalar get_node_mass(int node_index) const; - void reset_all_node_mass(); - void reset_all_node_positions(); - - void set_activation_state(bool p_active); - - void set_total_mass(real_t p_val); - _FORCE_INLINE_ real_t get_total_mass() const { return total_mass; } - - void set_linear_stiffness(real_t p_val); - _FORCE_INLINE_ real_t get_linear_stiffness() const { return linear_stiffness; } - - void set_simulation_precision(int p_val); - _FORCE_INLINE_ int get_simulation_precision() const { return simulation_precision; } - - void set_pressure_coefficient(real_t p_val); - _FORCE_INLINE_ real_t get_pressure_coefficient() const { return pressure_coefficient; } - - void set_damping_coefficient(real_t p_val); - _FORCE_INLINE_ real_t get_damping_coefficient() const { return damping_coefficient; } - - void set_drag_coefficient(real_t p_val); - _FORCE_INLINE_ real_t get_drag_coefficient() const { return drag_coefficient; } - -private: - bool set_trimesh_body_shape(Vector<int> p_indices, Vector<Vector3> p_vertices); - void setup_soft_body(); - - void pin_node(int p_node_index); - void unpin_node(int p_node_index); - int search_node_pinned(int p_node_index) const; -}; - -#endif // SOFT_BODY_BULLET_H diff --git a/modules/bullet/space_bullet.cpp b/modules/bullet/space_bullet.cpp deleted file mode 100644 index 460b78d778..0000000000 --- a/modules/bullet/space_bullet.cpp +++ /dev/null @@ -1,1436 +0,0 @@ -/*************************************************************************/ -/* space_bullet.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* 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 "space_bullet.h" - -#include "bullet_physics_server.h" -#include "bullet_types_converter.h" -#include "bullet_utilities.h" -#include "constraint_bullet.h" -#include "core/config/project_settings.h" -#include "core/string/ustring.h" -#include "godot_collision_configuration.h" -#include "godot_collision_dispatcher.h" -#include "rigid_body_bullet.h" -#include "servers/physics_server_3d.h" -#include "soft_body_bullet.h" - -#include <BulletCollision/BroadphaseCollision/btBroadphaseProxy.h> -#include <BulletCollision/CollisionDispatch/btCollisionObject.h> -#include <BulletCollision/CollisionDispatch/btGhostObject.h> -#include <BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h> -#include <BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h> -#include <BulletCollision/NarrowPhaseCollision/btPointCollector.h> -#include <BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h> -#include <BulletSoftBody/btSoftRigidDynamicsWorld.h> -#include <btBulletDynamicsCommon.h> - -#include <assert.h> - -BulletPhysicsDirectSpaceState::BulletPhysicsDirectSpaceState(SpaceBullet *p_space) : - PhysicsDirectSpaceState3D(), - space(p_space) {} - -int BulletPhysicsDirectSpaceState::intersect_point(const Vector3 &p_point, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) { - if (p_result_max <= 0) { - return 0; - } - - btVector3 bt_point; - G_TO_B(p_point, bt_point); - - btSphereShape sphere_point(0.001f); - btCollisionObject collision_object_point; - collision_object_point.setCollisionShape(&sphere_point); - collision_object_point.setWorldTransform(btTransform(btQuaternion::getIdentity(), bt_point)); - - // Setup query - GodotAllContactResultCallback btResult(&collision_object_point, r_results, p_result_max, &p_exclude, p_collide_with_bodies, p_collide_with_areas); - btResult.m_collisionFilterGroup = 0; - btResult.m_collisionFilterMask = p_collision_mask; - space->dynamicsWorld->contactTest(&collision_object_point, btResult); - - // The results are already populated by GodotAllConvexResultCallback - return btResult.m_count; -} - -bool BulletPhysicsDirectSpaceState::intersect_ray(const Vector3 &p_from, const Vector3 &p_to, RayResult &r_result, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas, bool p_pick_ray) { - btVector3 btVec_from; - btVector3 btVec_to; - - G_TO_B(p_from, btVec_from); - G_TO_B(p_to, btVec_to); - - // setup query - GodotClosestRayResultCallback btResult(btVec_from, btVec_to, &p_exclude, p_collide_with_bodies, p_collide_with_areas); - btResult.m_collisionFilterGroup = 0; - btResult.m_collisionFilterMask = p_collision_mask; - btResult.m_pickRay = p_pick_ray; - - space->dynamicsWorld->rayTest(btVec_from, btVec_to, btResult); - if (btResult.hasHit()) { - B_TO_G(btResult.m_hitPointWorld, r_result.position); - B_TO_G(btResult.m_hitNormalWorld.normalize(), r_result.normal); - CollisionObjectBullet *gObj = static_cast<CollisionObjectBullet *>(btResult.m_collisionObject->getUserPointer()); - if (gObj) { - r_result.shape = btResult.m_shapeId; - r_result.rid = gObj->get_self(); - r_result.collider_id = gObj->get_instance_id(); - r_result.collider = r_result.collider_id.is_null() ? nullptr : ObjectDB::get_instance(r_result.collider_id); - } else { - WARN_PRINT("The raycast performed has hit a collision object that is not part of Godot scene, please check it."); - } - return true; - } else { - return false; - } -} - -int BulletPhysicsDirectSpaceState::intersect_shape(const RID &p_shape, const Transform3D &p_xform, real_t p_margin, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) { - if (p_result_max <= 0) { - return 0; - } - - ShapeBullet *shape = space->get_physics_server()->get_shape_owner()->get_or_null(p_shape); - ERR_FAIL_COND_V(!shape, 0); - - btCollisionShape *btShape = shape->create_bt_shape(p_xform.basis.get_scale_abs(), p_margin); - if (!btShape->isConvex()) { - bulletdelete(btShape); - ERR_PRINT("The shape is not a convex shape, then is not supported: shape type: " + itos(shape->get_type())); - return 0; - } - btConvexShape *btConvex = static_cast<btConvexShape *>(btShape); - - btTransform bt_xform; - G_TO_B(p_xform, bt_xform); - UNSCALE_BT_BASIS(bt_xform); - - btCollisionObject collision_object; - collision_object.setCollisionShape(btConvex); - collision_object.setWorldTransform(bt_xform); - - GodotAllContactResultCallback btQuery(&collision_object, r_results, p_result_max, &p_exclude, p_collide_with_bodies, p_collide_with_areas); - btQuery.m_collisionFilterGroup = 0; - btQuery.m_collisionFilterMask = p_collision_mask; - btQuery.m_closestDistanceThreshold = 0; - space->dynamicsWorld->contactTest(&collision_object, btQuery); - - bulletdelete(btConvex); - - return btQuery.m_count; -} - -bool BulletPhysicsDirectSpaceState::cast_motion(const RID &p_shape, const Transform3D &p_xform, const Vector3 &p_motion, real_t p_margin, real_t &r_closest_safe, real_t &r_closest_unsafe, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas, ShapeRestInfo *r_info) { - r_closest_safe = 0.0f; - r_closest_unsafe = 0.0f; - btVector3 bt_motion; - G_TO_B(p_motion, bt_motion); - - ShapeBullet *shape = space->get_physics_server()->get_shape_owner()->get_or_null(p_shape); - ERR_FAIL_COND_V(!shape, false); - - btCollisionShape *btShape = shape->create_bt_shape(p_xform.basis.get_scale(), p_margin); - if (!btShape->isConvex()) { - bulletdelete(btShape); - ERR_PRINT("The shape is not a convex shape, then is not supported: shape type: " + itos(shape->get_type())); - return false; - } - btConvexShape *bt_convex_shape = static_cast<btConvexShape *>(btShape); - - btTransform bt_xform_from; - G_TO_B(p_xform, bt_xform_from); - UNSCALE_BT_BASIS(bt_xform_from); - - btTransform bt_xform_to(bt_xform_from); - bt_xform_to.getOrigin() += bt_motion; - - if ((bt_xform_to.getOrigin() - bt_xform_from.getOrigin()).fuzzyZero()) { - r_closest_safe = 1.0f; - r_closest_unsafe = 1.0f; - bulletdelete(btShape); - return true; - } - - GodotClosestConvexResultCallback btResult(bt_xform_from.getOrigin(), bt_xform_to.getOrigin(), &p_exclude, p_collide_with_bodies, p_collide_with_areas); - btResult.m_collisionFilterGroup = 0; - btResult.m_collisionFilterMask = p_collision_mask; - - space->dynamicsWorld->convexSweepTest(bt_convex_shape, bt_xform_from, bt_xform_to, btResult, space->dynamicsWorld->getDispatchInfo().m_allowedCcdPenetration); - - if (btResult.hasHit()) { - const btScalar l = bt_motion.length(); - r_closest_unsafe = btResult.m_closestHitFraction; - r_closest_safe = MAX(r_closest_unsafe - (1 - ((l - 0.01) / l)), 0); - if (r_info) { - if (btCollisionObject::CO_RIGID_BODY == btResult.m_hitCollisionObject->getInternalType()) { - B_TO_G(static_cast<const btRigidBody *>(btResult.m_hitCollisionObject)->getVelocityInLocalPoint(btResult.m_hitPointWorld), r_info->linear_velocity); - } - CollisionObjectBullet *collision_object = static_cast<CollisionObjectBullet *>(btResult.m_hitCollisionObject->getUserPointer()); - B_TO_G(btResult.m_hitPointWorld, r_info->point); - B_TO_G(btResult.m_hitNormalWorld, r_info->normal); - r_info->rid = collision_object->get_self(); - r_info->collider_id = collision_object->get_instance_id(); - r_info->shape = btResult.m_shapeId; - } - } else { - r_closest_safe = 1.0f; - r_closest_unsafe = 1.0f; - } - - bulletdelete(bt_convex_shape); - return true; // Mean success -} - -/// Returns the list of contacts pairs in this order: Local contact, other body contact -bool BulletPhysicsDirectSpaceState::collide_shape(RID p_shape, const Transform3D &p_shape_xform, real_t p_margin, Vector3 *r_results, int p_result_max, int &r_result_count, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) { - if (p_result_max <= 0) { - return false; - } - - ShapeBullet *shape = space->get_physics_server()->get_shape_owner()->get_or_null(p_shape); - ERR_FAIL_COND_V(!shape, false); - - btCollisionShape *btShape = shape->create_bt_shape(p_shape_xform.basis.get_scale_abs(), p_margin); - if (!btShape->isConvex()) { - bulletdelete(btShape); - ERR_PRINT("The shape is not a convex shape, then is not supported: shape type: " + itos(shape->get_type())); - return false; - } - btConvexShape *btConvex = static_cast<btConvexShape *>(btShape); - - btTransform bt_xform; - G_TO_B(p_shape_xform, bt_xform); - UNSCALE_BT_BASIS(bt_xform); - - btCollisionObject collision_object; - collision_object.setCollisionShape(btConvex); - collision_object.setWorldTransform(bt_xform); - - GodotContactPairContactResultCallback btQuery(&collision_object, r_results, p_result_max, &p_exclude, p_collide_with_bodies, p_collide_with_areas); - btQuery.m_collisionFilterGroup = 0; - btQuery.m_collisionFilterMask = p_collision_mask; - btQuery.m_closestDistanceThreshold = 0; - space->dynamicsWorld->contactTest(&collision_object, btQuery); - - r_result_count = btQuery.m_count; - bulletdelete(btConvex); - - return btQuery.m_count; -} - -bool BulletPhysicsDirectSpaceState::rest_info(RID p_shape, const Transform3D &p_shape_xform, real_t p_margin, ShapeRestInfo *r_info, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) { - ShapeBullet *shape = space->get_physics_server()->get_shape_owner()->get_or_null(p_shape); - ERR_FAIL_COND_V(!shape, false); - - btCollisionShape *btShape = shape->create_bt_shape(p_shape_xform.basis.get_scale_abs(), p_margin); - if (!btShape->isConvex()) { - bulletdelete(btShape); - ERR_PRINT("The shape is not a convex shape, then is not supported: shape type: " + itos(shape->get_type())); - return false; - } - btConvexShape *btConvex = static_cast<btConvexShape *>(btShape); - - btTransform bt_xform; - G_TO_B(p_shape_xform, bt_xform); - UNSCALE_BT_BASIS(bt_xform); - - btCollisionObject collision_object; - collision_object.setCollisionShape(btConvex); - collision_object.setWorldTransform(bt_xform); - - GodotRestInfoContactResultCallback btQuery(&collision_object, r_info, &p_exclude, p_collide_with_bodies, p_collide_with_areas); - btQuery.m_collisionFilterGroup = 0; - btQuery.m_collisionFilterMask = p_collision_mask; - btQuery.m_closestDistanceThreshold = 0; - space->dynamicsWorld->contactTest(&collision_object, btQuery); - - bulletdelete(btConvex); - - if (btQuery.m_collided) { - if (btCollisionObject::CO_RIGID_BODY == btQuery.m_rest_info_collision_object->getInternalType()) { - B_TO_G(static_cast<const btRigidBody *>(btQuery.m_rest_info_collision_object)->getVelocityInLocalPoint(btQuery.m_rest_info_bt_point), r_info->linear_velocity); - } - B_TO_G(btQuery.m_rest_info_bt_point, r_info->point); - } - - return btQuery.m_collided; -} - -Vector3 BulletPhysicsDirectSpaceState::get_closest_point_to_object_volume(RID p_object, const Vector3 p_point) const { - RigidCollisionObjectBullet *rigid_object = space->get_physics_server()->get_rigid_collision_object(p_object); - ERR_FAIL_COND_V(!rigid_object, Vector3()); - - btVector3 out_closest_point(0, 0, 0); - btScalar out_distance = 1e20; - - btVector3 bt_point; - G_TO_B(p_point, bt_point); - - btSphereShape point_shape(0.); - - btCollisionShape *shape; - btConvexShape *convex_shape; - btTransform child_transform; - btTransform body_transform(rigid_object->get_bt_collision_object()->getWorldTransform()); - - btGjkPairDetector::ClosestPointInput input; - input.m_transformA.getBasis().setIdentity(); - input.m_transformA.setOrigin(bt_point); - - bool shapes_found = false; - - for (int i = rigid_object->get_shape_count() - 1; 0 <= i; --i) { - shape = rigid_object->get_bt_shape(i); - if (shape->isConvex()) { - child_transform = rigid_object->get_bt_shape_transform(i); - convex_shape = static_cast<btConvexShape *>(shape); - - input.m_transformB = body_transform * child_transform; - - btPointCollector result; - btGjkPairDetector gjk_pair_detector(&point_shape, convex_shape, space->gjk_simplex_solver, space->gjk_epa_pen_solver); - gjk_pair_detector.getClosestPoints(input, result, nullptr); - - if (out_distance > result.m_distance) { - out_distance = result.m_distance; - out_closest_point = result.m_pointInWorld; - } - } - shapes_found = true; - } - - if (shapes_found) { - Vector3 out; - B_TO_G(out_closest_point, out); - return out; - } else { - // no shapes found, use distance to origin. - return rigid_object->get_transform().get_origin(); - } -} - -SpaceBullet::SpaceBullet() { - create_empty_world(GLOBAL_DEF("physics/3d/active_soft_world", true)); - direct_access = memnew(BulletPhysicsDirectSpaceState(this)); -} - -SpaceBullet::~SpaceBullet() { - memdelete(direct_access); - destroy_world(); -} - -void SpaceBullet::flush_queries() { - const btCollisionObjectArray &colObjArray = dynamicsWorld->getCollisionObjectArray(); - for (int i = colObjArray.size() - 1; 0 <= i; --i) { - static_cast<CollisionObjectBullet *>(colObjArray[i]->getUserPointer())->dispatch_callbacks(); - } -} - -void SpaceBullet::step(real_t p_delta_time) { - delta_time = p_delta_time; - dynamicsWorld->stepSimulation(p_delta_time, 0, 0); -} - -void SpaceBullet::set_param(PhysicsServer3D::AreaParameter p_param, const Variant &p_value) { - assert(dynamicsWorld); - - switch (p_param) { - case PhysicsServer3D::AREA_PARAM_GRAVITY: - gravityMagnitude = p_value; - update_gravity(); - break; - case PhysicsServer3D::AREA_PARAM_GRAVITY_VECTOR: - gravityDirection = p_value; - update_gravity(); - break; - case PhysicsServer3D::AREA_PARAM_LINEAR_DAMP: - linear_damp = p_value; - break; - case PhysicsServer3D::AREA_PARAM_ANGULAR_DAMP: - angular_damp = p_value; - break; - case PhysicsServer3D::AREA_PARAM_PRIORITY: - // Priority is always 0, the lower - break; - case PhysicsServer3D::AREA_PARAM_GRAVITY_IS_POINT: - case PhysicsServer3D::AREA_PARAM_GRAVITY_DISTANCE_SCALE: - case PhysicsServer3D::AREA_PARAM_GRAVITY_POINT_ATTENUATION: - break; - default: - WARN_PRINT("This set parameter (" + itos(p_param) + ") is ignored, the SpaceBullet doesn't support it."); - break; - } -} - -Variant SpaceBullet::get_param(PhysicsServer3D::AreaParameter p_param) { - switch (p_param) { - case PhysicsServer3D::AREA_PARAM_GRAVITY: - return gravityMagnitude; - case PhysicsServer3D::AREA_PARAM_GRAVITY_VECTOR: - return gravityDirection; - case PhysicsServer3D::AREA_PARAM_LINEAR_DAMP: - return linear_damp; - case PhysicsServer3D::AREA_PARAM_ANGULAR_DAMP: - return angular_damp; - case PhysicsServer3D::AREA_PARAM_PRIORITY: - return 0; // Priority is always 0, the lower - case PhysicsServer3D::AREA_PARAM_GRAVITY_IS_POINT: - return false; - case PhysicsServer3D::AREA_PARAM_GRAVITY_DISTANCE_SCALE: - return 0; - case PhysicsServer3D::AREA_PARAM_GRAVITY_POINT_ATTENUATION: - return 0; - default: - WARN_PRINT("This get parameter (" + itos(p_param) + ") is ignored, the SpaceBullet doesn't support it."); - return Variant(); - } -} - -void SpaceBullet::set_param(PhysicsServer3D::SpaceParameter p_param, real_t p_value) { - switch (p_param) { - case PhysicsServer3D::SPACE_PARAM_CONTACT_RECYCLE_RADIUS: - case PhysicsServer3D::SPACE_PARAM_CONTACT_MAX_SEPARATION: - case PhysicsServer3D::SPACE_PARAM_BODY_MAX_ALLOWED_PENETRATION: - case PhysicsServer3D::SPACE_PARAM_BODY_LINEAR_VELOCITY_SLEEP_THRESHOLD: - case PhysicsServer3D::SPACE_PARAM_BODY_ANGULAR_VELOCITY_SLEEP_THRESHOLD: - case PhysicsServer3D::SPACE_PARAM_BODY_TIME_TO_SLEEP: - default: - WARN_PRINT("This set parameter (" + itos(p_param) + ") is ignored, the SpaceBullet doesn't support it."); - break; - } -} - -real_t SpaceBullet::get_param(PhysicsServer3D::SpaceParameter p_param) { - switch (p_param) { - case PhysicsServer3D::SPACE_PARAM_CONTACT_RECYCLE_RADIUS: - case PhysicsServer3D::SPACE_PARAM_CONTACT_MAX_SEPARATION: - case PhysicsServer3D::SPACE_PARAM_BODY_MAX_ALLOWED_PENETRATION: - case PhysicsServer3D::SPACE_PARAM_BODY_LINEAR_VELOCITY_SLEEP_THRESHOLD: - case PhysicsServer3D::SPACE_PARAM_BODY_ANGULAR_VELOCITY_SLEEP_THRESHOLD: - case PhysicsServer3D::SPACE_PARAM_BODY_TIME_TO_SLEEP: - default: - WARN_PRINT("The SpaceBullet doesn't support this get parameter (" + itos(p_param) + "), 0 is returned."); - return 0.f; - } -} - -void SpaceBullet::add_area(AreaBullet *p_area) { - areas.push_back(p_area); - dynamicsWorld->addCollisionObject(p_area->get_bt_ghost(), p_area->get_collision_layer(), p_area->get_collision_mask()); -} - -void SpaceBullet::remove_area(AreaBullet *p_area) { - areas.erase(p_area); - dynamicsWorld->removeCollisionObject(p_area->get_bt_ghost()); -} - -void SpaceBullet::reload_collision_filters(AreaBullet *p_area) { - btGhostObject *ghost_object = p_area->get_bt_ghost(); - - btBroadphaseProxy *ghost_proxy = ghost_object->getBroadphaseHandle(); - ghost_proxy->m_collisionFilterGroup = p_area->get_collision_layer(); - ghost_proxy->m_collisionFilterMask = p_area->get_collision_mask(); - - dynamicsWorld->refreshBroadphaseProxy(ghost_object); -} - -void SpaceBullet::add_rigid_body(RigidBodyBullet *p_body) { - if (p_body->is_static()) { - dynamicsWorld->addCollisionObject(p_body->get_bt_rigid_body(), p_body->get_collision_layer(), p_body->get_collision_mask()); - } else { - dynamicsWorld->addRigidBody(p_body->get_bt_rigid_body(), p_body->get_collision_layer(), p_body->get_collision_mask()); - p_body->scratch_space_override_modificator(); - } -} - -void SpaceBullet::remove_rigid_body_constraints(RigidBodyBullet *p_body) { - btRigidBody *btBody = p_body->get_bt_rigid_body(); - - int constraints = btBody->getNumConstraintRefs(); - if (constraints > 0) { - ERR_PRINT("A body connected to joints was removed."); - for (int i = 0; i < constraints; i++) { - dynamicsWorld->removeConstraint(btBody->getConstraintRef(i)); - } - } -} - -void SpaceBullet::remove_rigid_body(RigidBodyBullet *p_body) { - btRigidBody *btBody = p_body->get_bt_rigid_body(); - - if (p_body->is_static()) { - dynamicsWorld->removeCollisionObject(btBody); - } else { - dynamicsWorld->removeRigidBody(btBody); - } -} - -void SpaceBullet::reload_collision_filters(RigidBodyBullet *p_body) { - btRigidBody *rigid_body = p_body->get_bt_rigid_body(); - - btBroadphaseProxy *body_proxy = rigid_body->getBroadphaseProxy(); - body_proxy->m_collisionFilterGroup = p_body->get_collision_layer(); - body_proxy->m_collisionFilterMask = p_body->get_collision_mask(); - - dynamicsWorld->refreshBroadphaseProxy(rigid_body); -} - -void SpaceBullet::add_soft_body(SoftBodyBullet *p_body) { - if (is_using_soft_world()) { - if (p_body->get_bt_soft_body()) { - p_body->get_bt_soft_body()->m_worldInfo = get_soft_body_world_info(); - static_cast<btSoftRigidDynamicsWorld *>(dynamicsWorld)->addSoftBody(p_body->get_bt_soft_body(), p_body->get_collision_layer(), p_body->get_collision_mask()); - } - } else { - ERR_PRINT("This soft body can't be added to non soft world"); - } -} - -void SpaceBullet::remove_soft_body(SoftBodyBullet *p_body) { - if (is_using_soft_world()) { - if (p_body->get_bt_soft_body()) { - static_cast<btSoftRigidDynamicsWorld *>(dynamicsWorld)->removeSoftBody(p_body->get_bt_soft_body()); - p_body->get_bt_soft_body()->m_worldInfo = nullptr; - } - } -} - -void SpaceBullet::reload_collision_filters(SoftBodyBullet *p_body) { - // This is necessary to change collision filter - remove_soft_body(p_body); - add_soft_body(p_body); -} - -void SpaceBullet::add_constraint(ConstraintBullet *p_constraint, bool disableCollisionsBetweenLinkedBodies) { - p_constraint->set_space(this); - dynamicsWorld->addConstraint(p_constraint->get_bt_constraint(), disableCollisionsBetweenLinkedBodies); -} - -void SpaceBullet::remove_constraint(ConstraintBullet *p_constraint) { - dynamicsWorld->removeConstraint(p_constraint->get_bt_constraint()); -} - -int SpaceBullet::get_num_collision_objects() const { - return dynamicsWorld->getNumCollisionObjects(); -} - -void SpaceBullet::remove_all_collision_objects() { - for (int i = dynamicsWorld->getNumCollisionObjects() - 1; 0 <= i; --i) { - btCollisionObject *btObj = dynamicsWorld->getCollisionObjectArray()[i]; - CollisionObjectBullet *colObj = static_cast<CollisionObjectBullet *>(btObj->getUserPointer()); - colObj->set_space(nullptr); - } -} - -void onBulletTickCallback(btDynamicsWorld *p_dynamicsWorld, btScalar timeStep) { - const btCollisionObjectArray &colObjArray = p_dynamicsWorld->getCollisionObjectArray(); - - // Notify all Collision objects the collision checker is started - for (int i = colObjArray.size() - 1; 0 <= i; --i) { - static_cast<CollisionObjectBullet *>(colObjArray[i]->getUserPointer())->on_collision_checker_start(); - } - - SpaceBullet *sb = static_cast<SpaceBullet *>(p_dynamicsWorld->getWorldUserInfo()); - sb->check_ghost_overlaps(); - sb->check_body_collision(); - - for (int i = colObjArray.size() - 1; 0 <= i; --i) { - static_cast<CollisionObjectBullet *>(colObjArray[i]->getUserPointer())->on_collision_checker_end(); - } -} - -BulletPhysicsDirectSpaceState *SpaceBullet::get_direct_state() { - return direct_access; -} - -btScalar calculateGodotCombinedRestitution(const btCollisionObject *body0, const btCollisionObject *body1) { - return CLAMP(body0->getRestitution() + body1->getRestitution(), 0, 1); -} - -btScalar calculateGodotCombinedFriction(const btCollisionObject *body0, const btCollisionObject *body1) { - return ABS(MIN(body0->getFriction(), body1->getFriction())); -} - -void SpaceBullet::create_empty_world(bool p_create_soft_world) { - gjk_epa_pen_solver = bulletnew(btGjkEpaPenetrationDepthSolver); - gjk_simplex_solver = bulletnew(btVoronoiSimplexSolver); - - void *world_mem; - if (p_create_soft_world) { - world_mem = malloc(sizeof(btSoftRigidDynamicsWorld)); - } else { - world_mem = malloc(sizeof(btDiscreteDynamicsWorld)); - } - - ERR_FAIL_COND_MSG(!world_mem, "Out of memory."); - - if (p_create_soft_world) { - collisionConfiguration = bulletnew(GodotSoftCollisionConfiguration(static_cast<btDiscreteDynamicsWorld *>(world_mem))); - } else { - collisionConfiguration = bulletnew(GodotCollisionConfiguration(static_cast<btDiscreteDynamicsWorld *>(world_mem))); - } - - dispatcher = bulletnew(GodotCollisionDispatcher(collisionConfiguration)); - broadphase = bulletnew(btDbvtBroadphase); - solver = bulletnew(btSequentialImpulseConstraintSolver); - - if (p_create_soft_world) { - dynamicsWorld = new (world_mem) btSoftRigidDynamicsWorld(dispatcher, broadphase, solver, collisionConfiguration); - soft_body_world_info = bulletnew(btSoftBodyWorldInfo); - } else { - dynamicsWorld = new (world_mem) btDiscreteDynamicsWorld(dispatcher, broadphase, solver, collisionConfiguration); - } - - ghostPairCallback = bulletnew(btGhostPairCallback); - godotFilterCallback = bulletnew(GodotFilterCallback); - gCalculateCombinedRestitutionCallback = &calculateGodotCombinedRestitution; - gCalculateCombinedFrictionCallback = &calculateGodotCombinedFriction; - gContactAddedCallback = &godotContactAddedCallback; - - dynamicsWorld->setWorldUserInfo(this); - - dynamicsWorld->setInternalTickCallback(onBulletTickCallback, this, false); - dynamicsWorld->getBroadphase()->getOverlappingPairCache()->setInternalGhostPairCallback(ghostPairCallback); // Setup ghost check - dynamicsWorld->getPairCache()->setOverlapFilterCallback(godotFilterCallback); - - if (soft_body_world_info) { - soft_body_world_info->m_broadphase = broadphase; - soft_body_world_info->m_dispatcher = dispatcher; - soft_body_world_info->m_sparsesdf.Initialize(); - } - - update_gravity(); -} - -void SpaceBullet::destroy_world() { - /// The world elements (like: Collision Objects, Constraints, Shapes) are managed by godot - - dynamicsWorld->getBroadphase()->getOverlappingPairCache()->setInternalGhostPairCallback(nullptr); - dynamicsWorld->getPairCache()->setOverlapFilterCallback(nullptr); - - bulletdelete(ghostPairCallback); - bulletdelete(godotFilterCallback); - - // Deallocate world - dynamicsWorld->~btDiscreteDynamicsWorld(); - free(dynamicsWorld); - dynamicsWorld = nullptr; - - bulletdelete(solver); - bulletdelete(broadphase); - bulletdelete(dispatcher); - bulletdelete(collisionConfiguration); - bulletdelete(soft_body_world_info); - bulletdelete(gjk_simplex_solver); - bulletdelete(gjk_epa_pen_solver); -} - -void SpaceBullet::check_ghost_overlaps() { - // For each area - for (int area_idx = 0; area_idx < areas.size(); area_idx++) { - AreaBullet *area = areas[area_idx]; - if (!area->is_monitoring()) { - continue; - } - - btGhostObject *bt_ghost = area->get_bt_ghost(); - const btTransform &area_transform = area->get_transform__bullet(); - const btVector3 &area_scale(area->get_bt_body_scale()); - - // Mark all current overlapping shapes dirty. - area->mark_all_overlaps_dirty(); - - // Broadphase - const btAlignedObjectArray<btCollisionObject *> overlapping_pairs = bt_ghost->getOverlappingPairs(); - // Narrowphase - for (int pair_idx = 0; pair_idx < overlapping_pairs.size(); pair_idx++) { - btCollisionObject *other_bt_collision_object = overlapping_pairs[pair_idx]; - RigidCollisionObjectBullet *other_object = static_cast<RigidCollisionObjectBullet *>(other_bt_collision_object->getUserPointer()); - const btTransform &other_transform = other_object->get_transform__bullet(); - const btVector3 &other_scale(other_object->get_bt_body_scale()); - - if (!area->is_updated() && !other_object->is_updated()) { - area->mark_object_overlaps_inside(other_object); - continue; - } - - if (other_bt_collision_object->getUserIndex() == CollisionObjectBullet::TYPE_AREA) { - if (!static_cast<AreaBullet *>(other_bt_collision_object->getUserPointer())->is_monitorable()) { - continue; - } - } else if (other_bt_collision_object->getUserIndex() != CollisionObjectBullet::TYPE_RIGID_BODY) { - continue; - } - - // For each area shape - for (int our_shape_id = 0; our_shape_id < area->get_shape_count(); our_shape_id++) { - btCollisionShape *area_shape = area->get_bt_shape(our_shape_id); - if (!area_shape->isConvex()) { - continue; - } - btConvexShape *area_convex_shape = static_cast<btConvexShape *>(area_shape); - - btTransform area_shape_transform(area->get_bt_shape_transform(our_shape_id)); - area_shape_transform.getOrigin() *= area_scale; - btGjkPairDetector::ClosestPointInput gjk_input; - gjk_input.m_transformA = area_transform * area_shape_transform; - - // For each other object shape - for (int other_shape_id = 0; other_shape_id < other_object->get_shape_count(); other_shape_id++) { - btCollisionShape *other_shape = other_object->get_bt_shape(other_shape_id); - btTransform other_shape_transform(other_object->get_bt_shape_transform(other_shape_id)); - other_shape_transform.getOrigin() *= other_scale; - gjk_input.m_transformB = other_transform * other_shape_transform; - - if (other_shape->isConvex()) { - btPointCollector result; - btGjkPairDetector gjk_pair_detector( - area_convex_shape, - static_cast<btConvexShape *>(other_shape), - gjk_simplex_solver, - gjk_epa_pen_solver); - - gjk_pair_detector.getClosestPoints(gjk_input, result, nullptr); - if (result.m_distance <= 0) { - area->set_overlap(other_object, other_shape_id, our_shape_id); - } - } else { // Other shape is not convex. - btCollisionObjectWrapper obA(nullptr, area_convex_shape, bt_ghost, gjk_input.m_transformA, -1, our_shape_id); - btCollisionObjectWrapper obB(nullptr, other_shape, other_bt_collision_object, gjk_input.m_transformB, -1, other_shape_id); - btCollisionAlgorithm *algorithm = dispatcher->findAlgorithm(&obA, &obB, nullptr, BT_CONTACT_POINT_ALGORITHMS); - - if (!algorithm) { - continue; - } - - GodotDeepPenetrationContactResultCallback contactPointResult(&obA, &obB); - algorithm->processCollision(&obA, &obB, dynamicsWorld->getDispatchInfo(), &contactPointResult); - algorithm->~btCollisionAlgorithm(); - dispatcher->freeCollisionAlgorithm(algorithm); - - if (contactPointResult.hasHit()) { - area->set_overlap(other_object, our_shape_id, other_shape_id); - } - } - } // End for each other object shape - } // End for each area shape - } // End for each overlapping pair - - // All overlapping shapes still marked dirty must have exited. - area->mark_all_dirty_overlaps_as_exit(); - } // End for each area -} - -void SpaceBullet::check_body_collision() { -#ifdef DEBUG_ENABLED - reset_debug_contact_count(); -#endif - - const int numManifolds = dynamicsWorld->getDispatcher()->getNumManifolds(); - for (int i = 0; i < numManifolds; ++i) { - btPersistentManifold *contactManifold = dynamicsWorld->getDispatcher()->getManifoldByIndexInternal(i); - - // I know this static cast is a bit risky. But I'm checking its type just after it. - // This allow me to avoid a lot of other cast and checks - RigidBodyBullet *bodyA = static_cast<RigidBodyBullet *>(contactManifold->getBody0()->getUserPointer()); - RigidBodyBullet *bodyB = static_cast<RigidBodyBullet *>(contactManifold->getBody1()->getUserPointer()); - - if (CollisionObjectBullet::TYPE_RIGID_BODY == bodyA->getType() && CollisionObjectBullet::TYPE_RIGID_BODY == bodyB->getType()) { - if (!bodyA->can_add_collision() && !bodyB->can_add_collision()) { - continue; - } - - const int numContacts = contactManifold->getNumContacts(); - - /// Since I don't need report all contacts for these objects, - /// So report only the first -#define REPORT_ALL_CONTACTS 0 -#if REPORT_ALL_CONTACTS - for (int j = 0; j < numContacts; j++) { - btManifoldPoint &pt = contactManifold->getContactPoint(j); -#else - if (numContacts) { - btManifoldPoint &pt = contactManifold->getContactPoint(0); -#endif - if ( - pt.getDistance() < 0.0 || - bodyA->was_colliding(bodyB) || - bodyB->was_colliding(bodyA)) { - Vector3 collisionWorldPosition; - Vector3 collisionLocalPosition; - Vector3 normalOnB; - real_t appliedImpulse = pt.m_appliedImpulse; - B_TO_G(pt.m_normalWorldOnB, normalOnB); - - // The pt.m_index only contains the shape index when more than one collision shape is used - // and only if the collision shape is not a concave collision shape. - // A value of -1 in pt.m_partId indicates the pt.m_index is a shape index. - int shape_index_a = 0; - if (bodyA->get_shape_count() > 1 && pt.m_partId0 == -1) { - shape_index_a = pt.m_index0; - } - int shape_index_b = 0; - if (bodyB->get_shape_count() > 1 && pt.m_partId1 == -1) { - shape_index_b = pt.m_index1; - } - - if (bodyA->can_add_collision()) { - B_TO_G(pt.getPositionWorldOnB(), collisionWorldPosition); - /// pt.m_localPointB Doesn't report the exact point in local space - B_TO_G(pt.getPositionWorldOnB() - contactManifold->getBody1()->getWorldTransform().getOrigin(), collisionLocalPosition); - bodyA->add_collision_object(bodyB, collisionWorldPosition, collisionLocalPosition, normalOnB, appliedImpulse, shape_index_b, shape_index_a); - } - if (bodyB->can_add_collision()) { - B_TO_G(pt.getPositionWorldOnA(), collisionWorldPosition); - /// pt.m_localPointA Doesn't report the exact point in local space - B_TO_G(pt.getPositionWorldOnA() - contactManifold->getBody0()->getWorldTransform().getOrigin(), collisionLocalPosition); - bodyB->add_collision_object(bodyA, collisionWorldPosition, collisionLocalPosition, normalOnB * -1, appliedImpulse * -1, shape_index_a, shape_index_b); - } - -#ifdef DEBUG_ENABLED - if (is_debugging_contacts()) { - add_debug_contact(collisionWorldPosition); - } -#endif - } - } - } - } -} - -void SpaceBullet::update_gravity() { - btVector3 btGravity; - G_TO_B(gravityDirection * gravityMagnitude, btGravity); - //dynamicsWorld->setGravity(btGravity); - dynamicsWorld->setGravity(btVector3(0, 0, 0)); - if (soft_body_world_info) { - soft_body_world_info->m_gravity = btGravity; - } -} - -/// IMPORTANT: Please don't turn it ON this is not managed correctly!! -/// I'm leaving this here just for future tests. -/// Debug motion and normal vector drawing -#define debug_test_motion 0 - -#define RECOVERING_MOVEMENT_SCALE 0.4 -#define RECOVERING_MOVEMENT_CYCLES 4 - -#if debug_test_motion - -#include "scene/3d/immediate_geometry.h" - -static ImmediateGeometry3D *motionVec(nullptr); -static ImmediateGeometry3D *normalLine(nullptr); -static Ref<StandardMaterial3D> red_mat; -static Ref<StandardMaterial3D> blue_mat; -#endif - -bool SpaceBullet::test_body_motion(RigidBodyBullet *p_body, const Transform3D &p_from, const Vector3 &p_motion, bool p_infinite_inertia, PhysicsServer3D::MotionResult *r_result, bool p_exclude_raycast_shapes, const Set<RID> &p_exclude) { -#if debug_test_motion - /// Yes I know this is not good, but I've used it as fast debugging hack. - /// I'm leaving it here just for speedup the other eventual debugs - if (!normalLine) { - motionVec = memnew(ImmediateGeometry3D); - normalLine = memnew(ImmediateGeometry3D); - SceneTree::get_singleton()->get_current_scene()->add_child(motionVec); - SceneTree::get_singleton()->get_current_scene()->add_child(normalLine); - - motionVec->set_as_top_level(true); - normalLine->set_as_top_level(true); - - red_mat = Ref<StandardMaterial3D>(memnew(StandardMaterial3D)); - red_mat->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED); - red_mat->set_line_width(20.0); - red_mat->set_transparency(StandardMaterial3D::TRANSPARENCY_ALPHA); - red_mat->set_flag(StandardMaterial3D::FLAG_ALBEDO_FROM_VERTEX_COLOR, true); - red_mat->set_flag(StandardMaterial3D::FLAG_SRGB_VERTEX_COLOR, true); - red_mat->set_albedo(Color(1, 0, 0, 1)); - motionVec->set_material_override(red_mat); - - blue_mat = Ref<StandardMaterial3D>(memnew(StandardMaterial3D)); - blue_mat->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED); - blue_mat->set_line_width(20.0); - blue_mat->set_transparency(StandardMaterial3D::TRANSPARENCY_ALPHA); - blue_mat->set_flag(StandardMaterial3D::FLAG_ALBEDO_FROM_VERTEX_COLOR, true); - blue_mat->set_flag(StandardMaterial3D::FLAG_SRGB_VERTEX_COLOR, true); - blue_mat->set_albedo(Color(0, 0, 1, 1)); - normalLine->set_material_override(blue_mat); - } -#endif - - btTransform body_transform; - G_TO_B(p_from, body_transform); - UNSCALE_BT_BASIS(body_transform); - - if (!p_body->get_kinematic_utilities()) { - p_body->init_kinematic_utilities(); - } - - btVector3 initial_recover_motion(0, 0, 0); - { /// Phase one - multi shapes depenetration using margin - for (int t(RECOVERING_MOVEMENT_CYCLES); 0 < t; --t) { - if (!recover_from_penetration(p_body, body_transform, RECOVERING_MOVEMENT_SCALE, p_infinite_inertia, initial_recover_motion, nullptr, p_exclude)) { - break; - } - } - // Add recover movement in order to make it safe - body_transform.getOrigin() += initial_recover_motion; - } - - btVector3 motion; - G_TO_B(p_motion, motion); - real_t total_length = motion.length(); - real_t unsafe_fraction = 1.0; - real_t safe_fraction = 1.0; - { - // Phase two - sweep test, from a secure position without margin - - const int shape_count(p_body->get_shape_count()); - -#if debug_test_motion - Vector3 sup_line; - B_TO_G(body_safe_position.getOrigin(), sup_line); - motionVec->clear(); - motionVec->begin(Mesh::PRIMITIVE_LINES, nullptr); - motionVec->add_vertex(sup_line); - motionVec->add_vertex(sup_line + p_motion * 10); - motionVec->end(); -#endif - - for (int shIndex = 0; shIndex < shape_count; ++shIndex) { - if (p_body->is_shape_disabled(shIndex)) { - continue; - } - - if (!p_body->get_bt_shape(shIndex)->isConvex()) { - // Skip no convex shape - continue; - } - - if (p_exclude_raycast_shapes && p_body->get_bt_shape(shIndex)->getShapeType() == CUSTOM_CONVEX_SHAPE_TYPE) { - // Skip rayshape in order to implement custom separation process - continue; - } - - btConvexShape *convex_shape_test(static_cast<btConvexShape *>(p_body->get_bt_shape(shIndex))); - - btTransform shape_world_from = body_transform * p_body->get_kinematic_utilities()->shapes[shIndex].transform; - - btTransform shape_world_to(shape_world_from); - shape_world_to.getOrigin() += motion; - - if ((shape_world_to.getOrigin() - shape_world_from.getOrigin()).fuzzyZero()) { - motion = btVector3(0, 0, 0); - break; - } - - GodotKinClosestConvexResultCallback btResult(shape_world_from.getOrigin(), shape_world_to.getOrigin(), p_body, p_infinite_inertia, &p_exclude); - btResult.m_collisionFilterGroup = p_body->get_collision_layer(); - btResult.m_collisionFilterMask = p_body->get_collision_mask(); - - dynamicsWorld->convexSweepTest(convex_shape_test, shape_world_from, shape_world_to, btResult, dynamicsWorld->getDispatchInfo().m_allowedCcdPenetration); - - if (btResult.hasHit()) { - if (total_length > CMP_EPSILON) { - real_t hit_fraction = btResult.m_closestHitFraction * motion.length() / total_length; - if (hit_fraction < unsafe_fraction) { - unsafe_fraction = hit_fraction; - real_t margin = p_body->get_kinematic_utilities()->safe_margin; - safe_fraction = MAX(hit_fraction - (1 - ((total_length - margin) / total_length)), 0); - } - } - - /// Since for each sweep test I fix the motion of new shapes in base the recover result, - /// if another shape will hit something it means that has a deepest penetration respect the previous shape - motion *= btResult.m_closestHitFraction; - } - } - - body_transform.getOrigin() += motion; - } - - bool has_penetration = false; - - { /// Phase three - contact test with margin - - btVector3 __rec(0, 0, 0); - RecoverResult r_recover_result; - - has_penetration = recover_from_penetration(p_body, body_transform, 1, p_infinite_inertia, __rec, &r_recover_result, p_exclude); - - // Parse results - if (r_result) { - B_TO_G(motion + initial_recover_motion + __rec, r_result->motion); - - if (has_penetration) { - const btRigidBody *btRigid = static_cast<const btRigidBody *>(r_recover_result.other_collision_object); - CollisionObjectBullet *collisionObject = static_cast<CollisionObjectBullet *>(btRigid->getUserPointer()); - - B_TO_G(motion, r_result->remainder); // is the remaining movements - r_result->remainder = p_motion - r_result->remainder; - - B_TO_G(r_recover_result.pointWorld, r_result->collision_point); - B_TO_G(r_recover_result.normal, r_result->collision_normal); - B_TO_G(btRigid->getVelocityInLocalPoint(r_recover_result.pointWorld - btRigid->getWorldTransform().getOrigin()), r_result->collider_velocity); // It calculates velocity at point and assign it using special function Bullet_to_Godot - r_result->collider = collisionObject->get_self(); - r_result->collider_id = collisionObject->get_instance_id(); - r_result->collider_shape = r_recover_result.other_compound_shape_index; - r_result->collision_local_shape = r_recover_result.local_shape_most_recovered; - r_result->collision_depth = Math::abs(r_recover_result.penetration_distance); - r_result->collision_safe_fraction = safe_fraction; - r_result->collision_unsafe_fraction = unsafe_fraction; - -#if debug_test_motion - Vector3 sup_line2; - B_TO_G(motion, sup_line2); - normalLine->clear(); - normalLine->begin(Mesh::PRIMITIVE_LINES, nullptr); - normalLine->add_vertex(r_result->collision_point); - normalLine->add_vertex(r_result->collision_point + r_result->collision_normal * 10); - normalLine->end(); -#endif - } else { - r_result->remainder = Vector3(); - } - } - } - - return has_penetration; -} - -int SpaceBullet::test_ray_separation(RigidBodyBullet *p_body, const Transform3D &p_transform, bool p_infinite_inertia, Vector3 &r_recover_motion, PhysicsServer3D::SeparationResult *r_results, int p_result_max, real_t p_margin) { - btTransform body_transform; - G_TO_B(p_transform, body_transform); - UNSCALE_BT_BASIS(body_transform); - - if (!p_body->get_kinematic_utilities()) { - p_body->init_kinematic_utilities(); - } - - btVector3 recover_motion(0, 0, 0); - - int rays_found = 0; - int rays_found_this_round = 0; - - for (int t(RECOVERING_MOVEMENT_CYCLES); 0 < t; --t) { - PhysicsServer3D::SeparationResult *next_results = &r_results[rays_found]; - rays_found_this_round = recover_from_penetration_ray(p_body, body_transform, RECOVERING_MOVEMENT_SCALE, p_infinite_inertia, p_result_max - rays_found, recover_motion, next_results); - - rays_found += rays_found_this_round; - if (rays_found_this_round == 0) { - body_transform.getOrigin() += recover_motion; - break; - } - } - - B_TO_G(recover_motion, r_recover_motion); - return rays_found; -} - -struct RecoverPenetrationBroadPhaseCallback : public btBroadphaseAabbCallback { -private: - btDbvtVolume bounds; - - const btCollisionObject *self_collision_object; - uint32_t collision_layer = 0; - - struct CompoundLeafCallback : btDbvt::ICollide { - private: - RecoverPenetrationBroadPhaseCallback *parent_callback = nullptr; - btCollisionObject *collision_object = nullptr; - - public: - CompoundLeafCallback(RecoverPenetrationBroadPhaseCallback *p_parent_callback, btCollisionObject *p_collision_object) : - parent_callback(p_parent_callback), - collision_object(p_collision_object) { - } - - void Process(const btDbvtNode *leaf) { - BroadphaseResult result; - result.collision_object = collision_object; - result.compound_child_index = leaf->dataAsInt; - parent_callback->results.push_back(result); - } - }; - -public: - struct BroadphaseResult { - btCollisionObject *collision_object = nullptr; - int compound_child_index = 0; - }; - - Vector<BroadphaseResult> results; - -public: - RecoverPenetrationBroadPhaseCallback(const btCollisionObject *p_self_collision_object, uint32_t p_collision_layer, btVector3 p_aabb_min, btVector3 p_aabb_max) : - self_collision_object(p_self_collision_object), - collision_layer(p_collision_layer) { - bounds = btDbvtVolume::FromMM(p_aabb_min, p_aabb_max); - } - - virtual ~RecoverPenetrationBroadPhaseCallback() {} - - virtual bool process(const btBroadphaseProxy *proxy) { - btCollisionObject *co = static_cast<btCollisionObject *>(proxy->m_clientObject); - if (co->getInternalType() <= btCollisionObject::CO_RIGID_BODY) { - if (self_collision_object != proxy->m_clientObject && (proxy->collision_layer & m_collisionFilterMask)) { - if (co->getCollisionShape()->isCompound()) { - const btCompoundShape *cs = static_cast<btCompoundShape *>(co->getCollisionShape()); - - if (cs->getNumChildShapes() > 1) { - const btDbvt *tree = cs->getDynamicAabbTree(); - ERR_FAIL_COND_V(tree == nullptr, true); - - // Transform bounds into compound shape local space - const btTransform other_in_compound_space = co->getWorldTransform().inverse(); - const btMatrix3x3 abs_b = other_in_compound_space.getBasis().absolute(); - const btVector3 local_center = other_in_compound_space(bounds.Center()); - const btVector3 local_extent = bounds.Extents().dot3(abs_b[0], abs_b[1], abs_b[2]); - const btVector3 local_aabb_min = local_center - local_extent; - const btVector3 local_aabb_max = local_center + local_extent; - const btDbvtVolume local_bounds = btDbvtVolume::FromMM(local_aabb_min, local_aabb_max); - - // Test collision against compound child shapes using its AABB tree - CompoundLeafCallback compound_leaf_callback(this, co); - tree->collideTV(tree->m_root, local_bounds, compound_leaf_callback); - } else { - // If there's only a single child shape then there's no need to search any more, we know which child overlaps - BroadphaseResult result; - result.collision_object = co; - result.compound_child_index = 0; - results.push_back(result); - } - } else { - BroadphaseResult result; - result.collision_object = co; - result.compound_child_index = -1; - results.push_back(result); - } - return true; - } - } - return false; - } -}; - -bool SpaceBullet::recover_from_penetration(RigidBodyBullet *p_body, const btTransform &p_body_position, btScalar p_recover_movement_scale, bool p_infinite_inertia, btVector3 &r_delta_recover_movement, RecoverResult *r_recover_result, const Set<RID> &p_exclude) { - // Calculate the cumulative AABB of all shapes of the kinematic body - btVector3 aabb_min, aabb_max; - bool shapes_found = false; - - for (int kinIndex = p_body->get_kinematic_utilities()->shapes.size() - 1; 0 <= kinIndex; --kinIndex) { - const RigidBodyBullet::KinematicShape &kin_shape(p_body->get_kinematic_utilities()->shapes[kinIndex]); - if (!kin_shape.is_active()) { - continue; - } - - if (kin_shape.shape->getShapeType() == CUSTOM_CONVEX_SHAPE_TYPE) { - // Skip rayshape in order to implement custom separation process - continue; - } - - btTransform shape_transform = p_body_position * kin_shape.transform; - shape_transform.getOrigin() += r_delta_recover_movement; - - btVector3 shape_aabb_min, shape_aabb_max; - kin_shape.shape->getAabb(shape_transform, shape_aabb_min, shape_aabb_max); - - if (!shapes_found) { - aabb_min = shape_aabb_min; - aabb_max = shape_aabb_max; - shapes_found = true; - } else { - aabb_min.setX((aabb_min.x() < shape_aabb_min.x()) ? aabb_min.x() : shape_aabb_min.x()); - aabb_min.setY((aabb_min.y() < shape_aabb_min.y()) ? aabb_min.y() : shape_aabb_min.y()); - aabb_min.setZ((aabb_min.z() < shape_aabb_min.z()) ? aabb_min.z() : shape_aabb_min.z()); - - aabb_max.setX((aabb_max.x() > shape_aabb_max.x()) ? aabb_max.x() : shape_aabb_max.x()); - aabb_max.setY((aabb_max.y() > shape_aabb_max.y()) ? aabb_max.y() : shape_aabb_max.y()); - aabb_max.setZ((aabb_max.z() > shape_aabb_max.z()) ? aabb_max.z() : shape_aabb_max.z()); - } - } - - // If there are no shapes then there is no penetration either - if (!shapes_found) { - return false; - } - - // Perform broadphase test - RecoverPenetrationBroadPhaseCallback recover_broad_result(p_body->get_bt_collision_object(), p_body->get_collision_layer(), aabb_min, aabb_max); - dynamicsWorld->getBroadphase()->aabbTest(aabb_min, aabb_max, recover_broad_result); - - bool penetration = false; - - // Perform narrowphase per shape - for (int kinIndex = p_body->get_kinematic_utilities()->shapes.size() - 1; 0 <= kinIndex; --kinIndex) { - const RigidBodyBullet::KinematicShape &kin_shape(p_body->get_kinematic_utilities()->shapes[kinIndex]); - if (!kin_shape.is_active()) { - continue; - } - - if (kin_shape.shape->getShapeType() == CUSTOM_CONVEX_SHAPE_TYPE) { - // Skip rayshape in order to implement custom separation process - continue; - } - - if (kin_shape.shape->getShapeType() == EMPTY_SHAPE_PROXYTYPE) { - continue; - } - - btTransform shape_transform = p_body_position * kin_shape.transform; - shape_transform.getOrigin() += r_delta_recover_movement; - - for (int i = recover_broad_result.results.size() - 1; 0 <= i; --i) { - btCollisionObject *otherObject = recover_broad_result.results[i].collision_object; - - CollisionObjectBullet *gObj = static_cast<CollisionObjectBullet *>(otherObject->getUserPointer()); - if (p_exclude.has(gObj->get_self())) { - continue; - } - - if (p_infinite_inertia && !otherObject->isStaticOrKinematicObject()) { - otherObject->activate(); // Force activation of hitten rigid, soft body - continue; - } else if (!p_body->get_bt_collision_object()->checkCollideWith(otherObject) || !otherObject->checkCollideWith(p_body->get_bt_collision_object())) { - continue; - } - - if (otherObject->getCollisionShape()->isCompound()) { - const btCompoundShape *cs = static_cast<const btCompoundShape *>(otherObject->getCollisionShape()); - int shape_idx = recover_broad_result.results[i].compound_child_index; - ERR_FAIL_COND_V(shape_idx < 0 || shape_idx >= cs->getNumChildShapes(), false); - - if (cs->getChildShape(shape_idx)->isConvex()) { - if (RFP_convex_convex_test(kin_shape.shape, static_cast<const btConvexShape *>(cs->getChildShape(shape_idx)), otherObject, kinIndex, shape_idx, shape_transform, otherObject->getWorldTransform() * cs->getChildTransform(shape_idx), p_recover_movement_scale, r_delta_recover_movement, r_recover_result)) { - penetration = true; - } - } else { - if (RFP_convex_world_test(kin_shape.shape, cs->getChildShape(shape_idx), p_body->get_bt_collision_object(), otherObject, kinIndex, shape_idx, shape_transform, otherObject->getWorldTransform() * cs->getChildTransform(shape_idx), p_recover_movement_scale, r_delta_recover_movement, r_recover_result)) { - penetration = true; - } - } - } else if (otherObject->getCollisionShape()->isConvex()) { /// Execute GJK test against object shape - if (RFP_convex_convex_test(kin_shape.shape, static_cast<const btConvexShape *>(otherObject->getCollisionShape()), otherObject, kinIndex, 0, shape_transform, otherObject->getWorldTransform(), p_recover_movement_scale, r_delta_recover_movement, r_recover_result)) { - penetration = true; - } - } else { - if (RFP_convex_world_test(kin_shape.shape, otherObject->getCollisionShape(), p_body->get_bt_collision_object(), otherObject, kinIndex, 0, shape_transform, otherObject->getWorldTransform(), p_recover_movement_scale, r_delta_recover_movement, r_recover_result)) { - penetration = true; - } - } - } - } - - return penetration; -} - -bool SpaceBullet::RFP_convex_convex_test(const btConvexShape *p_shapeA, const btConvexShape *p_shapeB, btCollisionObject *p_objectB, int p_shapeId_A, int p_shapeId_B, const btTransform &p_transformA, const btTransform &p_transformB, btScalar p_recover_movement_scale, btVector3 &r_delta_recover_movement, RecoverResult *r_recover_result) { - // Initialize GJK input - btGjkPairDetector::ClosestPointInput gjk_input; - gjk_input.m_transformA = p_transformA; - gjk_input.m_transformB = p_transformB; - - // Perform GJK test - btPointCollector result; - btGjkPairDetector gjk_pair_detector(p_shapeA, p_shapeB, gjk_simplex_solver, gjk_epa_pen_solver); - gjk_pair_detector.getClosestPoints(gjk_input, result, nullptr); - if (0 > result.m_distance) { - // Has penetration - r_delta_recover_movement += result.m_normalOnBInWorld * (result.m_distance * -1 * p_recover_movement_scale); - - if (r_recover_result) { - if (result.m_distance < r_recover_result->penetration_distance) { - r_recover_result->hasPenetration = true; - r_recover_result->local_shape_most_recovered = p_shapeId_A; - r_recover_result->other_collision_object = p_objectB; - r_recover_result->other_compound_shape_index = p_shapeId_B; - r_recover_result->penetration_distance = result.m_distance; - r_recover_result->pointWorld = result.m_pointInWorld; - r_recover_result->normal = result.m_normalOnBInWorld; - } - } - return true; - } - return false; -} - -bool SpaceBullet::RFP_convex_world_test(const btConvexShape *p_shapeA, const btCollisionShape *p_shapeB, btCollisionObject *p_objectA, btCollisionObject *p_objectB, int p_shapeId_A, int p_shapeId_B, const btTransform &p_transformA, const btTransform &p_transformB, btScalar p_recover_movement_scale, btVector3 &r_delta_recover_movement, RecoverResult *r_recover_result) { - /// Contact test - - btTransform tA(p_transformA); - - btCollisionObjectWrapper obA(nullptr, p_shapeA, p_objectA, tA, -1, p_shapeId_A); - btCollisionObjectWrapper obB(nullptr, p_shapeB, p_objectB, p_transformB, -1, p_shapeId_B); - - btCollisionAlgorithm *algorithm = dispatcher->findAlgorithm(&obA, &obB, nullptr, BT_CONTACT_POINT_ALGORITHMS); - if (algorithm) { - GodotDeepPenetrationContactResultCallback contactPointResult(&obA, &obB); - //discrete collision detection query - algorithm->processCollision(&obA, &obB, dynamicsWorld->getDispatchInfo(), &contactPointResult); - - algorithm->~btCollisionAlgorithm(); - dispatcher->freeCollisionAlgorithm(algorithm); - - if (contactPointResult.hasHit()) { - r_delta_recover_movement += contactPointResult.m_pointNormalWorld * (contactPointResult.m_penetration_distance * -1 * p_recover_movement_scale); - if (r_recover_result) { - if (contactPointResult.m_penetration_distance < r_recover_result->penetration_distance) { - r_recover_result->hasPenetration = true; - r_recover_result->local_shape_most_recovered = p_shapeId_A; - r_recover_result->other_collision_object = p_objectB; - r_recover_result->other_compound_shape_index = p_shapeId_B; - r_recover_result->penetration_distance = contactPointResult.m_penetration_distance; - r_recover_result->pointWorld = contactPointResult.m_pointWorld; - r_recover_result->normal = contactPointResult.m_pointNormalWorld; - } - } - return true; - } - } - return false; -} - -int SpaceBullet::add_separation_result(PhysicsServer3D::SeparationResult *r_result, const SpaceBullet::RecoverResult &p_recover_result, int p_shape_id, const btCollisionObject *p_other_object) const { - // optimize results (ignore non-colliding) - if (p_recover_result.penetration_distance < 0.0) { - const btRigidBody *btRigid = static_cast<const btRigidBody *>(p_other_object); - CollisionObjectBullet *collisionObject = static_cast<CollisionObjectBullet *>(p_other_object->getUserPointer()); - - r_result->collision_depth = p_recover_result.penetration_distance; - B_TO_G(p_recover_result.pointWorld, r_result->collision_point); - B_TO_G(p_recover_result.normal, r_result->collision_normal); - B_TO_G(btRigid->getVelocityInLocalPoint(p_recover_result.pointWorld - btRigid->getWorldTransform().getOrigin()), r_result->collider_velocity); - r_result->collision_local_shape = p_shape_id; - r_result->collider_id = collisionObject->get_instance_id(); - r_result->collider = collisionObject->get_self(); - r_result->collider_shape = p_recover_result.other_compound_shape_index; - - return 1; - } else { - return 0; - } -} - -int SpaceBullet::recover_from_penetration_ray(RigidBodyBullet *p_body, const btTransform &p_body_position, btScalar p_recover_movement_scale, bool p_infinite_inertia, int p_result_max, btVector3 &r_delta_recover_movement, PhysicsServer3D::SeparationResult *r_results) { - // Calculate the cumulative AABB of all shapes of the kinematic body - btVector3 aabb_min, aabb_max; - bool shapes_found = false; - - for (int kinIndex = p_body->get_kinematic_utilities()->shapes.size() - 1; 0 <= kinIndex; --kinIndex) { - const RigidBodyBullet::KinematicShape &kin_shape(p_body->get_kinematic_utilities()->shapes[kinIndex]); - if (!kin_shape.is_active()) { - continue; - } - - if (kin_shape.shape->getShapeType() != CUSTOM_CONVEX_SHAPE_TYPE) { - continue; - } - - btTransform shape_transform = p_body_position * kin_shape.transform; - shape_transform.getOrigin() += r_delta_recover_movement; - - btVector3 shape_aabb_min, shape_aabb_max; - kin_shape.shape->getAabb(shape_transform, shape_aabb_min, shape_aabb_max); - - if (!shapes_found) { - aabb_min = shape_aabb_min; - aabb_max = shape_aabb_max; - shapes_found = true; - } else { - aabb_min.setX((aabb_min.x() < shape_aabb_min.x()) ? aabb_min.x() : shape_aabb_min.x()); - aabb_min.setY((aabb_min.y() < shape_aabb_min.y()) ? aabb_min.y() : shape_aabb_min.y()); - aabb_min.setZ((aabb_min.z() < shape_aabb_min.z()) ? aabb_min.z() : shape_aabb_min.z()); - - aabb_max.setX((aabb_max.x() > shape_aabb_max.x()) ? aabb_max.x() : shape_aabb_max.x()); - aabb_max.setY((aabb_max.y() > shape_aabb_max.y()) ? aabb_max.y() : shape_aabb_max.y()); - aabb_max.setZ((aabb_max.z() > shape_aabb_max.z()) ? aabb_max.z() : shape_aabb_max.z()); - } - } - - // If there are no shapes then there is no penetration either - if (!shapes_found) { - return 0; - } - - // Perform broadphase test - RecoverPenetrationBroadPhaseCallback recover_broad_result(p_body->get_bt_collision_object(), p_body->get_collision_layer(), aabb_min, aabb_max); - dynamicsWorld->getBroadphase()->aabbTest(aabb_min, aabb_max, recover_broad_result); - - int ray_count = 0; - - // Perform narrowphase per shape - for (int kinIndex = p_body->get_kinematic_utilities()->shapes.size() - 1; 0 <= kinIndex; --kinIndex) { - if (ray_count >= p_result_max) { - break; - } - - const RigidBodyBullet::KinematicShape &kin_shape(p_body->get_kinematic_utilities()->shapes[kinIndex]); - if (!kin_shape.is_active()) { - continue; - } - - if (kin_shape.shape->getShapeType() != CUSTOM_CONVEX_SHAPE_TYPE) { - continue; - } - - btTransform shape_transform = p_body_position * kin_shape.transform; - shape_transform.getOrigin() += r_delta_recover_movement; - - for (int i = recover_broad_result.results.size() - 1; 0 <= i; --i) { - btCollisionObject *otherObject = recover_broad_result.results[i].collision_object; - if (p_infinite_inertia && !otherObject->isStaticOrKinematicObject()) { - otherObject->activate(); // Force activation of hitten rigid, soft body - continue; - } else if (!p_body->get_bt_collision_object()->checkCollideWith(otherObject) || !otherObject->checkCollideWith(p_body->get_bt_collision_object())) { - continue; - } - - if (otherObject->getCollisionShape()->isCompound()) { - const btCompoundShape *cs = static_cast<const btCompoundShape *>(otherObject->getCollisionShape()); - int shape_idx = recover_broad_result.results[i].compound_child_index; - ERR_FAIL_COND_V(shape_idx < 0 || shape_idx >= cs->getNumChildShapes(), false); - - RecoverResult recover_result; - if (RFP_convex_world_test(kin_shape.shape, cs->getChildShape(shape_idx), p_body->get_bt_collision_object(), otherObject, kinIndex, shape_idx, shape_transform, otherObject->getWorldTransform() * cs->getChildTransform(shape_idx), p_recover_movement_scale, r_delta_recover_movement, &recover_result)) { - ray_count = add_separation_result(&r_results[ray_count], recover_result, kinIndex, otherObject); - } - } else { - RecoverResult recover_result; - if (RFP_convex_world_test(kin_shape.shape, otherObject->getCollisionShape(), p_body->get_bt_collision_object(), otherObject, kinIndex, 0, shape_transform, otherObject->getWorldTransform(), p_recover_movement_scale, r_delta_recover_movement, &recover_result)) { - ray_count = add_separation_result(&r_results[ray_count], recover_result, kinIndex, otherObject); - } - } - } - } - - return ray_count; -} diff --git a/modules/bullet/space_bullet.h b/modules/bullet/space_bullet.h deleted file mode 100644 index f858c5fcb5..0000000000 --- a/modules/bullet/space_bullet.h +++ /dev/null @@ -1,220 +0,0 @@ -/*************************************************************************/ -/* space_bullet.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* 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. */ -/*************************************************************************/ - -#ifndef SPACE_BULLET_H -#define SPACE_BULLET_H - -#include "core/templates/vector.h" -#include "core/variant/variant.h" -#include "godot_result_callbacks.h" -#include "rid_bullet.h" -#include "servers/physics_server_3d.h" - -#include <BulletCollision/BroadphaseCollision/btBroadphaseProxy.h> -#include <BulletCollision/BroadphaseCollision/btOverlappingPairCache.h> -#include <LinearMath/btScalar.h> -#include <LinearMath/btTransform.h> -#include <LinearMath/btVector3.h> - -class AreaBullet; -class btBroadphaseInterface; -class btCollisionDispatcher; -class btConstraintSolver; -class btDefaultCollisionConfiguration; -class btDynamicsWorld; -class btDiscreteDynamicsWorld; -class btEmptyShape; -class btGhostPairCallback; -class btSoftRigidDynamicsWorld; -struct btSoftBodyWorldInfo; -class ConstraintBullet; -class CollisionObjectBullet; -class RigidBodyBullet; -class SpaceBullet; -class SoftBodyBullet; -class btGjkEpaPenetrationDepthSolver; - -extern ContactAddedCallback gContactAddedCallback; - -class BulletPhysicsDirectSpaceState : public PhysicsDirectSpaceState3D { - GDCLASS(BulletPhysicsDirectSpaceState, PhysicsDirectSpaceState3D); - -private: - SpaceBullet *space; - -public: - BulletPhysicsDirectSpaceState(SpaceBullet *p_space); - - virtual int intersect_point(const Vector3 &p_point, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = UINT32_MAX, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) override; - virtual bool intersect_ray(const Vector3 &p_from, const Vector3 &p_to, RayResult &r_result, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = UINT32_MAX, bool p_collide_with_bodies = true, bool p_collide_with_areas = false, bool p_pick_ray = false) override; - virtual int intersect_shape(const RID &p_shape, const Transform3D &p_xform, real_t p_margin, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = UINT32_MAX, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) override; - virtual bool cast_motion(const RID &p_shape, const Transform3D &p_xform, const Vector3 &p_motion, real_t p_margin, real_t &r_closest_safe, real_t &r_closest_unsafe, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = UINT32_MAX, bool p_collide_with_bodies = true, bool p_collide_with_areas = false, ShapeRestInfo *r_info = nullptr) override; - /// Returns the list of contacts pairs in this order: Local contact, other body contact - virtual bool collide_shape(RID p_shape, const Transform3D &p_shape_xform, real_t p_margin, Vector3 *r_results, int p_result_max, int &r_result_count, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = UINT32_MAX, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) override; - virtual bool rest_info(RID p_shape, const Transform3D &p_shape_xform, real_t p_margin, ShapeRestInfo *r_info, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = UINT32_MAX, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) override; - virtual Vector3 get_closest_point_to_object_volume(RID p_object, const Vector3 p_point) const override; -}; - -class SpaceBullet : public RIDBullet { - friend class AreaBullet; - friend void onBulletTickCallback(btDynamicsWorld *world, btScalar timeStep); - friend class BulletPhysicsDirectSpaceState; - - btBroadphaseInterface *broadphase = nullptr; - btDefaultCollisionConfiguration *collisionConfiguration = nullptr; - btCollisionDispatcher *dispatcher = nullptr; - btConstraintSolver *solver = nullptr; - btDiscreteDynamicsWorld *dynamicsWorld = nullptr; - btSoftBodyWorldInfo *soft_body_world_info = nullptr; - btGhostPairCallback *ghostPairCallback = nullptr; - GodotFilterCallback *godotFilterCallback = nullptr; - - btGjkEpaPenetrationDepthSolver *gjk_epa_pen_solver = nullptr; - btVoronoiSimplexSolver *gjk_simplex_solver = nullptr; - - BulletPhysicsDirectSpaceState *direct_access; - Vector3 gravityDirection = Vector3(0, -1, 0); - real_t gravityMagnitude = 10.0; - - real_t linear_damp = 0.0; - real_t angular_damp = 0.0; - - Vector<AreaBullet *> areas; - - Vector<Vector3> contactDebug; - int contactDebugCount = 0; - real_t delta_time = 0.; - -public: - SpaceBullet(); - virtual ~SpaceBullet(); - - void flush_queries(); - real_t get_delta_time() { return delta_time; } - void step(real_t p_delta_time); - - _FORCE_INLINE_ btBroadphaseInterface *get_broadphase() const { return broadphase; } - _FORCE_INLINE_ btDefaultCollisionConfiguration *get_collision_configuration() const { return collisionConfiguration; } - _FORCE_INLINE_ btCollisionDispatcher *get_dispatcher() const { return dispatcher; } - _FORCE_INLINE_ btConstraintSolver *get_solver() const { return solver; } - _FORCE_INLINE_ btDiscreteDynamicsWorld *get_dynamic_world() const { return dynamicsWorld; } - _FORCE_INLINE_ btSoftBodyWorldInfo *get_soft_body_world_info() const { return soft_body_world_info; } - _FORCE_INLINE_ bool is_using_soft_world() { return soft_body_world_info; } - - /// Used to set some parameters to Bullet world - /// @param p_param: - /// AREA_PARAM_GRAVITY to set the gravity magnitude of entire world - /// AREA_PARAM_GRAVITY_VECTOR to set the gravity direction of entire world - void set_param(PhysicsServer3D::AreaParameter p_param, const Variant &p_value); - /// Used to get some parameters to Bullet world - /// @param p_param: - /// AREA_PARAM_GRAVITY to get the gravity magnitude of entire world - /// AREA_PARAM_GRAVITY_VECTOR to get the gravity direction of entire world - Variant get_param(PhysicsServer3D::AreaParameter p_param); - - void set_param(PhysicsServer3D::SpaceParameter p_param, real_t p_value); - real_t get_param(PhysicsServer3D::SpaceParameter p_param); - - void add_area(AreaBullet *p_area); - void remove_area(AreaBullet *p_area); - void reload_collision_filters(AreaBullet *p_area); - - void add_rigid_body(RigidBodyBullet *p_body); - void remove_rigid_body_constraints(RigidBodyBullet *p_body); - void remove_rigid_body(RigidBodyBullet *p_body); - void reload_collision_filters(RigidBodyBullet *p_body); - - void add_soft_body(SoftBodyBullet *p_body); - void remove_soft_body(SoftBodyBullet *p_body); - void reload_collision_filters(SoftBodyBullet *p_body); - - void add_constraint(ConstraintBullet *p_constraint, bool disableCollisionsBetweenLinkedBodies = false); - void remove_constraint(ConstraintBullet *p_constraint); - - int get_num_collision_objects() const; - void remove_all_collision_objects(); - - BulletPhysicsDirectSpaceState *get_direct_state(); - - void set_debug_contacts(int p_amount) { contactDebug.resize(p_amount); } - _FORCE_INLINE_ bool is_debugging_contacts() const { return !contactDebug.is_empty(); } - _FORCE_INLINE_ void reset_debug_contact_count() { - contactDebugCount = 0; - } - _FORCE_INLINE_ void add_debug_contact(const Vector3 &p_contact) { - if (contactDebugCount < contactDebug.size()) { - contactDebug.write[contactDebugCount++] = p_contact; - } - } - _FORCE_INLINE_ Vector<Vector3> get_debug_contacts() { return contactDebug; } - _FORCE_INLINE_ int get_debug_contact_count() { return contactDebugCount; } - - const Vector3 &get_gravity_direction() const { return gravityDirection; } - real_t get_gravity_magnitude() const { return gravityMagnitude; } - - void update_gravity(); - - real_t get_linear_damp() const { return linear_damp; } - real_t get_angular_damp() const { return angular_damp; } - - bool test_body_motion(RigidBodyBullet *p_body, const Transform3D &p_from, const Vector3 &p_motion, bool p_infinite_inertia, PhysicsServer3D::MotionResult *r_result, bool p_exclude_raycast_shapes, const Set<RID> &p_exclude = Set<RID>()); - int test_ray_separation(RigidBodyBullet *p_body, const Transform3D &p_transform, bool p_infinite_inertia, Vector3 &r_recover_motion, PhysicsServer3D::SeparationResult *r_results, int p_result_max, real_t p_margin); - -private: - void create_empty_world(bool p_create_soft_world); - void destroy_world(); - void check_ghost_overlaps(); - void check_body_collision(); - - struct RecoverResult { - bool hasPenetration = false; - btVector3 normal = btVector3(0, 0, 0); - btVector3 pointWorld = btVector3(0, 0, 0); - btScalar penetration_distance = 1e20; // Negative mean penetration - int other_compound_shape_index = 0; - const btCollisionObject *other_collision_object = nullptr; - int local_shape_most_recovered = 0; - - RecoverResult() {} - }; - - bool recover_from_penetration(RigidBodyBullet *p_body, const btTransform &p_body_position, btScalar p_recover_movement_scale, bool p_infinite_inertia, btVector3 &r_delta_recover_movement, RecoverResult *r_recover_result = nullptr, const Set<RID> &p_exclude = Set<RID>()); - /// This is an API that recover a kinematic object from penetration - /// This allow only Convex Convex test and it always use GJK algorithm, With this API we don't benefit of Bullet special accelerated functions - bool RFP_convex_convex_test(const btConvexShape *p_shapeA, const btConvexShape *p_shapeB, btCollisionObject *p_objectB, int p_shapeId_A, int p_shapeId_B, const btTransform &p_transformA, const btTransform &p_transformB, btScalar p_recover_movement_scale, btVector3 &r_delta_recover_movement, RecoverResult *r_recover_result = nullptr); - /// This is an API that recover a kinematic object from penetration - /// Using this we leave Bullet to select the best algorithm, For example GJK in case we have Convex Convex, or a Bullet accelerated algorithm - bool RFP_convex_world_test(const btConvexShape *p_shapeA, const btCollisionShape *p_shapeB, btCollisionObject *p_objectA, btCollisionObject *p_objectB, int p_shapeId_A, int p_shapeId_B, const btTransform &p_transformA, const btTransform &p_transformB, btScalar p_recover_movement_scale, btVector3 &r_delta_recover_movement, RecoverResult *r_recover_result = nullptr); - - int add_separation_result(PhysicsServer3D::SeparationResult *r_results, const SpaceBullet::RecoverResult &p_recover_result, int p_shape_id, const btCollisionObject *p_other_object) const; - int recover_from_penetration_ray(RigidBodyBullet *p_body, const btTransform &p_body_position, btScalar p_recover_movement_scale, bool p_infinite_inertia, int p_result_max, btVector3 &r_delta_recover_movement, PhysicsServer3D::SeparationResult *r_results); -}; - -#endif // SPACE_BULLET_H diff --git a/modules/csg/csg_shape.cpp b/modules/csg/csg_shape.cpp index a659062438..be9bf9538f 100644 --- a/modules/csg/csg_shape.cpp +++ b/modules/csg/csg_shape.cpp @@ -138,7 +138,7 @@ float CSGShape3D::get_snap() const { void CSGShape3D::_make_dirty(bool p_parent_removing) { if ((p_parent_removing || is_root_shape()) && !dirty) { - call_deferred("_update_shape"); // Must be deferred; otherwise, is_root_shape() will use the previous parent + call_deferred(SNAME("_update_shape")); // Must be deferred; otherwise, is_root_shape() will use the previous parent } if (!is_root_shape()) { @@ -280,7 +280,7 @@ void CSGShape3D::mikktSetTSpaceDefault(const SMikkTSpaceContext *pContext, const } void CSGShape3D::_update_shape() { - if (!is_root_shape() || !is_inside_tree()) { + if (!is_root_shape()) { return; } @@ -303,17 +303,19 @@ void CSGShape3D::_update_shape() { ERR_CONTINUE(mat < -1 || mat >= face_count.size()); int idx = mat == -1 ? face_count.size() - 1 : mat; - Plane p(n->faces[i].vertices[0], n->faces[i].vertices[1], n->faces[i].vertices[2]); + if (n->faces[i].smooth) { + Plane p(n->faces[i].vertices[0], n->faces[i].vertices[1], n->faces[i].vertices[2]); - for (int j = 0; j < 3; j++) { - Vector3 v = n->faces[i].vertices[j]; - Vector3 add; - if (vec_map.lookup(v, add)) { - add += p.normal; - } else { - add = p.normal; + for (int j = 0; j < 3; j++) { + Vector3 v = n->faces[i].vertices[j]; + Vector3 add; + if (vec_map.lookup(v, add)) { + add += p.normal; + } else { + add = p.normal; + } + vec_map.set(v, add); } - vec_map.set(v, add); } face_count.write[idx]++; @@ -491,10 +493,6 @@ Vector<Vector3> CSGShape3D::get_brush_faces() { return faces; } -Vector<Face3> CSGShape3D::get_faces(uint32_t p_usage_flags) const { - return Vector<Face3>(); -} - void CSGShape3D::_notification(int p_what) { switch (p_what) { case NOTIFICATION_PARENTED: { @@ -1534,6 +1532,9 @@ CSGBrush *CSGTorus3D::_build_brush() { for (int i = 0; i < sides; i++) { float inci = float(i) / sides; float inci_n = float((i + 1)) / sides; + if (i == sides - 1) { + inci_n = 0; + } float angi = inci * Math_TAU; float angi_n = inci_n * Math_TAU; @@ -1544,6 +1545,9 @@ CSGBrush *CSGTorus3D::_build_brush() { for (int j = 0; j < ring_sides; j++) { float incj = float(j) / ring_sides; float incj_n = float((j + 1)) / ring_sides; + if (j == ring_sides - 1) { + incj_n = 0; + } float angj = incj * Math_TAU; float angj_n = incj_n * Math_TAU; diff --git a/modules/csg/csg_shape.h b/modules/csg/csg_shape.h index d16250e30d..4721d0c11c 100644 --- a/modules/csg/csg_shape.h +++ b/modules/csg/csg_shape.h @@ -128,7 +128,6 @@ public: virtual Vector<Vector3> get_brush_faces(); virtual AABB get_aabb() const override; - virtual Vector<Face3> get_faces(uint32_t p_usage_flags) const override; void set_use_collision(bool p_enable); bool is_using_collision() const; diff --git a/modules/csg/register_types.cpp b/modules/csg/register_types.cpp index f01907bef3..f8db42b1a9 100644 --- a/modules/csg/register_types.cpp +++ b/modules/csg/register_types.cpp @@ -36,8 +36,8 @@ void register_csg_types() { #ifndef _3D_DISABLED - GDREGISTER_VIRTUAL_CLASS(CSGShape3D); - GDREGISTER_VIRTUAL_CLASS(CSGPrimitive3D); + GDREGISTER_ABSTRACT_CLASS(CSGShape3D); + GDREGISTER_ABSTRACT_CLASS(CSGPrimitive3D); GDREGISTER_CLASS(CSGMesh3D); GDREGISTER_CLASS(CSGSphere3D); GDREGISTER_CLASS(CSGBox3D); diff --git a/modules/enet/register_types.cpp b/modules/enet/register_types.cpp index 36a4e6e6e7..ebc5d95348 100644 --- a/modules/enet/register_types.cpp +++ b/modules/enet/register_types.cpp @@ -44,7 +44,7 @@ void register_enet_types() { } GDREGISTER_CLASS(ENetMultiplayerPeer); - GDREGISTER_VIRTUAL_CLASS(ENetPacketPeer); + GDREGISTER_ABSTRACT_CLASS(ENetPacketPeer); GDREGISTER_CLASS(ENetConnection); } diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp index 8bf5fd1eda..c12c1a43a3 100644 --- a/modules/gdscript/gdscript.cpp +++ b/modules/gdscript/gdscript.cpp @@ -938,7 +938,7 @@ const Vector<Multiplayer::RPCConfig> GDScript::get_rpc_methods() const { return rpc_functions; } -Variant GDScript::call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) { +Variant GDScript::callp(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) { GDScript *top = this; while (top) { Map<StringName, GDScriptFunction *>::Element *E = top->member_functions.find(p_method); @@ -952,7 +952,7 @@ Variant GDScript::call(const StringName &p_method, const Variant **p_args, int p //none found, regular - return Script::call(p_method, p_args, p_argcount, r_error); + return Script::callp(p_method, p_args, p_argcount, r_error); } bool GDScript::_get(const StringName &p_name, Variant &r_ret) const { @@ -1273,7 +1273,7 @@ bool GDScriptInstance::set(const StringName &p_name, const Variant &p_value) { if (member->setter) { const Variant *val = &p_value; Callable::CallError err; - call(member->setter, &val, 1, err); + callp(member->setter, &val, 1, err); if (err.error == Callable::CallError::CALL_OK) { return true; //function exists, call was successful } else { @@ -1335,7 +1335,7 @@ bool GDScriptInstance::get(const StringName &p_name, Variant &r_ret) const { if (E) { if (E->get().getter) { Callable::CallError err; - r_ret = const_cast<GDScriptInstance *>(this)->call(E->get().getter, nullptr, 0, err); + r_ret = const_cast<GDScriptInstance *>(this)->callp(E->get().getter, nullptr, 0, err); if (err.error == Callable::CallError::CALL_OK) { return true; } @@ -1520,7 +1520,7 @@ bool GDScriptInstance::has_method(const StringName &p_method) const { return false; } -Variant GDScriptInstance::call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) { +Variant GDScriptInstance::callp(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) { GDScript *sptr = script.ptr(); while (sptr) { Map<StringName, GDScriptFunction *>::Element *E = sptr->member_functions.find(p_method); @@ -1555,7 +1555,7 @@ void GDScriptInstance::notification(int p_notification) { String GDScriptInstance::to_string(bool *r_valid) { if (has_method(CoreStringNames::get_singleton()->_to_string)) { Callable::CallError ce; - Variant ret = call(CoreStringNames::get_singleton()->_to_string, nullptr, 0, ce); + Variant ret = callp(CoreStringNames::get_singleton()->_to_string, nullptr, 0, ce); if (ce.error == Callable::CallError::CALL_OK) { if (ret.get_type() != Variant::STRING) { if (r_valid) { diff --git a/modules/gdscript/gdscript.h b/modules/gdscript/gdscript.h index 2b43e6d21b..30e60e2b91 100644 --- a/modules/gdscript/gdscript.h +++ b/modules/gdscript/gdscript.h @@ -166,7 +166,7 @@ protected: bool _set(const StringName &p_name, const Variant &p_value); void _get_property_list(List<PropertyInfo> *p_properties) const; - Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) override; + Variant callp(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) override; static void _bind_methods(); @@ -285,7 +285,7 @@ public: virtual void get_method_list(List<MethodInfo> *p_list) const; virtual bool has_method(const StringName &p_method) const; - virtual Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error); + virtual Variant callp(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error); Variant debug_get_member_by_index(int p_idx) const { return members[p_idx]; } diff --git a/modules/gdscript/gdscript_rpc_callable.cpp b/modules/gdscript/gdscript_rpc_callable.cpp index 07e5ed4171..07ef5aefcb 100644 --- a/modules/gdscript/gdscript_rpc_callable.cpp +++ b/modules/gdscript/gdscript_rpc_callable.cpp @@ -64,7 +64,7 @@ ObjectID GDScriptRPCCallable::get_object() const { } void GDScriptRPCCallable::call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const { - r_return_value = object->call(method, p_arguments, p_argcount, r_call_error); + r_return_value = object->callp(method, p_arguments, p_argcount, r_call_error); } GDScriptRPCCallable::GDScriptRPCCallable(Object *p_object, const StringName &p_method) { diff --git a/modules/gdscript/gdscript_vm.cpp b/modules/gdscript/gdscript_vm.cpp index 6964f27423..41c59c7703 100644 --- a/modules/gdscript/gdscript_vm.cpp +++ b/modules/gdscript/gdscript_vm.cpp @@ -1447,7 +1447,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a const StringName native_type = _global_names_ptr[native_type_idx]; Array array; - array.set_typed(builtin_type, native_type, script_type); + array.set_typed(builtin_type, native_type, *script_type); array.resize(argc); for (int i = 0; i < argc; i++) { @@ -1517,7 +1517,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a Callable::CallError err; if (call_ret) { GET_INSTRUCTION_ARG(ret, argc + 1); - base->call(*methodname, (const Variant **)argptrs, argc, *ret, err); + base->callp(*methodname, (const Variant **)argptrs, argc, *ret, err); #ifdef DEBUG_ENABLED if (!call_async && ret->get_type() == Variant::OBJECT) { // Check if getting a function state without await. @@ -1536,7 +1536,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a #endif } else { Variant ret; - base->call(*methodname, (const Variant **)argptrs, argc, ret, err); + base->callp(*methodname, (const Variant **)argptrs, argc, ret, err); } #ifdef DEBUG_ENABLED if (GDScriptLanguage::get_singleton()->profiling) { @@ -2340,7 +2340,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a } Array array; - array.set_typed(builtin_type, native_type, script_type); + array.set_typed(builtin_type, native_type, *script_type); #ifdef DEBUG_ENABLED bool valid = array.typed_assign(*VariantInternal::get_array(r)); @@ -2810,7 +2810,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a args[0] = &vref; Callable::CallError ce; - Variant has_next = obj->call(CoreStringNames::get_singleton()->_iter_init, (const Variant **)args, 1, ce); + Variant has_next = obj->callp(CoreStringNames::get_singleton()->_iter_init, (const Variant **)args, 1, ce); #ifdef DEBUG_ENABLED if (ce.error != Callable::CallError::CALL_OK) { @@ -2824,7 +2824,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a ip = jumpto; } else { GET_INSTRUCTION_ARG(iterator, 2); - *iterator = obj->call(CoreStringNames::get_singleton()->_iter_get, (const Variant **)args, 1, ce); + *iterator = obj->callp(CoreStringNames::get_singleton()->_iter_get, (const Variant **)args, 1, ce); #ifdef DEBUG_ENABLED if (ce.error != Callable::CallError::CALL_OK) { err_text = vformat(R"(There was an error calling "_iter_get" on iterator object of type %s.)", *container); @@ -3141,7 +3141,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a args[0] = &vref; Callable::CallError ce; - Variant has_next = obj->call(CoreStringNames::get_singleton()->_iter_next, (const Variant **)args, 1, ce); + Variant has_next = obj->callp(CoreStringNames::get_singleton()->_iter_next, (const Variant **)args, 1, ce); #ifdef DEBUG_ENABLED if (ce.error != Callable::CallError::CALL_OK) { @@ -3155,7 +3155,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a ip = jumpto; } else { GET_INSTRUCTION_ARG(iterator, 2); - *iterator = obj->call(CoreStringNames::get_singleton()->_iter_get, (const Variant **)args, 1, ce); + *iterator = obj->callp(CoreStringNames::get_singleton()->_iter_get, (const Variant **)args, 1, ce); #ifdef DEBUG_ENABLED if (ce.error != Callable::CallError::CALL_OK) { err_text = vformat(R"(There was an error calling "_iter_get" on iterator object of type %s.)", *container); diff --git a/modules/gdscript/tests/gdscript_test_runner.cpp b/modules/gdscript/tests/gdscript_test_runner.cpp index c2bb2caa29..e8ddf90836 100644 --- a/modules/gdscript/tests/gdscript_test_runner.cpp +++ b/modules/gdscript/tests/gdscript_test_runner.cpp @@ -573,7 +573,7 @@ GDScriptTest::TestResult GDScriptTest::execute_test_code(bool p_is_generating) { // Call test function. Callable::CallError call_err; - instance->call(GDScriptTestRunner::test_function_name, nullptr, 0, call_err); + instance->callp(GDScriptTestRunner::test_function_name, nullptr, 0, call_err); // Tear down output handlers. remove_print_handler(&_print_handler); diff --git a/modules/minimp3/audio_stream_mp3.cpp b/modules/minimp3/audio_stream_mp3.cpp index 63fec6db8c..b5b51403f7 100644 --- a/modules/minimp3/audio_stream_mp3.cpp +++ b/modules/minimp3/audio_stream_mp3.cpp @@ -83,7 +83,7 @@ void AudioStreamPlaybackMP3::start(float p_from_pos) { active = true; seek(p_from_pos); loops = 0; - _begin_resample(); + begin_resample(); } void AudioStreamPlaybackMP3::stop() { diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp index c0b0d63600..7ed0422236 100644 --- a/modules/mono/csharp_script.cpp +++ b/modules/mono/csharp_script.cpp @@ -1893,7 +1893,7 @@ bool CSharpInstance::has_method(const StringName &p_method) const { return false; } -Variant CSharpInstance::call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) { +Variant CSharpInstance::callp(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) { ERR_FAIL_COND_V(!script.is_valid(), Variant()); GD_MONO_SCOPE_THREAD_ATTACH; @@ -2908,7 +2908,7 @@ int CSharpScript::_try_get_member_export_hint(IMonoClassMember *p_member, Manage } #endif -Variant CSharpScript::call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) { +Variant CSharpScript::callp(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) { if (unlikely(GDMono::get_singleton() == nullptr)) { // Probably not the best error but eh. r_error.error = Callable::CallError::CALL_ERROR_INSTANCE_IS_NULL; @@ -2936,7 +2936,7 @@ Variant CSharpScript::call(const StringName &p_method, const Variant **p_args, i } // No static method found. Try regular instance calls - return Script::call(p_method, p_args, p_argcount, r_error); + return Script::callp(p_method, p_args, p_argcount, r_error); } void CSharpScript::_resource_path_changed() { diff --git a/modules/mono/csharp_script.h b/modules/mono/csharp_script.h index d6cd9e6e57..3b97d2acc4 100644 --- a/modules/mono/csharp_script.h +++ b/modules/mono/csharp_script.h @@ -184,7 +184,7 @@ private: protected: static void _bind_methods(); - Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) override; + Variant callp(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) override; void _resource_path_changed() override; bool _get(const StringName &p_name, Variant &r_ret) const; bool _set(const StringName &p_name, const Variant &p_value); @@ -295,7 +295,7 @@ public: void get_method_list(List<MethodInfo> *p_list) const override; bool has_method(const StringName &p_method) const override; - Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) override; + Variant callp(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) override; void mono_object_disposed(MonoObject *p_obj); diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs index ee218cb1f8..d4b623b2ea 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs @@ -511,8 +511,9 @@ namespace Godot /// Returns the result of the spherical linear interpolation between /// this vector and <paramref name="to"/> by amount <paramref name="weight"/>. /// - /// This method also handles interpolating the lengths if the input vectors have different lengths. - /// For the special case of one or both input vectors having zero length, this method behaves like [method lerp]. + /// This method also handles interpolating the lengths if the input vectors + /// have different lengths. For the special case of one or both input vectors + /// having zero length, this method behaves like <see cref="Lerp"/>. /// </summary> /// <param name="to">The destination vector for interpolation.</param> /// <param name="weight">A value on the range of 0.0 to 1.0, representing the amount of interpolation.</param> diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs index 45e5287610..eddfa76f10 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs @@ -551,8 +551,9 @@ namespace Godot /// Returns the result of the spherical linear interpolation between /// this vector and <paramref name="to"/> by amount <paramref name="weight"/>. /// - /// This method also handles interpolating the lengths if the input vectors have different lengths. - /// For the special case of one or both input vectors having zero length, this method behaves like [method lerp]. + /// This method also handles interpolating the lengths if the input vectors + /// have different lengths. For the special case of one or both input vectors + /// having zero length, this method behaves like <see cref="Lerp"/>. /// </summary> /// <param name="to">The destination vector for interpolation.</param> /// <param name="weight">A value on the range of 0.0 to 1.0, representing the amount of interpolation.</param> diff --git a/modules/mono/glue/base_object_glue.cpp b/modules/mono/glue/base_object_glue.cpp index 8e7b125ed5..b5f2c98af5 100644 --- a/modules/mono/glue/base_object_glue.cpp +++ b/modules/mono/glue/base_object_glue.cpp @@ -199,7 +199,7 @@ MonoBoolean godot_icall_DynamicGodotObject_InvokeMember(Object *p_ptr, MonoStrin } Callable::CallError error; - Variant result = p_ptr->call(StringName(name), args.ptr(), argc, error); + Variant result = p_ptr->callp(StringName(name), args.ptr(), argc, error); *r_result = GDMonoMarshal::variant_to_mono_object(result); diff --git a/modules/mono/mono_gd/gd_mono.cpp b/modules/mono/mono_gd/gd_mono.cpp index 4cd4772d2c..424b74906f 100644 --- a/modules/mono/mono_gd/gd_mono.cpp +++ b/modules/mono/mono_gd/gd_mono.cpp @@ -643,9 +643,8 @@ bool GDMono::copy_prebuilt_api_assembly(ApiAssemblyInfo::Type p_api_type, const // Create destination directory if needed if (!DirAccess::exists(dst_dir)) { - DirAccess *da = DirAccess::create_for_path(dst_dir); + DirAccessRef da = DirAccess::create_for_path(dst_dir); Error err = da->make_dir_recursive(dst_dir); - memdelete(da); if (err != OK) { ERR_PRINT("Failed to create destination directory for the API assemblies. Error: " + itos(err) + "."); diff --git a/modules/navigation/rvo_agent.cpp b/modules/navigation/rvo_agent.cpp index c967d0bf98..a6a5660c0c 100644 --- a/modules/navigation/rvo_agent.cpp +++ b/modules/navigation/rvo_agent.cpp @@ -75,5 +75,5 @@ void RvoAgent::dispatch_callback() { const Variant *vp[2] = { &callback.new_velocity, &callback.udata }; int argc = (callback.udata.get_type() == Variant::NIL) ? 1 : 2; - obj->call(callback.method, vp, argc, responseCallError); + obj->callp(callback.method, vp, argc, responseCallError); } diff --git a/modules/openxr/doc_classes/OpenXRInterface.xml b/modules/openxr/doc_classes/OpenXRInterface.xml index 1160061e04..74f708bc95 100644 --- a/modules/openxr/doc_classes/OpenXRInterface.xml +++ b/modules/openxr/doc_classes/OpenXRInterface.xml @@ -10,4 +10,31 @@ <tutorials> <link title="OpenXR documentation">$DOCS_URL/tutorials/vr/openxr/index.html</link> </tutorials> + <signals> + <signal name="pose_recentered"> + <description> + Informs the user queued a recenter of the player position. + </description> + </signal> + <signal name="session_begun"> + <description> + Informs our OpenXR session has been started. + </description> + </signal> + <signal name="session_focussed"> + <description> + Informs our OpenXR session now has focus. + </description> + </signal> + <signal name="session_stopping"> + <description> + Informs our OpenXR session is stopping. + </description> + </signal> + <signal name="session_visible"> + <description> + Informs our OpenXR session is now visible (output is being sent to the HMD). + </description> + </signal> + </signals> </class> diff --git a/modules/openxr/openxr_api.cpp b/modules/openxr/openxr_api.cpp index e3da214cc8..4d533337f3 100644 --- a/modules/openxr/openxr_api.cpp +++ b/modules/openxr/openxr_api.cpp @@ -48,6 +48,8 @@ #include "extensions/openxr_vulkan_extension.h" #endif +#include "modules/openxr/openxr_interface.h" + OpenXRAPI *OpenXRAPI::singleton = nullptr; void OpenXRAPI::setup_global_defs() { @@ -877,7 +879,9 @@ bool OpenXRAPI::on_state_ready() { wrapper->on_state_ready(); } - // TODO emit signal + if (xr_interface) { + xr_interface->on_state_ready(); + } // TODO Tell android @@ -889,6 +893,13 @@ bool OpenXRAPI::on_state_synchronized() { print_line("On state synchronized"); #endif + // Just in case, see if we already have active trackers... + List<RID> trackers; + tracker_owner.get_owned_list(&trackers); + for (int i = 0; i < trackers.size(); i++) { + tracker_check_profile(trackers[i]); + } + for (OpenXRExtensionWrapper *wrapper : registered_extension_wrappers) { wrapper->on_state_synchronized(); } @@ -905,7 +916,9 @@ bool OpenXRAPI::on_state_visible() { wrapper->on_state_visible(); } - // TODO emit signal + if (xr_interface) { + xr_interface->on_state_visible(); + } return true; } @@ -919,7 +932,9 @@ bool OpenXRAPI::on_state_focused() { wrapper->on_state_focused(); } - // TODO emit signal + if (xr_interface) { + xr_interface->on_state_focused(); + } return true; } @@ -929,7 +944,9 @@ bool OpenXRAPI::on_state_stopping() { print_line("On state stopping"); #endif - // TODO emit signal + if (xr_interface) { + xr_interface->on_state_stopping(); + } for (OpenXRExtensionWrapper *wrapper : registered_extension_wrappers) { wrapper->on_state_stopping(); @@ -1081,6 +1098,10 @@ void OpenXRAPI::finish() { destroy_instance(); } +void OpenXRAPI::set_xr_interface(OpenXRInterface *p_xr_interface) { + xr_interface = p_xr_interface; +} + void OpenXRAPI::register_extension_wrapper(OpenXRExtensionWrapper *p_extension_wrapper) { registered_extension_wrappers.push_back(p_extension_wrapper); } @@ -1204,20 +1225,38 @@ bool OpenXRAPI::poll_events() { handled |= wrapper->on_event_polled(runtimeEvent); } switch (runtimeEvent.type) { - // case XR_TYPE_EVENT_DATA_EVENTS_LOST: { - // } break; - // case XR_TYPE_EVENT_DATA_VISIBILITY_MASK_CHANGED_KHR: { - // } break; - // case XR_TYPE_EVENT_DATA_INSTANCE_LOSS_PENDING: { - // } break; + case XR_TYPE_EVENT_DATA_EVENTS_LOST: { + XrEventDataEventsLost *event = (XrEventDataEventsLost *)&runtimeEvent; + + // We probably didn't poll fast enough, just output warning + WARN_PRINT("OpenXR EVENT: " + itos(event->lostEventCount) + " event data lost!"); + } break; + case XR_TYPE_EVENT_DATA_VISIBILITY_MASK_CHANGED_KHR: { + // XrEventDataVisibilityMaskChangedKHR *event = (XrEventDataVisibilityMaskChangedKHR *)&runtimeEvent; + + // TODO implement this in the future, we should call xrGetVisibilityMaskKHR to obtain a mask, + // this will allow us to prevent rendering the part of our view which is never displayed giving us + // a decent performance improvement. + + print_verbose("OpenXR EVENT: STUB: visibility mask changed"); + } break; + case XR_TYPE_EVENT_DATA_INSTANCE_LOSS_PENDING: { + XrEventDataInstanceLossPending *event = (XrEventDataInstanceLossPending *)&runtimeEvent; + + // TODO We get this event if we're about to loose our OpenXR instance. + // We should queue exiting Godot at this point. + + print_verbose("OpenXR EVENT: instance loss pending at " + itos(event->lossTime)); + return false; + } break; case XR_TYPE_EVENT_DATA_SESSION_STATE_CHANGED: { XrEventDataSessionStateChanged *event = (XrEventDataSessionStateChanged *)&runtimeEvent; session_state = event->state; if (session_state >= XR_SESSION_STATE_MAX_ENUM) { - print_line("OpenXR EVENT: session state changed to UNKNOWN -", session_state); + print_verbose("OpenXR EVENT: session state changed to UNKNOWN - " + itos(session_state)); } else { - print_line("OpenXR EVENT: session state changed to", OpenXRUtil::get_session_state_name(session_state)); + print_verbose("OpenXR EVENT: session state changed to " + OpenXRUtil::get_session_state_name(session_state)); switch (session_state) { case XR_SESSION_STATE_IDLE: @@ -1249,13 +1288,29 @@ bool OpenXRAPI::poll_events() { } } } break; - // case XR_TYPE_EVENT_DATA_REFERENCE_SPACE_CHANGE_PENDING: { - // } break; - // case XR_TYPE_EVENT_DATA_INTERACTION_PROFILE_CHANGED: { - // } break; + case XR_TYPE_EVENT_DATA_REFERENCE_SPACE_CHANGE_PENDING: { + XrEventDataReferenceSpaceChangePending *event = (XrEventDataReferenceSpaceChangePending *)&runtimeEvent; + + print_verbose("OpenXR EVENT: reference space type " + OpenXRUtil::get_reference_space_name(event->referenceSpaceType) + " change pending!"); + if (event->poseValid && xr_interface) { + xr_interface->on_pose_recentered(); + } + } break; + case XR_TYPE_EVENT_DATA_INTERACTION_PROFILE_CHANGED: { + print_verbose("OpenXR EVENT: interaction profile changed!"); + + XrEventDataInteractionProfileChanged *event = (XrEventDataInteractionProfileChanged *)&runtimeEvent; + + List<RID> trackers; + tracker_owner.get_owned_list(&trackers); + for (int i = 0; i < trackers.size(); i++) { + tracker_check_profile(trackers[i], event->session); + } + + } break; default: if (!handled) { - print_line("OpenXR Unhandled event type", OpenXRUtil::get_structure_type_name(runtimeEvent.type)); + print_verbose("OpenXR Unhandled event type " + OpenXRUtil::get_structure_type_name(runtimeEvent.type)); } break; } @@ -1348,9 +1403,21 @@ void OpenXRAPI::pre_render() { XrResult result = xrWaitFrame(session, &frame_wait_info, &frame_state); if (XR_FAILED(result)) { print_line("OpenXR: xrWaitFrame() was not successful [", get_error_string(result), "]"); + + // reset just in case + frame_state.predictedDisplayTime = 0; + frame_state.predictedDisplayPeriod = 0; + frame_state.shouldRender = false; + return; } + if (frame_state.predictedDisplayPeriod > 500000000) { + // display period more then 0.5 seconds? must be wrong data + print_verbose("OpenXR resetting invalid display period " + rtos(frame_state.predictedDisplayPeriod)); + frame_state.predictedDisplayPeriod = 0; + } + for (OpenXRExtensionWrapper *wrapper : registered_extension_wrappers) { wrapper->on_pre_render(); } @@ -1691,38 +1758,97 @@ void OpenXRAPI::parse_velocities(const XrSpaceVelocity &p_velocity, Vector3 &r_l } } -RID OpenXRAPI::path_create(const String p_name) { - ERR_FAIL_COND_V(instance == XR_NULL_HANDLE, RID()); +RID OpenXRAPI::get_tracker_rid(XrPath p_path) { + List<RID> current; + tracker_owner.get_owned_list(¤t); + for (int i = 0; i < current.size(); i++) { + Tracker *tracker = tracker_owner.get_or_null(current[i]); + if (tracker && tracker->toplevel_path == p_path) { + return current[i]; + } + } - // Encoding our path as a RID is probably overkill but it does future proof this - // Note that we only do this for XrPaths that we access from outside of this class! + return RID(); +} - Path new_path; +RID OpenXRAPI::tracker_create(const String p_name) { + ERR_FAIL_COND_V(instance == XR_NULL_HANDLE, RID()); - print_line("Parsing path ", p_name); + Tracker new_tracker; + new_tracker.name = p_name; + new_tracker.toplevel_path = XR_NULL_PATH; + new_tracker.active_profile_rid = RID(); - XrResult result = xrStringToPath(instance, p_name.utf8().get_data(), &new_path.path); + XrResult result = xrStringToPath(instance, p_name.utf8().get_data(), &new_tracker.toplevel_path); if (XR_FAILED(result)) { print_line("OpenXR: failed to get path for ", p_name, "! [", get_error_string(result), "]"); return RID(); } - return xr_path_owner.make_rid(new_path); + return tracker_owner.make_rid(new_tracker); } -void OpenXRAPI::path_free(RID p_path) { - Path *path = xr_path_owner.get_or_null(p_path); - ERR_FAIL_NULL(path); +String OpenXRAPI::tracker_get_name(RID p_tracker) { + if (p_tracker.is_null()) { + return String("None"); + } + + Tracker *tracker = tracker_owner.get_or_null(p_tracker); + ERR_FAIL_NULL_V(tracker, String()); + + return tracker->name; +} + +void OpenXRAPI::tracker_check_profile(RID p_tracker, XrSession p_session) { + if (p_session == XR_NULL_HANDLE) { + p_session = session; + } + + Tracker *tracker = tracker_owner.get_or_null(p_tracker); + ERR_FAIL_NULL(tracker); + + if (tracker->toplevel_path == XR_NULL_PATH) { + // no path, how was this even created? + return; + } + + XrInteractionProfileState profile_state = { + XR_TYPE_INTERACTION_PROFILE_STATE, // type + nullptr, // next + XR_NULL_PATH // interactionProfile + }; + + XrResult result = xrGetCurrentInteractionProfile(p_session, tracker->toplevel_path, &profile_state); + if (XR_FAILED(result)) { + print_line("OpenXR: Failed to get interaction profile for", itos(tracker->toplevel_path), "[", get_error_string(result), "]"); + return; + } + + XrPath new_profile = profile_state.interactionProfile; + XrPath was_profile = get_interaction_profile_path(tracker->active_profile_rid); + if (was_profile != new_profile) { + tracker->active_profile_rid = get_interaction_profile_rid(new_profile); + + if (xr_interface) { + xr_interface->tracker_profile_changed(p_tracker, tracker->active_profile_rid); + } + } +} + +void OpenXRAPI::tracker_free(RID p_tracker) { + Tracker *tracker = tracker_owner.get_or_null(p_tracker); + ERR_FAIL_NULL(tracker); // there is nothing to free here - xr_path_owner.free(p_path); + tracker_owner.free(p_tracker); } RID OpenXRAPI::action_set_create(const String p_name, const String p_localized_name, const int p_priority) { ERR_FAIL_COND_V(instance == XR_NULL_HANDLE, RID()); ActionSet action_set; + action_set.name = p_name; action_set.is_attached = false; // create our action set... @@ -1737,7 +1863,7 @@ RID OpenXRAPI::action_set_create(const String p_name, const String p_localized_n copy_string_to_char_buffer(p_name, action_set_info.actionSetName, XR_MAX_ACTION_SET_NAME_SIZE); copy_string_to_char_buffer(p_localized_name, action_set_info.localizedActionSetName, XR_MAX_LOCALIZED_ACTION_SET_NAME_SIZE); - print_line("Creating action set ", action_set_info.actionSetName, " - ", action_set_info.localizedActionSetName, " (", itos(action_set_info.priority), ")"); + // print_line("Creating action set ", action_set_info.actionSetName, " - ", action_set_info.localizedActionSetName, " (", itos(action_set_info.priority), ")"); XrResult result = xrCreateActionSet(instance, &action_set_info, &action_set.handle); if (XR_FAILED(result)) { @@ -1748,6 +1874,17 @@ RID OpenXRAPI::action_set_create(const String p_name, const String p_localized_n return action_set_owner.make_rid(action_set); } +String OpenXRAPI::action_set_get_name(RID p_action_set) { + if (p_action_set.is_null()) { + return String("None"); + } + + ActionSet *action_set = action_set_owner.get_or_null(p_action_set); + ERR_FAIL_NULL_V(action_set, String()); + + return action_set->name; +} + bool OpenXRAPI::action_set_attach(RID p_action_set) { ActionSet *action_set = action_set_owner.get_or_null(p_action_set); ERR_FAIL_NULL_V(action_set, false); @@ -1776,6 +1913,24 @@ bool OpenXRAPI::action_set_attach(RID p_action_set) { action_set->is_attached = true; + /* For debugging: + print_verbose("Attached set " + action_set->name); + List<RID> action_rids; + action_owner.get_owned_list(&action_rids); + for (int i = 0; i < action_rids.size(); i++) { + Action * action = action_owner.get_or_null(action_rids[i]); + if (action && action->action_set_rid == p_action_set) { + print_verbose(" - Action " + action->name + ": " + OpenXRUtil::get_action_type_name(action->action_type)); + for (int j = 0; j < action->trackers.size(); j++) { + Tracker * tracker = tracker_owner.get_or_null(action->trackers[j].tracker_rid); + if (tracker) { + print_verbose(" - " + tracker->name); + } + } + } + } + */ + return true; } @@ -1790,14 +1945,29 @@ void OpenXRAPI::action_set_free(RID p_action_set) { action_set_owner.free(p_action_set); } -RID OpenXRAPI::action_create(RID p_action_set, const String p_name, const String p_localized_name, OpenXRAction::ActionType p_action_type, const Vector<RID> &p_toplevel_paths) { +RID OpenXRAPI::get_action_rid(XrAction p_action) { + List<RID> current; + action_owner.get_owned_list(¤t); + for (int i = 0; i < current.size(); i++) { + Action *action = action_owner.get_or_null(current[i]); + if (action && action->handle == p_action) { + return current[i]; + } + } + + return RID(); +} + +RID OpenXRAPI::action_create(RID p_action_set, const String p_name, const String p_localized_name, OpenXRAction::ActionType p_action_type, const Vector<RID> &p_trackers) { ERR_FAIL_COND_V(instance == XR_NULL_HANDLE, RID()); Action action; + action.name = p_name; ActionSet *action_set = action_set_owner.get_or_null(p_action_set); ERR_FAIL_NULL_V(action_set, RID()); ERR_FAIL_COND_V(action_set->handle == XR_NULL_HANDLE, RID()); + action.action_set_rid = p_action_set; switch (p_action_type) { case OpenXRAction::OPENXR_ACTION_BOOL: @@ -1821,17 +1991,17 @@ RID OpenXRAPI::action_create(RID p_action_set, const String p_name, const String } Vector<XrPath> toplevel_paths; - for (int i = 0; i < p_toplevel_paths.size(); i++) { - Path *xr_path = xr_path_owner.get_or_null(p_toplevel_paths[i]); - if (xr_path != nullptr && xr_path->path != XR_NULL_PATH) { - PathWithSpace path_with_space = { - xr_path->path, // toplevel_path + for (int i = 0; i < p_trackers.size(); i++) { + Tracker *tracker = tracker_owner.get_or_null(p_trackers[i]); + if (tracker != nullptr && tracker->toplevel_path != XR_NULL_PATH) { + ActionTracker action_tracker = { + p_trackers[i], // tracker XR_NULL_HANDLE, // space false // was_location_valid }; - action.toplevel_paths.push_back(path_with_space); + action.trackers.push_back(action_tracker); - toplevel_paths.push_back(xr_path->path); + toplevel_paths.push_back(tracker->toplevel_path); } } @@ -1848,7 +2018,7 @@ RID OpenXRAPI::action_create(RID p_action_set, const String p_name, const String copy_string_to_char_buffer(p_name, action_info.actionName, XR_MAX_ACTION_NAME_SIZE); copy_string_to_char_buffer(p_localized_name, action_info.localizedActionName, XR_MAX_LOCALIZED_ACTION_NAME_SIZE); - print_line("Creating action ", action_info.actionName, action_info.localizedActionName, action_info.countSubactionPaths); + // print_line("Creating action ", action_info.actionName, action_info.localizedActionName, action_info.countSubactionPaths); XrResult result = xrCreateAction(action_set->handle, &action_info, &action.handle); if (XR_FAILED(result)) { @@ -1859,6 +2029,17 @@ RID OpenXRAPI::action_create(RID p_action_set, const String p_name, const String return action_owner.make_rid(action); } +String OpenXRAPI::action_get_name(RID p_action) { + if (p_action.is_null()) { + return String("None"); + } + + Action *action = action_owner.get_or_null(p_action); + ERR_FAIL_NULL_V(action, String()); + + return action->name; +} + void OpenXRAPI::action_free(RID p_action) { Action *action = action_owner.get_or_null(p_action); ERR_FAIL_NULL(action); @@ -1870,55 +2051,139 @@ void OpenXRAPI::action_free(RID p_action) { action_owner.free(p_action); } -bool OpenXRAPI::suggest_bindings(const String p_interaction_profile, const Vector<Binding> p_bindings) { - ERR_FAIL_COND_V(instance == XR_NULL_HANDLE, false); +RID OpenXRAPI::get_interaction_profile_rid(XrPath p_path) { + List<RID> current; + interaction_profile_owner.get_owned_list(¤t); + for (int i = 0; i < current.size(); i++) { + InteractionProfile *ip = interaction_profile_owner.get_or_null(current[i]); + if (ip && ip->path == p_path) { + return current[i]; + } + } + + return RID(); +} + +XrPath OpenXRAPI::get_interaction_profile_path(RID p_interaction_profile) { + if (p_interaction_profile.is_null()) { + return XR_NULL_PATH; + } + + InteractionProfile *ip = interaction_profile_owner.get_or_null(p_interaction_profile); + ERR_FAIL_NULL_V(ip, XR_NULL_PATH); - XrPath interaction_profile; - Vector<XrActionSuggestedBinding> bindings; + return ip->path; +} - XrResult result = xrStringToPath(instance, p_interaction_profile.utf8().get_data(), &interaction_profile); +RID OpenXRAPI::interaction_profile_create(const String p_name) { + InteractionProfile new_interaction_profile; + + XrResult result = xrStringToPath(instance, p_name.utf8().get_data(), &new_interaction_profile.path); if (XR_FAILED(result)) { - print_line("OpenXR: failed to get path for ", p_interaction_profile, "! [", get_error_string(result), "]"); - return false; + print_line("OpenXR: failed to get path for ", p_name, "! [", get_error_string(result), "]"); + return RID(); } - for (int i = 0; i < p_bindings.size(); i++) { - XrActionSuggestedBinding binding; + RID existing_ip = get_interaction_profile_rid(new_interaction_profile.path); + if (existing_ip.is_valid()) { + return existing_ip; + } - Action *action = action_owner.get_or_null(p_bindings[i].action); - if (action == nullptr || action->handle == XR_NULL_HANDLE) { - // just skip it - continue; - } + new_interaction_profile.name = p_name; + return interaction_profile_owner.make_rid(new_interaction_profile); +} - binding.action = action->handle; +String OpenXRAPI::interaction_profile_get_name(RID p_interaction_profile) { + if (p_interaction_profile.is_null()) { + return String("None"); + } - result = xrStringToPath(instance, p_bindings[i].path.utf8().get_data(), &binding.binding); - if (XR_FAILED(result)) { - print_line("OpenXR: failed to get path for ", p_bindings[i].path, "! [", get_error_string(result), "]"); - continue; - } + InteractionProfile *ip = interaction_profile_owner.get_or_null(p_interaction_profile); + ERR_FAIL_NULL_V(ip, String()); + + return ip->name; +} + +void OpenXRAPI::interaction_profile_clear_bindings(RID p_interaction_profile) { + InteractionProfile *ip = interaction_profile_owner.get_or_null(p_interaction_profile); + ERR_FAIL_NULL(ip); + + ip->bindings.clear(); +} + +bool OpenXRAPI::interaction_profile_add_binding(RID p_interaction_profile, RID p_action, const String p_path) { + InteractionProfile *ip = interaction_profile_owner.get_or_null(p_interaction_profile); + ERR_FAIL_NULL_V(ip, false); + + XrActionSuggestedBinding binding; + + Action *action = action_owner.get_or_null(p_action); + ERR_FAIL_COND_V(action == nullptr || action->handle == XR_NULL_HANDLE, false); - bindings.push_back(binding); + binding.action = action->handle; + + XrResult result = xrStringToPath(instance, p_path.utf8().get_data(), &binding.binding); + if (XR_FAILED(result)) { + print_line("OpenXR: failed to get path for ", p_path, "! [", get_error_string(result), "]"); + return false; } + ip->bindings.push_back(binding); + + return true; +} + +bool OpenXRAPI::interaction_profile_suggest_bindings(RID p_interaction_profile) { + ERR_FAIL_COND_V(instance == XR_NULL_HANDLE, false); + + InteractionProfile *ip = interaction_profile_owner.get_or_null(p_interaction_profile); + ERR_FAIL_NULL_V(ip, false); + const XrInteractionProfileSuggestedBinding suggested_bindings = { XR_TYPE_INTERACTION_PROFILE_SUGGESTED_BINDING, // type nullptr, // next - interaction_profile, // interactionProfile - uint32_t(bindings.size()), // countSuggestedBindings - bindings.ptr() // suggestedBindings + ip->path, // interactionProfile + uint32_t(ip->bindings.size()), // countSuggestedBindings + ip->bindings.ptr() // suggestedBindings }; - result = xrSuggestInteractionProfileBindings(instance, &suggested_bindings); - if (XR_FAILED(result)) { - print_line("OpenXR: failed to suggest bindings for ", p_interaction_profile, "! [", get_error_string(result), "]"); + XrResult result = xrSuggestInteractionProfileBindings(instance, &suggested_bindings); + if (result == XR_ERROR_PATH_UNSUPPORTED) { + // this is fine, not all runtimes support all devices. + print_verbose("OpenXR Interaction profile " + ip->name + " is not supported on this runtime"); + } else if (XR_FAILED(result)) { + print_line("OpenXR: failed to suggest bindings for ", ip->name, "! [", get_error_string(result), "]"); // reporting is enough... } + /* For debugging: + print_verbose("Suggested bindings for " + ip->name); + for (int i = 0; i < ip->bindings.size(); i++) { + uint32_t strlen; + char path[XR_MAX_PATH_LENGTH]; + + String action_name = action_get_name(get_action_rid(ip->bindings[i].action)); + + XrResult result = xrPathToString(instance, ip->bindings[i].binding, XR_MAX_PATH_LENGTH, &strlen, path); + if (XR_FAILED(result)) { + print_line("OpenXR: failed to retrieve bindings for ", action_name, "! [", get_error_string(result), "]"); + } + print_verbose(" - " + action_name + " => " + String(path)); + } + */ + return true; } +void OpenXRAPI::interaction_profile_free(RID p_interaction_profile) { + InteractionProfile *ip = interaction_profile_owner.get_or_null(p_interaction_profile); + ERR_FAIL_NULL(ip); + + ip->bindings.clear(); + + interaction_profile_owner.free(p_interaction_profile); +} + bool OpenXRAPI::sync_action_sets(const Vector<RID> p_active_sets) { ERR_FAIL_COND_V(session == XR_NULL_HANDLE, false); @@ -1955,12 +2220,12 @@ bool OpenXRAPI::sync_action_sets(const Vector<RID> p_active_sets) { return true; } -bool OpenXRAPI::get_action_bool(RID p_action, RID p_path) { +bool OpenXRAPI::get_action_bool(RID p_action, RID p_tracker) { ERR_FAIL_COND_V(session == XR_NULL_HANDLE, false); Action *action = action_owner.get_or_null(p_action); ERR_FAIL_NULL_V(action, false); - Path *path = xr_path_owner.get_or_null(p_path); - ERR_FAIL_NULL_V(path, false); + Tracker *tracker = tracker_owner.get_or_null(p_tracker); + ERR_FAIL_NULL_V(tracker, false); if (!running) { return false; @@ -1972,7 +2237,7 @@ bool OpenXRAPI::get_action_bool(RID p_action, RID p_path) { XR_TYPE_ACTION_STATE_GET_INFO, // type nullptr, // next action->handle, // action - path->path // subactionPath + tracker->toplevel_path // subactionPath }; XrActionStateBoolean result_state; @@ -1987,12 +2252,12 @@ bool OpenXRAPI::get_action_bool(RID p_action, RID p_path) { return result_state.isActive && result_state.currentState; } -float OpenXRAPI::get_action_float(RID p_action, RID p_path) { +float OpenXRAPI::get_action_float(RID p_action, RID p_tracker) { ERR_FAIL_COND_V(session == XR_NULL_HANDLE, 0.0); Action *action = action_owner.get_or_null(p_action); ERR_FAIL_NULL_V(action, 0.0); - Path *path = xr_path_owner.get_or_null(p_path); - ERR_FAIL_NULL_V(path, 0.0); + Tracker *tracker = tracker_owner.get_or_null(p_tracker); + ERR_FAIL_NULL_V(tracker, 0.0); if (!running) { return 0.0; @@ -2004,7 +2269,7 @@ float OpenXRAPI::get_action_float(RID p_action, RID p_path) { XR_TYPE_ACTION_STATE_GET_INFO, // type nullptr, // next action->handle, // action - path->path // subactionPath + tracker->toplevel_path // subactionPath }; XrActionStateFloat result_state; @@ -2019,12 +2284,12 @@ float OpenXRAPI::get_action_float(RID p_action, RID p_path) { return result_state.isActive ? result_state.currentState : 0.0; } -Vector2 OpenXRAPI::get_action_vector2(RID p_action, RID p_path) { +Vector2 OpenXRAPI::get_action_vector2(RID p_action, RID p_tracker) { ERR_FAIL_COND_V(session == XR_NULL_HANDLE, Vector2()); Action *action = action_owner.get_or_null(p_action); ERR_FAIL_NULL_V(action, Vector2()); - Path *path = xr_path_owner.get_or_null(p_path); - ERR_FAIL_NULL_V(path, Vector2()); + Tracker *tracker = tracker_owner.get_or_null(p_tracker); + ERR_FAIL_NULL_V(tracker, Vector2()); if (!running) { return Vector2(); @@ -2036,7 +2301,7 @@ Vector2 OpenXRAPI::get_action_vector2(RID p_action, RID p_path) { XR_TYPE_ACTION_STATE_GET_INFO, // type nullptr, // next action->handle, // action - path->path // subactionPath + tracker->toplevel_path // subactionPath }; XrActionStateVector2f result_state; @@ -2051,12 +2316,12 @@ Vector2 OpenXRAPI::get_action_vector2(RID p_action, RID p_path) { return result_state.isActive ? Vector2(result_state.currentState.x, result_state.currentState.y) : Vector2(); } -XRPose::TrackingConfidence OpenXRAPI::get_action_pose(RID p_action, RID p_path, Transform3D &r_transform, Vector3 &r_linear_velocity, Vector3 &r_angular_velocity) { +XRPose::TrackingConfidence OpenXRAPI::get_action_pose(RID p_action, RID p_tracker, Transform3D &r_transform, Vector3 &r_linear_velocity, Vector3 &r_angular_velocity) { ERR_FAIL_COND_V(session == XR_NULL_HANDLE, XRPose::XR_TRACKING_CONFIDENCE_NONE); Action *action = action_owner.get_or_null(p_action); ERR_FAIL_NULL_V(action, XRPose::XR_TRACKING_CONFIDENCE_NONE); - Path *path = xr_path_owner.get_or_null(p_path); - ERR_FAIL_NULL_V(path, XRPose::XR_TRACKING_CONFIDENCE_NONE); + Tracker *tracker = tracker_owner.get_or_null(p_tracker); + ERR_FAIL_NULL_V(tracker, XRPose::XR_TRACKING_CONFIDENCE_NONE); if (!running) { return XRPose::XR_TRACKING_CONFIDENCE_NONE; @@ -2064,10 +2329,12 @@ XRPose::TrackingConfidence OpenXRAPI::get_action_pose(RID p_action, RID p_path, ERR_FAIL_COND_V(action->action_type != XR_ACTION_TYPE_POSE_INPUT, XRPose::XR_TRACKING_CONFIDENCE_NONE); + // print_verbose("Checking " + action->name + " => " + tracker->name + " (" + itos(tracker->toplevel_path) + ")"); + uint64_t index = 0xFFFFFFFF; - uint64_t size = uint64_t(action->toplevel_paths.size()); + uint64_t size = uint64_t(action->trackers.size()); for (uint64_t i = 0; i < size && index == 0xFFFFFFFF; i++) { - if (action->toplevel_paths[i].toplevel_path == path->path) { + if (action->trackers[i].tracker_rid == p_tracker) { index = i; } } @@ -2077,14 +2344,19 @@ XRPose::TrackingConfidence OpenXRAPI::get_action_pose(RID p_action, RID p_path, return XRPose::XR_TRACKING_CONFIDENCE_NONE; } - if (action->toplevel_paths[index].space == XR_NULL_HANDLE) { + XrTime display_time = get_next_frame_time(); + if (display_time == 0) { + return XRPose::XR_TRACKING_CONFIDENCE_NONE; + } + + if (action->trackers[index].space == XR_NULL_HANDLE) { // if this is a pose we need to define spaces XrActionSpaceCreateInfo action_space_info = { XR_TYPE_ACTION_SPACE_CREATE_INFO, // type nullptr, // next action->handle, // action - action->toplevel_paths[index].toplevel_path, // subactionPath + tracker->toplevel_path, // subactionPath { { 0.0, 0.0, 0.0, 1.0 }, // orientation { 0.0, 0.0, 0.0 } // position @@ -2098,11 +2370,9 @@ XRPose::TrackingConfidence OpenXRAPI::get_action_pose(RID p_action, RID p_path, return XRPose::XR_TRACKING_CONFIDENCE_NONE; } - action->toplevel_paths.ptrw()[index].space = space; + action->trackers.ptrw()[index].space = space; } - XrTime display_time = get_next_frame_time(); - XrSpaceVelocity velocity = { XR_TYPE_SPACE_VELOCITY, // type nullptr, // next @@ -2121,7 +2391,7 @@ XRPose::TrackingConfidence OpenXRAPI::get_action_pose(RID p_action, RID p_path, } // pose }; - XrResult result = xrLocateSpace(action->toplevel_paths[index].space, play_space, display_time, &location); + XrResult result = xrLocateSpace(action->trackers[index].space, play_space, display_time, &location); if (XR_FAILED(result)) { print_line("OpenXR: failed to locate space! [", get_error_string(result), "]"); return XRPose::XR_TRACKING_CONFIDENCE_NONE; @@ -2133,12 +2403,12 @@ XRPose::TrackingConfidence OpenXRAPI::get_action_pose(RID p_action, RID p_path, return confidence; } -bool OpenXRAPI::trigger_haptic_pulse(RID p_action, RID p_path, float p_frequency, float p_amplitude, XrDuration p_duration_ns) { +bool OpenXRAPI::trigger_haptic_pulse(RID p_action, RID p_tracker, float p_frequency, float p_amplitude, XrDuration p_duration_ns) { ERR_FAIL_COND_V(session == XR_NULL_HANDLE, false); Action *action = action_owner.get_or_null(p_action); ERR_FAIL_NULL_V(action, false); - Path *path = xr_path_owner.get_or_null(p_path); - ERR_FAIL_NULL_V(path, false); + Tracker *tracker = tracker_owner.get_or_null(p_tracker); + ERR_FAIL_NULL_V(tracker, false); if (!running) { return false; @@ -2150,7 +2420,7 @@ bool OpenXRAPI::trigger_haptic_pulse(RID p_action, RID p_path, float p_frequency XR_TYPE_HAPTIC_ACTION_INFO, // type nullptr, // next action->handle, // action - path->path // subactionPath + tracker->toplevel_path // subactionPath }; XrHapticVibration vibration = { diff --git a/modules/openxr/openxr_api.h b/modules/openxr/openxr_api.h index 33b503543a..e20826c849 100644 --- a/modules/openxr/openxr_api.h +++ b/modules/openxr/openxr_api.h @@ -55,12 +55,16 @@ // forward declarations, we don't want to include these fully class OpenXRVulkanExtension; +class OpenXRInterface; class OpenXRAPI { private: // our singleton static OpenXRAPI *singleton; + // linked XR interface + OpenXRInterface *xr_interface = nullptr; + // layers uint32_t num_layer_properties = 0; XrApiLayerProperties *layer_properties = nullptr; @@ -148,29 +152,45 @@ private: bool release_image(XrSwapchain p_swapchain); // action map - struct Path { - XrPath path; + struct Tracker { // Trackers represent tracked physical objects such as controllers, pucks, etc. + String name; // Name for this tracker (i.e. "/user/hand/left") + XrPath toplevel_path; // OpenXR XrPath for this tracker + RID active_profile_rid; // RID of the active profile for this tracker }; - RID_Owner<Path, true> xr_path_owner; + RID_Owner<Tracker, true> tracker_owner; + RID get_tracker_rid(XrPath p_path); - struct ActionSet { - bool is_attached; - XrActionSet handle; + struct ActionSet { // Action sets define a set of actions that can be enabled together + String name; // Name for this action set (i.e. "godot_action_set") + bool is_attached; // If true our action set has been attached to the session and can no longer be modified + XrActionSet handle; // OpenXR handle for this action set }; RID_Owner<ActionSet, true> action_set_owner; - struct PathWithSpace { - XrPath toplevel_path; - XrSpace space; - bool was_location_valid; + struct ActionTracker { // Links and action to a tracker + RID tracker_rid; // RID of the tracker + XrSpace space; // Optional space for pose actions + bool was_location_valid; // If true the last position we obtained was valid }; - struct Action { - XrActionType action_type; - Vector<PathWithSpace> toplevel_paths; - XrAction handle; + struct Action { // Actions define the inputs and outputs in OpenXR + RID action_set_rid; // RID of the action set this action belongs to + String name; // Name for this action (i.e. "aim_pose") + XrActionType action_type; // Type of action (bool, float, etc.) + Vector<ActionTracker> trackers; // The trackers this action can be used with + XrAction handle; // OpenXR handle for this action }; RID_Owner<Action, true> action_owner; + RID get_action_rid(XrAction p_action); + + struct InteractionProfile { // Interaction profiles define suggested bindings between the physical inputs on controller types and our actions + String name; // Name of the interaction profile (i.e. "/interaction_profiles/valve/index_controller") + XrPath path; // OpenXR path for this profile + Vector<XrActionSuggestedBinding> bindings; // OpenXR action bindings + }; + RID_Owner<InteractionProfile, true> interaction_profile_owner; + RID get_interaction_profile_rid(XrPath p_path); + XrPath get_interaction_profile_path(RID p_interaction_profile); // state changes bool poll_events(); @@ -209,6 +229,7 @@ public: String get_error_string(XrResult result); String get_swapchain_format_name(int64_t p_swapchain_format) const; + void set_xr_interface(OpenXRInterface *p_xr_interface); void register_extension_wrapper(OpenXRExtensionWrapper *p_extension_wrapper); bool is_initialized(); @@ -233,26 +254,34 @@ public: // action map String get_default_action_map_resource_name(); - RID path_create(const String p_name); - void path_free(RID p_path); + + RID tracker_create(const String p_name); + String tracker_get_name(RID p_tracker); + void tracker_check_profile(RID p_tracker, XrSession p_session = XR_NULL_HANDLE); + void tracker_free(RID p_tracker); + RID action_set_create(const String p_name, const String p_localized_name, const int p_priority); + String action_set_get_name(RID p_action_set); bool action_set_attach(RID p_action_set); void action_set_free(RID p_action_set); - RID action_create(RID p_action_set, const String p_name, const String p_localized_name, OpenXRAction::ActionType p_action_type, const Vector<RID> &p_toplevel_paths); + + RID action_create(RID p_action_set, const String p_name, const String p_localized_name, OpenXRAction::ActionType p_action_type, const Vector<RID> &p_trackers); + String action_get_name(RID p_action); void action_free(RID p_action); - struct Binding { - RID action; - String path; - }; - bool suggest_bindings(const String p_interaction_profile, const Vector<Binding> p_bindings); + RID interaction_profile_create(const String p_name); + String interaction_profile_get_name(RID p_interaction_profile); + void interaction_profile_clear_bindings(RID p_interaction_profile); + bool interaction_profile_add_binding(RID p_interaction_profile, RID p_action, const String p_path); + bool interaction_profile_suggest_bindings(RID p_interaction_profile); + void interaction_profile_free(RID p_interaction_profile); bool sync_action_sets(const Vector<RID> p_active_sets); - bool get_action_bool(RID p_action, RID p_path); - float get_action_float(RID p_action, RID p_path); - Vector2 get_action_vector2(RID p_action, RID p_path); - XRPose::TrackingConfidence get_action_pose(RID p_action, RID p_path, Transform3D &r_transform, Vector3 &r_linear_velocity, Vector3 &r_angular_velocity); - bool trigger_haptic_pulse(RID p_action, RID p_path, float p_frequency, float p_amplitude, XrDuration p_duration_ns); + bool get_action_bool(RID p_action, RID p_tracker); + float get_action_float(RID p_action, RID p_tracker); + Vector2 get_action_vector2(RID p_action, RID p_tracker); + XRPose::TrackingConfidence get_action_pose(RID p_action, RID p_tracker, Transform3D &r_transform, Vector3 &r_linear_velocity, Vector3 &r_angular_velocity); + bool trigger_haptic_pulse(RID p_action, RID p_tracker, float p_frequency, float p_amplitude, XrDuration p_duration_ns); OpenXRAPI(); ~OpenXRAPI(); diff --git a/modules/openxr/openxr_interface.cpp b/modules/openxr/openxr_interface.cpp index 394f634687..39f9153f0d 100644 --- a/modules/openxr/openxr_interface.cpp +++ b/modules/openxr/openxr_interface.cpp @@ -35,7 +35,12 @@ #include "servers/rendering/rendering_server_globals.h" void OpenXRInterface::_bind_methods() { - // todo + // lifecycle signals + ADD_SIGNAL(MethodInfo("session_begun")); + ADD_SIGNAL(MethodInfo("session_stopping")); + ADD_SIGNAL(MethodInfo("session_focussed")); + ADD_SIGNAL(MethodInfo("session_visible")); + ADD_SIGNAL(MethodInfo("pose_recentered")); } StringName OpenXRInterface::get_name() const { @@ -46,6 +51,18 @@ uint32_t OpenXRInterface::get_capabilities() const { return XRInterface::XR_VR + XRInterface::XR_STEREO; }; +PackedStringArray OpenXRInterface::get_suggested_tracker_names() const { + // These are hardcoded in OpenXR, note that they will only be available if added to our action map + + PackedStringArray arr = { + "left_hand", // /user/hand/left is mapped to our defaults + "right_hand", // /user/hand/right is mapped to our defaults + "/user/treadmill" + }; + + return arr; +} + XRInterface::TrackingStatus OpenXRInterface::get_tracking_status() const { return tracking_state; } @@ -64,8 +81,9 @@ void OpenXRInterface::_load_action_map() { // This allow us to process the relevant actions each frame. // just in case clean up - free_action_sets(); free_trackers(); + free_interaction_profiles(); + free_action_sets(); Ref<OpenXRActionMap> action_map; if (Engine::get_singleton()->is_editor_hint()) { @@ -95,7 +113,7 @@ void OpenXRInterface::_load_action_map() { // process our action map if (action_map.is_valid()) { - Map<Ref<OpenXRAction>, RID> action_rids; + Map<Ref<OpenXRAction>, Action *> xr_actions; Array action_sets = action_map->get_action_sets(); for (int i = 0; i < action_sets.size(); i++) { @@ -112,18 +130,16 @@ void OpenXRInterface::_load_action_map() { Ref<OpenXRAction> xr_action = actions[j]; PackedStringArray toplevel_paths = xr_action->get_toplevel_paths(); - Vector<RID> toplevel_rids; Vector<Tracker *> trackers; for (int k = 0; k < toplevel_paths.size(); k++) { - Tracker *tracker = get_tracker(toplevel_paths[k]); + Tracker *tracker = find_tracker(toplevel_paths[k], true); if (tracker) { - toplevel_rids.push_back(tracker->path_rid); trackers.push_back(tracker); } } - Action *action = create_action(action_set, xr_action->get_name(), xr_action->get_localized_name(), xr_action->get_action_type(), toplevel_rids); + Action *action = create_action(action_set, xr_action->get_name(), xr_action->get_localized_name(), xr_action->get_action_type(), trackers); if (action) { // we link our actions back to our trackers so we know which actions to check when we're processing our trackers for (int t = 0; t < trackers.size(); t++) { @@ -131,7 +147,7 @@ void OpenXRInterface::_load_action_map() { } // add this to our map for creating our interaction profiles - action_rids[xr_action] = action->action_rid; + xr_actions[xr_action] = action; } } } @@ -139,30 +155,38 @@ void OpenXRInterface::_load_action_map() { // now do our suggestions Array interaction_profiles = action_map->get_interaction_profiles(); for (int i = 0; i < interaction_profiles.size(); i++) { - Vector<OpenXRAPI::Binding> bindings; Ref<OpenXRInteractionProfile> xr_interaction_profile = interaction_profiles[i]; + // Note, we can only have one entry per interaction profile so if it already exists we clear it out + RID ip = openxr_api->interaction_profile_create(xr_interaction_profile->get_interaction_profile_path()); + openxr_api->interaction_profile_clear_bindings(ip); + Array xr_bindings = xr_interaction_profile->get_bindings(); for (int j = 0; j < xr_bindings.size(); j++) { Ref<OpenXRIPBinding> xr_binding = xr_bindings[j]; Ref<OpenXRAction> xr_action = xr_binding->get_action(); - OpenXRAPI::Binding binding; - if (action_rids.has(xr_action)) { - binding.action = action_rids[xr_action]; + Action *action = nullptr; + if (xr_actions.has(xr_action)) { + action = xr_actions[xr_action]; } else { print_line("Action ", xr_action->get_name(), " isn't part of an action set!"); continue; } - PackedStringArray xr_paths = xr_binding->get_paths(); - for (int k = 0; k < xr_paths.size(); k++) { - binding.path = xr_paths[k]; - bindings.push_back(binding); + PackedStringArray paths = xr_binding->get_paths(); + for (int k = 0; k < paths.size(); k++) { + openxr_api->interaction_profile_add_binding(ip, action->action_rid, paths[k]); } } - openxr_api->suggest_bindings(xr_interaction_profile->get_interaction_profile_path(), bindings); + // Now submit our suggestions + openxr_api->interaction_profile_suggest_bindings(ip); + + // And record it in our array so we can clean it up later on + if (interaction_profiles.has(ip)) { + interaction_profiles.push_back(ip); + } } } } @@ -193,15 +217,16 @@ void OpenXRInterface::free_action_sets() { for (int i = 0; i < action_sets.size(); i++) { ActionSet *action_set = action_sets[i]; - openxr_api->path_free(action_set->action_set_rid); free_actions(action_set); + openxr_api->action_set_free(action_set->action_set_rid); + memfree(action_set); } action_sets.clear(); } -OpenXRInterface::Action *OpenXRInterface::create_action(ActionSet *p_action_set, const String &p_action_name, const String &p_localized_name, OpenXRAction::ActionType p_action_type, const Vector<RID> p_toplevel_paths) { +OpenXRInterface::Action *OpenXRInterface::create_action(ActionSet *p_action_set, const String &p_action_name, const String &p_localized_name, OpenXRAction::ActionType p_action_type, const Vector<Tracker *> p_trackers) { ERR_FAIL_NULL_V(openxr_api, nullptr); for (int i = 0; i < p_action_set->actions.size(); i++) { @@ -211,10 +236,31 @@ OpenXRInterface::Action *OpenXRInterface::create_action(ActionSet *p_action_set, } } + Vector<RID> tracker_rids; + for (int i = 0; i < p_trackers.size(); i++) { + tracker_rids.push_back(p_trackers[i]->tracker_rid); + } + Action *action = memnew(Action); - action->action_name = p_action_name; + if (p_action_type == OpenXRAction::OPENXR_ACTION_POSE) { + // We can't have dual action names in OpenXR hence we added _pose, + // but default, aim and grip and default pose action names in Godot so rename them on the tracker. + // NOTE need to decide on whether we should keep the naming convention or rename it on Godots side + if (p_action_name == "default_pose") { + action->action_name = "default"; + } else if (p_action_name == "aim_pose") { + action->action_name = "aim"; + } else if (p_action_name == "grip_pose") { + action->action_name = "grip"; + } else { + action->action_name = p_action_name; + } + } else { + action->action_name = p_action_name; + } + action->action_type = p_action_type; - action->action_rid = openxr_api->action_create(p_action_set->action_set_rid, p_action_name, p_localized_name, p_action_type, p_toplevel_paths); + action->action_rid = openxr_api->action_create(p_action_set->action_set_rid, p_action_name, p_localized_name, p_action_type, tracker_rids); p_action_set->actions.push_back(action); return action; @@ -248,7 +294,7 @@ void OpenXRInterface::free_actions(ActionSet *p_action_set) { p_action_set->actions.clear(); } -OpenXRInterface::Tracker *OpenXRInterface::get_tracker(const String &p_path_name) { +OpenXRInterface::Tracker *OpenXRInterface::find_tracker(const String &p_tracker_name, bool p_create) { XRServer *xr_server = XRServer::get_singleton(); ERR_FAIL_NULL_V(xr_server, nullptr); ERR_FAIL_NULL_V(openxr_api, nullptr); @@ -256,52 +302,72 @@ OpenXRInterface::Tracker *OpenXRInterface::get_tracker(const String &p_path_name Tracker *tracker = nullptr; for (int i = 0; i < trackers.size(); i++) { tracker = trackers[i]; - if (tracker->path_name == p_path_name) { + if (tracker->tracker_name == p_tracker_name) { return tracker; } } + if (!p_create) { + return nullptr; + } + + // Create our RID + RID tracker_rid = openxr_api->tracker_create(p_tracker_name); + ERR_FAIL_COND_V(tracker_rid.is_null(), nullptr); + // create our positional tracker Ref<XRPositionalTracker> positional_tracker; positional_tracker.instantiate(); // We have standardised some names to make things nicer to the user so lets recognise the toplevel paths related to these. - if (p_path_name == "/user/hand/left") { + if (p_tracker_name == "/user/hand/left") { positional_tracker->set_tracker_type(XRServer::TRACKER_CONTROLLER); positional_tracker->set_tracker_name("left_hand"); positional_tracker->set_tracker_desc("Left hand controller"); positional_tracker->set_tracker_hand(XRPositionalTracker::TRACKER_HAND_LEFT); - } else if (p_path_name == "/user/hand/right") { + } else if (p_tracker_name == "/user/hand/right") { positional_tracker->set_tracker_type(XRServer::TRACKER_CONTROLLER); positional_tracker->set_tracker_name("right_hand"); positional_tracker->set_tracker_desc("Right hand controller"); positional_tracker->set_tracker_hand(XRPositionalTracker::TRACKER_HAND_RIGHT); } else { positional_tracker->set_tracker_type(XRServer::TRACKER_CONTROLLER); - positional_tracker->set_tracker_name(p_path_name); - positional_tracker->set_tracker_desc(p_path_name); + positional_tracker->set_tracker_name(p_tracker_name); + positional_tracker->set_tracker_desc(p_tracker_name); } + positional_tracker->set_tracker_profile(INTERACTION_PROFILE_NONE); xr_server->add_tracker(positional_tracker); // create a new entry tracker = memnew(Tracker); - tracker->path_name = p_path_name; - tracker->path_rid = openxr_api->path_create(p_path_name); + tracker->tracker_name = p_tracker_name; + tracker->tracker_rid = tracker_rid; tracker->positional_tracker = positional_tracker; + tracker->interaction_profile = RID(); trackers.push_back(tracker); return tracker; } -OpenXRInterface::Tracker *OpenXRInterface::find_tracker(const String &p_positional_tracker_name) { - for (int i = 0; i < trackers.size(); i++) { - Tracker *tracker = trackers[i]; - if (tracker->positional_tracker.is_valid() && tracker->positional_tracker->get_tracker_name() == p_positional_tracker_name) { - return tracker; +void OpenXRInterface::tracker_profile_changed(RID p_tracker, RID p_interaction_profile) { + Tracker *tracker = nullptr; + for (int i = 0; i < trackers.size() && tracker == nullptr; i++) { + if (trackers[i]->tracker_rid == p_tracker) { + tracker = trackers[i]; } } + ERR_FAIL_NULL(tracker); - return nullptr; + tracker->interaction_profile = p_interaction_profile; + + if (p_interaction_profile.is_null()) { + print_verbose("OpenXR: Interaction profile for " + tracker->tracker_name + " changed to " + INTERACTION_PROFILE_NONE); + tracker->positional_tracker->set_tracker_profile(INTERACTION_PROFILE_NONE); + } else { + String name = openxr_api->interaction_profile_get_name(p_interaction_profile); + print_verbose("OpenXR: Interaction profile for " + tracker->tracker_name + " changed to " + name); + tracker->positional_tracker->set_tracker_profile(name); + } } void OpenXRInterface::link_action_to_tracker(Tracker *p_tracker, Action *p_action) { @@ -314,40 +380,43 @@ void OpenXRInterface::handle_tracker(Tracker *p_tracker) { ERR_FAIL_NULL(openxr_api); ERR_FAIL_COND(p_tracker->positional_tracker.is_null()); - // handle all the actions + // Note, which actions are actually bound to inputs are handled by our interaction profiles however interaction + // profiles are suggested bindings for controller types we know about. OpenXR runtimes can stray away from these + // and rebind them or even offer bindings to controllers that are not known to us. + + // We don't really have a consistant way to detect whether a controller is active however as long as it is + // unbound it seems to be unavailable, so far unknown controller seem to mimic one of the profiles we've + // supplied. + if (p_tracker->interaction_profile.is_null()) { + return; + } + + // We check all actions that are related to our tracker. for (int i = 0; i < p_tracker->actions.size(); i++) { Action *action = p_tracker->actions[i]; switch (action->action_type) { case OpenXRAction::OPENXR_ACTION_BOOL: { - bool pressed = openxr_api->get_action_bool(action->action_rid, p_tracker->path_rid); + bool pressed = openxr_api->get_action_bool(action->action_rid, p_tracker->tracker_rid); p_tracker->positional_tracker->set_input(action->action_name, Variant(pressed)); } break; case OpenXRAction::OPENXR_ACTION_FLOAT: { - real_t value = openxr_api->get_action_float(action->action_rid, p_tracker->path_rid); + real_t value = openxr_api->get_action_float(action->action_rid, p_tracker->tracker_rid); p_tracker->positional_tracker->set_input(action->action_name, Variant(value)); } break; case OpenXRAction::OPENXR_ACTION_VECTOR2: { - Vector2 value = openxr_api->get_action_vector2(action->action_rid, p_tracker->path_rid); + Vector2 value = openxr_api->get_action_vector2(action->action_rid, p_tracker->tracker_rid); p_tracker->positional_tracker->set_input(action->action_name, Variant(value)); } break; case OpenXRAction::OPENXR_ACTION_POSE: { Transform3D transform; Vector3 linear, angular; - XRPose::TrackingConfidence confidence = openxr_api->get_action_pose(action->action_rid, p_tracker->path_rid, transform, linear, angular); + + XRPose::TrackingConfidence confidence = openxr_api->get_action_pose(action->action_rid, p_tracker->tracker_rid, transform, linear, angular); + if (confidence != XRPose::XR_TRACKING_CONFIDENCE_NONE) { - String name; - // We can't have dual action names in OpenXR hence we added _pose, but default, aim and grip and default pose action names in Godot so rename them on the tracker. - // NOTE need to decide on whether we should keep the naming convention or rename it on Godots side - if (action->action_name == "default_pose") { - name = "default"; - } else if (action->action_name == "aim_pose") { - name = "aim"; - } else if (action->action_name == "grip_pose") { - name = "grip"; - } else { - name = action->action_name; - } - p_tracker->positional_tracker->set_pose(name, transform, linear, angular, confidence); + p_tracker->positional_tracker->set_pose(action->action_name, transform, linear, angular, confidence); + } else { + p_tracker->positional_tracker->invalidate_pose(action->action_name); } } break; default: { @@ -368,7 +437,7 @@ void OpenXRInterface::trigger_haptic_pulse(const String &p_action_name, const St XrDuration duration = XrDuration(p_duration_sec * 1000000000.0); // seconds -> nanoseconds - openxr_api->trigger_haptic_pulse(action->action_rid, tracker->path_rid, p_frequency, p_amplitude, duration); + openxr_api->trigger_haptic_pulse(action->action_rid, tracker->tracker_rid, p_frequency, p_amplitude, duration); } void OpenXRInterface::free_trackers() { @@ -379,7 +448,7 @@ void OpenXRInterface::free_trackers() { for (int i = 0; i < trackers.size(); i++) { Tracker *tracker = trackers[i]; - openxr_api->path_free(tracker->path_rid); + openxr_api->tracker_free(tracker->tracker_rid); xr_server->remove_tracker(tracker->positional_tracker); tracker->positional_tracker.unref(); @@ -388,6 +457,15 @@ void OpenXRInterface::free_trackers() { trackers.clear(); } +void OpenXRInterface::free_interaction_profiles() { + ERR_FAIL_NULL(openxr_api); + + for (int i = 0; i < interaction_profiles.size(); i++) { + openxr_api->interaction_profile_free(interaction_profiles[i]); + } + interaction_profiles.clear(); +} + bool OpenXRInterface::initialise_on_startup() const { if (openxr_api == nullptr) { return false; @@ -447,14 +525,14 @@ void OpenXRInterface::uninitialize() { // end the session if we need to? // cleanup stuff - free_action_sets(); free_trackers(); + free_interaction_profiles(); + free_action_sets(); XRServer *xr_server = XRServer::get_singleton(); if (xr_server) { if (head.is_valid()) { xr_server->remove_tracker(head); - head.unref(); } } @@ -649,8 +727,31 @@ void OpenXRInterface::end_frame() { } } +void OpenXRInterface::on_state_ready() { + emit_signal(SNAME("session_begun")); +} + +void OpenXRInterface::on_state_visible() { + emit_signal(SNAME("session_visible")); +} + +void OpenXRInterface::on_state_focused() { + emit_signal(SNAME("session_focussed")); +} + +void OpenXRInterface::on_state_stopping() { + emit_signal(SNAME("session_stopping")); +} + +void OpenXRInterface::on_pose_recentered() { + emit_signal(SNAME("pose_recentered")); +} + OpenXRInterface::OpenXRInterface() { openxr_api = OpenXRAPI::get_singleton(); + if (openxr_api) { + openxr_api->set_xr_interface(this); + } // while we don't have head tracking, don't put the headset on the floor... _set_default_pos(head_transform, 1.0, 0); @@ -659,5 +760,12 @@ OpenXRInterface::OpenXRInterface() { } OpenXRInterface::~OpenXRInterface() { - openxr_api = nullptr; + if (is_initialized()) { + uninitialize(); + } + + if (openxr_api) { + openxr_api->set_xr_interface(nullptr); + openxr_api = nullptr; + } } diff --git a/modules/openxr/openxr_interface.h b/modules/openxr/openxr_interface.h index ede7d481d2..421838e445 100644 --- a/modules/openxr/openxr_interface.h +++ b/modules/openxr/openxr_interface.h @@ -37,6 +37,9 @@ #include "action_map/openxr_action_map.h" #include "openxr_api.h" +// declare some default strings +#define INTERACTION_PROFILE_NONE "/interaction_profiles/none" + class OpenXRInterface : public XRInterface { GDCLASS(OpenXRInterface, XRInterface); @@ -54,40 +57,43 @@ private: void _load_action_map(); - struct Action { - String action_name; - OpenXRAction::ActionType action_type; - RID action_rid; + struct Action { // An action we've registered with OpenXR + String action_name; // Name of our action as presented to Godot (can be altered from the action map) + OpenXRAction::ActionType action_type; // The action type of this action + RID action_rid; // RID of the action registered with our OpenXR API }; - struct ActionSet { - String action_set_name; - bool is_active; - RID action_set_rid; - Vector<Action *> actions; + struct ActionSet { // An action set we've registered with OpenXR + String action_set_name; // Name of our action set + bool is_active; // If true this action set is active and we will sync it + Vector<Action *> actions; // List of actions in this action set + RID action_set_rid; // RID of the action registered with our OpenXR API }; - struct Tracker { - String path_name; - RID path_rid; - Ref<XRPositionalTracker> positional_tracker; - Vector<Action *> actions; + struct Tracker { // A tracker we've registered with OpenXR + String tracker_name; // Name of our tracker (can be altered from the action map) + Vector<Action *> actions; // Actions related to this tracker + Ref<XRPositionalTracker> positional_tracker; // Our positional tracker object that holds our tracker state + RID tracker_rid; // RID of the tracker registered with our OpenXR API + RID interaction_profile; // RID of the interaction profile bound to this tracker (can be null) }; Vector<ActionSet *> action_sets; + Vector<RID> interaction_profiles; Vector<Tracker *> trackers; ActionSet *create_action_set(const String &p_action_set_name, const String &p_localized_name, const int p_priority); void free_action_sets(); - Action *create_action(ActionSet *p_action_set, const String &p_action_name, const String &p_localized_name, OpenXRAction::ActionType p_action_type, const Vector<RID> p_toplevel_paths); + Action *create_action(ActionSet *p_action_set, const String &p_action_name, const String &p_localized_name, OpenXRAction::ActionType p_action_type, const Vector<Tracker *> p_trackers); Action *find_action(const String &p_action_name); void free_actions(ActionSet *p_action_set); - Tracker *get_tracker(const String &p_path_name); - Tracker *find_tracker(const String &p_positional_tracker_name); + Tracker *find_tracker(const String &p_tracker_name, bool p_create = false); void link_action_to_tracker(Tracker *p_tracker, Action *p_action); void handle_tracker(Tracker *p_tracker); void free_trackers(); + void free_interaction_profiles(); + void _set_default_pos(Transform3D &p_transform, double p_world_scale, uint64_t p_eye); protected: @@ -97,6 +103,7 @@ public: virtual StringName get_name() const override; virtual uint32_t get_capabilities() const override; + virtual PackedStringArray get_suggested_tracker_names() const override; virtual TrackingStatus get_tracking_status() const override; bool initialise_on_startup() const; @@ -122,6 +129,13 @@ public: virtual Vector<BlitToScreen> post_draw_viewport(RID p_render_target, const Rect2 &p_screen_rect) override; virtual void end_frame() override; + void on_state_ready(); + void on_state_visible(); + void on_state_focused(); + void on_state_stopping(); + void on_pose_recentered(); + void tracker_profile_changed(RID p_tracker, RID p_interaction_profile); + OpenXRInterface(); ~OpenXRInterface(); }; diff --git a/modules/openxr/openxr_util.cpp b/modules/openxr/openxr_util.cpp index e515336daa..230b10c5f1 100644 --- a/modules/openxr/openxr_util.cpp +++ b/modules/openxr/openxr_util.cpp @@ -278,6 +278,20 @@ String OpenXRUtil::get_session_state_name(XrSessionState p_session_state) { } } +String OpenXRUtil::get_action_type_name(XrActionType p_action_type) { + switch (p_action_type) { + ENUM_TO_STRING_CASE(XR_ACTION_TYPE_BOOLEAN_INPUT) + ENUM_TO_STRING_CASE(XR_ACTION_TYPE_FLOAT_INPUT) + ENUM_TO_STRING_CASE(XR_ACTION_TYPE_VECTOR2F_INPUT) + ENUM_TO_STRING_CASE(XR_ACTION_TYPE_POSE_INPUT) + ENUM_TO_STRING_CASE(XR_ACTION_TYPE_VIBRATION_OUTPUT) + ENUM_TO_STRING_CASE(XR_ACTION_TYPE_MAX_ENUM) + default: { + return String("Action type ") + String::num_int64(int64_t(p_action_type)); + } break; + } +} + String OpenXRUtil::make_xr_version_string(XrVersion p_version) { String version; diff --git a/modules/openxr/openxr_util.h b/modules/openxr/openxr_util.h index 1261268376..4371b74d2f 100644 --- a/modules/openxr/openxr_util.h +++ b/modules/openxr/openxr_util.h @@ -40,6 +40,7 @@ public: static String get_reference_space_name(XrReferenceSpaceType p_reference_space); static String get_structure_type_name(XrStructureType p_structure_type); static String get_session_state_name(XrSessionState p_session_state); + static String get_action_type_name(XrActionType p_action_type); static String make_xr_version_string(XrVersion p_version); }; diff --git a/modules/openxr/register_types.cpp b/modules/openxr/register_types.cpp index 86ff368619..7a74c8c089 100644 --- a/modules/openxr/register_types.cpp +++ b/modules/openxr/register_types.cpp @@ -75,9 +75,18 @@ void register_openxr_types() { void unregister_openxr_types() { if (openxr_interface.is_valid()) { + // uninitialise just in case + if (openxr_interface->is_initialized()) { + openxr_interface->uninitialize(); + } + // unregister our interface from the XR server - if (XRServer::get_singleton()) { - XRServer::get_singleton()->remove_interface(openxr_interface); + XRServer *xr_server = XRServer::get_singleton(); + if (xr_server) { + if (xr_server->get_primary_interface() == openxr_interface) { + xr_server->set_primary_interface(Ref<XRInterface>()); + } + xr_server->remove_interface(openxr_interface); } // and release diff --git a/modules/svg/image_loader_svg.cpp b/modules/svg/image_loader_svg.cpp index 96b83bf25a..79ef2de929 100644 --- a/modules/svg/image_loader_svg.cpp +++ b/modules/svg/image_loader_svg.cpp @@ -78,7 +78,7 @@ void ImageLoaderSVG::create_image_from_string(Ref<Image> p_image, String p_strin return; } float fw, fh; - picture->viewbox(nullptr, nullptr, &fw, &fh); + picture->size(&fw, &fh); uint32_t width = MIN(fw * p_scale, 16 * 1024); uint32_t height = MIN(fh * p_scale, 16 * 1024); diff --git a/modules/text_server_adv/text_server_adv.cpp b/modules/text_server_adv/text_server_adv.cpp index 1b4512dc60..7fd9cd42ed 100644 --- a/modules/text_server_adv/text_server_adv.cpp +++ b/modules/text_server_adv/text_server_adv.cpp @@ -704,7 +704,7 @@ String TextServerAdvanced::tag_to_name(int32_t p_tag) const { /* Font Glyph Rendering */ /*************************************************************************/ -_FORCE_INLINE_ TextServerAdvanced::FontTexturePosition TextServerAdvanced::find_texture_pos_for_glyph(FontDataForSizeAdvanced *p_data, int p_color_size, Image::Format p_image_format, int p_width, int p_height) const { +_FORCE_INLINE_ TextServerAdvanced::FontTexturePosition TextServerAdvanced::find_texture_pos_for_glyph(FontDataForSizeAdvanced *p_data, int p_color_size, Image::Format p_image_format, int p_width, int p_height, bool p_msdf) const { FontTexturePosition ret; ret.index = -1; @@ -769,8 +769,11 @@ _FORCE_INLINE_ TextServerAdvanced::FontTexturePosition TextServerAdvanced::find_ } texsize = next_power_of_2(texsize); - - texsize = MIN(texsize, 4096); + if (p_msdf) { + texsize = MIN(texsize, 2048); + } else { + texsize = MIN(texsize, 1024); + } FontTexture tex; tex.texture_w = texsize; @@ -935,10 +938,10 @@ _FORCE_INLINE_ TextServerAdvanced::FontGlyph TextServerAdvanced::rasterize_msdf( int mw = w + p_rect_margin * 2; int mh = h + p_rect_margin * 2; - ERR_FAIL_COND_V(mw > 4096, FontGlyph()); - ERR_FAIL_COND_V(mh > 4096, FontGlyph()); + ERR_FAIL_COND_V(mw > 1024, FontGlyph()); + ERR_FAIL_COND_V(mh > 1024, FontGlyph()); - FontTexturePosition tex_pos = find_texture_pos_for_glyph(p_data, 4, Image::FORMAT_RGBA8, mw, mh); + FontTexturePosition tex_pos = find_texture_pos_for_glyph(p_data, 4, Image::FORMAT_RGBA8, mw, mh, true); ERR_FAIL_COND_V(tex_pos.index < 0, FontGlyph()); FontTexture &tex = p_data->textures.write[tex_pos.index]; @@ -1013,13 +1016,13 @@ _FORCE_INLINE_ TextServerAdvanced::FontGlyph TextServerAdvanced::rasterize_bitma int mw = w + p_rect_margin * 2; int mh = h + p_rect_margin * 2; - ERR_FAIL_COND_V(mw > 4096, FontGlyph()); - ERR_FAIL_COND_V(mh > 4096, FontGlyph()); + ERR_FAIL_COND_V(mw > 1024, FontGlyph()); + ERR_FAIL_COND_V(mh > 1024, FontGlyph()); int color_size = bitmap.pixel_mode == FT_PIXEL_MODE_BGRA ? 4 : 2; Image::Format require_format = color_size == 4 ? Image::FORMAT_RGBA8 : Image::FORMAT_LA8; - FontTexturePosition tex_pos = find_texture_pos_for_glyph(p_data, color_size, require_format, mw, mh); + FontTexturePosition tex_pos = find_texture_pos_for_glyph(p_data, color_size, require_format, mw, mh, false); ERR_FAIL_COND_V(tex_pos.index < 0, FontGlyph()); // Fit character in char texture. @@ -1155,6 +1158,16 @@ _FORCE_INLINE_ bool TextServerAdvanced::_ensure_glyph(FontDataAdvanced *p_font_d } } + if (p_font_data->embolden != 0.f) { + FT_Pos strength = p_font_data->embolden * p_size.x * 4; // 26.6 fractional units (1 / 64). + FT_Outline_Embolden(&fd->face->glyph->outline, strength); + } + + if (p_font_data->transform != Transform2D()) { + FT_Matrix mat = { FT_Fixed(p_font_data->transform[0][0] * 65536), FT_Fixed(p_font_data->transform[0][1] * 65536), FT_Fixed(p_font_data->transform[1][0] * 65536), FT_Fixed(p_font_data->transform[1][1] * 65536) }; // 16.16 fractional units (1 / 65536). + FT_Outline_Transform(&fd->face->glyph->outline, &mat); + } + if (!outline) { if (!p_font_data->msdf) { error = FT_Render_Glyph(fd->face->glyph, p_font_data->antialiased ? FT_RENDER_MODE_NORMAL : FT_RENDER_MODE_MONO); @@ -1874,6 +1887,44 @@ TextServer::SubpixelPositioning TextServerAdvanced::font_get_subpixel_positionin return fd->subpixel_positioning; } +void TextServerAdvanced::font_set_embolden(RID p_font_rid, float p_strength) { + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); + ERR_FAIL_COND(!fd); + + MutexLock lock(fd->mutex); + if (fd->embolden != p_strength) { + _font_clear_cache(fd); + fd->embolden = p_strength; + } +} + +float TextServerAdvanced::font_get_embolden(RID p_font_rid) const { + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); + ERR_FAIL_COND_V(!fd, 0.f); + + MutexLock lock(fd->mutex); + return fd->embolden; +} + +void TextServerAdvanced::font_set_transform(RID p_font_rid, Transform2D p_transform) { + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); + ERR_FAIL_COND(!fd); + + MutexLock lock(fd->mutex); + if (fd->transform != p_transform) { + _font_clear_cache(fd); + fd->transform = p_transform; + } +} + +Transform2D TextServerAdvanced::font_get_transform(RID p_font_rid) const { + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); + ERR_FAIL_COND_V(!fd, Transform2D()); + + MutexLock lock(fd->mutex); + return fd->transform; +} + void TextServerAdvanced::font_set_variation_coordinates(RID p_font_rid, const Dictionary &p_variation_coordinates) { FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND(!fd); @@ -2275,6 +2326,20 @@ void TextServerAdvanced::font_remove_glyph(RID p_font_rid, const Vector2i &p_siz fd->cache[size]->glyph_map.erase(p_glyph); } +float TextServerAdvanced::_get_extra_advance(RID p_font_rid, int p_font_size) const { + const FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); + ERR_FAIL_COND_V(!fd, 0.0); + + MutexLock lock(fd->mutex); + Vector2i size = _get_size(fd, p_font_size); + + if (fd->embolden != 0.0) { + return fd->embolden * float(size.x) / 64.0; + } else { + return 0.0; + } +} + Vector2 TextServerAdvanced::font_get_glyph_advance(RID p_font_rid, int p_size, int32_t p_glyph) const { FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND_V(!fd, Vector2()); @@ -2289,12 +2354,17 @@ Vector2 TextServerAdvanced::font_get_glyph_advance(RID p_font_rid, int p_size, i const HashMap<int32_t, FontGlyph> &gl = fd->cache[size]->glyph_map; + Vector2 ea; + if (fd->embolden != 0.0) { + ea.x = fd->embolden * float(size.x) / 64.0; + } + if (fd->msdf) { - return gl[p_glyph].advance * (float)p_size / (float)fd->msdf_source_size; + return (gl[p_glyph].advance + ea) * (float)p_size / (float)fd->msdf_source_size; } else if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_DISABLED) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x > SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE)) { - return gl[p_glyph].advance.round(); + return (gl[p_glyph].advance + ea).round(); } else { - return gl[p_glyph].advance; + return gl[p_glyph].advance + ea; } } @@ -4420,9 +4490,9 @@ Glyph TextServerAdvanced::_shape_single_glyph(ShapedTextDataAdvanced *p_sd, char float scale = font_get_scale(p_font, p_font_size); if (p_sd->orientation == ORIENTATION_HORIZONTAL) { if (subpos) { - gl.advance = glyph_pos[0].x_advance / (64.0 / scale); + gl.advance = glyph_pos[0].x_advance / (64.0 / scale) + _get_extra_advance(p_font, p_font_size); } else { - gl.advance = Math::round(glyph_pos[0].x_advance / (64.0 / scale)); + gl.advance = Math::round(glyph_pos[0].x_advance / (64.0 / scale) + _get_extra_advance(p_font, p_font_size)); } } else { gl.advance = -Math::round(glyph_pos[0].y_advance / (64.0 / scale)); @@ -4499,6 +4569,7 @@ void TextServerAdvanced::_shape_run(ShapedTextDataAdvanced *p_sd, int32_t p_star float scale = font_get_scale(f, fs); float sp_sp = font_get_spacing(f, fs, SPACING_SPACE); float sp_gl = font_get_spacing(f, fs, SPACING_GLYPH); + float ea = _get_extra_advance(f, fs); bool subpos = (font_get_subpixel_positioning(f) == SUBPIXEL_POSITIONING_ONE_HALF) || (font_get_subpixel_positioning(f) == SUBPIXEL_POSITIONING_ONE_QUARTER) || (font_get_subpixel_positioning(f) == SUBPIXEL_POSITIONING_AUTO && fs <= SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE); ERR_FAIL_COND(hb_font == nullptr); @@ -4577,9 +4648,9 @@ void TextServerAdvanced::_shape_run(ShapedTextDataAdvanced *p_sd, int32_t p_star if (gl.index != 0) { if (p_sd->orientation == ORIENTATION_HORIZONTAL) { if (subpos) { - gl.advance = glyph_pos[i].x_advance / (64.0 / scale); + gl.advance = glyph_pos[i].x_advance / (64.0 / scale) + ea; } else { - gl.advance = Math::round(glyph_pos[i].x_advance / (64.0 / scale)); + gl.advance = Math::round(glyph_pos[i].x_advance / (64.0 / scale) + ea); } } else { gl.advance = -Math::round(glyph_pos[i].y_advance / (64.0 / scale)); diff --git a/modules/text_server_adv/text_server_adv.h b/modules/text_server_adv/text_server_adv.h index 7841a15cd3..e5958fc162 100644 --- a/modules/text_server_adv/text_server_adv.h +++ b/modules/text_server_adv/text_server_adv.h @@ -177,6 +177,8 @@ class TextServerAdvanced : public TextServer { TextServer::SubpixelPositioning subpixel_positioning = TextServer::SUBPIXEL_POSITIONING_AUTO; Dictionary variation_coordinates; float oversampling = 0.f; + float embolden = 0.f; + Transform2D transform; uint32_t style_flags = 0; String font_name; @@ -208,7 +210,7 @@ class TextServerAdvanced : public TextServer { } }; - _FORCE_INLINE_ FontTexturePosition find_texture_pos_for_glyph(FontDataForSizeAdvanced *p_data, int p_color_size, Image::Format p_image_format, int p_width, int p_height) const; + _FORCE_INLINE_ FontTexturePosition find_texture_pos_for_glyph(FontDataForSizeAdvanced *p_data, int p_color_size, Image::Format p_image_format, int p_width, int p_height, bool p_msdf) const; #ifdef MODULE_MSDFGEN_ENABLED _FORCE_INLINE_ FontGlyph rasterize_msdf(FontDataAdvanced *p_font_data, FontDataForSizeAdvanced *p_data, int p_pixel_range, int p_rect_margin, FT_Outline *outline, const Vector2 &advance) const; #endif @@ -240,6 +242,8 @@ class TextServerAdvanced : public TextServer { } } + _FORCE_INLINE_ float _get_extra_advance(RID p_font_rid, int p_font_size) const; + // Shaped text cache data. struct ShapedTextDataAdvanced : public ShapedTextData { @@ -383,6 +387,12 @@ public: virtual void font_set_subpixel_positioning(RID p_font_rid, SubpixelPositioning p_subpixel) override; virtual SubpixelPositioning font_get_subpixel_positioning(RID p_font_rid) const override; + virtual void font_set_embolden(RID p_font_rid, float p_strength) override; + virtual float font_get_embolden(RID p_font_rid) const override; + + virtual void font_set_transform(RID p_font_rid, Transform2D p_transform) override; + virtual Transform2D font_get_transform(RID p_font_rid) const override; + virtual void font_set_variation_coordinates(RID p_font_rid, const Dictionary &p_variation_coordinates) override; virtual Dictionary font_get_variation_coordinates(RID p_font_rid) const override; diff --git a/modules/text_server_fb/text_server_fb.cpp b/modules/text_server_fb/text_server_fb.cpp index e6f9bcf131..0d7a9d0db8 100644 --- a/modules/text_server_fb/text_server_fb.cpp +++ b/modules/text_server_fb/text_server_fb.cpp @@ -155,7 +155,7 @@ String TextServerFallback::tag_to_name(int32_t p_tag) const { /* Font Glyph Rendering */ /*************************************************************************/ -_FORCE_INLINE_ TextServerFallback::FontTexturePosition TextServerFallback::find_texture_pos_for_glyph(FontDataForSizeFallback *p_data, int p_color_size, Image::Format p_image_format, int p_width, int p_height) const { +_FORCE_INLINE_ TextServerFallback::FontTexturePosition TextServerFallback::find_texture_pos_for_glyph(FontDataForSizeFallback *p_data, int p_color_size, Image::Format p_image_format, int p_width, int p_height, bool p_msdf) const { FontTexturePosition ret; ret.index = -1; @@ -221,7 +221,11 @@ _FORCE_INLINE_ TextServerFallback::FontTexturePosition TextServerFallback::find_ texsize = next_power_of_2(texsize); - texsize = MIN(texsize, 4096); + if (p_msdf) { + texsize = MIN(texsize, 2048); + } else { + texsize = MIN(texsize, 1024); + } FontTexture tex; tex.texture_w = texsize; @@ -386,10 +390,10 @@ _FORCE_INLINE_ TextServerFallback::FontGlyph TextServerFallback::rasterize_msdf( int mw = w + p_rect_margin * 2; int mh = h + p_rect_margin * 2; - ERR_FAIL_COND_V(mw > 4096, FontGlyph()); - ERR_FAIL_COND_V(mh > 4096, FontGlyph()); + ERR_FAIL_COND_V(mw > 1024, FontGlyph()); + ERR_FAIL_COND_V(mh > 1024, FontGlyph()); - FontTexturePosition tex_pos = find_texture_pos_for_glyph(p_data, 4, Image::FORMAT_RGBA8, mw, mh); + FontTexturePosition tex_pos = find_texture_pos_for_glyph(p_data, 4, Image::FORMAT_RGBA8, mw, mh, true); ERR_FAIL_COND_V(tex_pos.index < 0, FontGlyph()); FontTexture &tex = p_data->textures.write[tex_pos.index]; @@ -464,13 +468,13 @@ _FORCE_INLINE_ TextServerFallback::FontGlyph TextServerFallback::rasterize_bitma int mw = w + p_rect_margin * 2; int mh = h + p_rect_margin * 2; - ERR_FAIL_COND_V(mw > 4096, FontGlyph()); - ERR_FAIL_COND_V(mh > 4096, FontGlyph()); + ERR_FAIL_COND_V(mw > 1024, FontGlyph()); + ERR_FAIL_COND_V(mh > 1024, FontGlyph()); int color_size = bitmap.pixel_mode == FT_PIXEL_MODE_BGRA ? 4 : 2; Image::Format require_format = color_size == 4 ? Image::FORMAT_RGBA8 : Image::FORMAT_LA8; - FontTexturePosition tex_pos = find_texture_pos_for_glyph(p_data, color_size, require_format, mw, mh); + FontTexturePosition tex_pos = find_texture_pos_for_glyph(p_data, color_size, require_format, mw, mh, false); ERR_FAIL_COND_V(tex_pos.index < 0, FontGlyph()); // Fit character in char texture. @@ -586,6 +590,8 @@ _FORCE_INLINE_ bool TextServerFallback::_ensure_glyph(FontDataFallback *p_font_d flags |= FT_LOAD_COLOR; } + glyph_index = FT_Get_Char_Index(fd->face, glyph_index); + FT_Fixed v, h; FT_Get_Advance(fd->face, glyph_index, flags, &h); FT_Get_Advance(fd->face, glyph_index, flags | FT_LOAD_VERTICAL_LAYOUT, &v); @@ -606,6 +612,16 @@ _FORCE_INLINE_ bool TextServerFallback::_ensure_glyph(FontDataFallback *p_font_d } } + if (p_font_data->embolden != 0.f) { + FT_Pos strength = p_font_data->embolden * p_size.x * 4; // 26.6 fractional units (1 / 64). + FT_Outline_Embolden(&fd->face->glyph->outline, strength); + } + + if (p_font_data->transform != Transform2D()) { + FT_Matrix mat = { FT_Fixed(p_font_data->transform[0][0] * 65536), FT_Fixed(p_font_data->transform[0][1] * 65536), FT_Fixed(p_font_data->transform[1][0] * 65536), FT_Fixed(p_font_data->transform[1][1] * 65536) }; // 16.16 fractional units (1 / 65536). + FT_Outline_Transform(&fd->face->glyph->outline, &mat); + } + if (!outline) { if (!p_font_data->msdf) { error = FT_Render_Glyph(fd->face->glyph, p_font_data->antialiased ? FT_RENDER_MODE_NORMAL : FT_RENDER_MODE_MONO); @@ -1044,6 +1060,44 @@ TextServer::SubpixelPositioning TextServerFallback::font_get_subpixel_positionin return fd->subpixel_positioning; } +void TextServerFallback::font_set_embolden(RID p_font_rid, float p_strength) { + FontDataFallback *fd = font_owner.get_or_null(p_font_rid); + ERR_FAIL_COND(!fd); + + MutexLock lock(fd->mutex); + if (fd->embolden != p_strength) { + _font_clear_cache(fd); + fd->embolden = p_strength; + } +} + +float TextServerFallback::font_get_embolden(RID p_font_rid) const { + FontDataFallback *fd = font_owner.get_or_null(p_font_rid); + ERR_FAIL_COND_V(!fd, 0.f); + + MutexLock lock(fd->mutex); + return fd->embolden; +} + +void TextServerFallback::font_set_transform(RID p_font_rid, Transform2D p_transform) { + FontDataFallback *fd = font_owner.get_or_null(p_font_rid); + ERR_FAIL_COND(!fd); + + MutexLock lock(fd->mutex); + if (fd->transform != p_transform) { + _font_clear_cache(fd); + fd->transform = p_transform; + } +} + +Transform2D TextServerFallback::font_get_transform(RID p_font_rid) const { + FontDataFallback *fd = font_owner.get_or_null(p_font_rid); + ERR_FAIL_COND_V(!fd, Transform2D()); + + MutexLock lock(fd->mutex); + return fd->transform; +} + void TextServerFallback::font_set_variation_coordinates(RID p_font_rid, const Dictionary &p_variation_coordinates) { FontDataFallback *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND(!fd); @@ -1459,12 +1513,17 @@ Vector2 TextServerFallback::font_get_glyph_advance(RID p_font_rid, int p_size, i const HashMap<int32_t, FontGlyph> &gl = fd->cache[size]->glyph_map; + Vector2 ea; + if (fd->embolden != 0.0) { + ea.x = fd->embolden * float(size.x) / 64.0; + } + if (fd->msdf) { - return gl[p_glyph].advance * (float)p_size / (float)fd->msdf_source_size; + return (gl[p_glyph].advance + ea) * (float)p_size / (float)fd->msdf_source_size; } else if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_DISABLED) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x > SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE)) { - return gl[p_glyph].advance.round(); + return (gl[p_glyph].advance + ea).round(); } else { - return gl[p_glyph].advance; + return gl[p_glyph].advance + ea; } } diff --git a/modules/text_server_fb/text_server_fb.h b/modules/text_server_fb/text_server_fb.h index 91afd02ae9..d4c7b5666e 100644 --- a/modules/text_server_fb/text_server_fb.h +++ b/modules/text_server_fb/text_server_fb.h @@ -142,6 +142,8 @@ class TextServerFallback : public TextServer { TextServer::SubpixelPositioning subpixel_positioning = TextServer::SUBPIXEL_POSITIONING_AUTO; Dictionary variation_coordinates; float oversampling = 0.f; + float embolden = 0.f; + Transform2D transform; uint32_t style_flags = 0; String font_name; @@ -172,7 +174,7 @@ class TextServerFallback : public TextServer { } }; - _FORCE_INLINE_ FontTexturePosition find_texture_pos_for_glyph(FontDataForSizeFallback *p_data, int p_color_size, Image::Format p_image_format, int p_width, int p_height) const; + _FORCE_INLINE_ FontTexturePosition find_texture_pos_for_glyph(FontDataForSizeFallback *p_data, int p_color_size, Image::Format p_image_format, int p_width, int p_height, bool p_msdf) const; #ifdef MODULE_MSDFGEN_ENABLED _FORCE_INLINE_ FontGlyph rasterize_msdf(FontDataFallback *p_font_data, FontDataForSizeFallback *p_data, int p_pixel_range, int p_rect_margin, FT_Outline *outline, const Vector2 &advance) const; #endif @@ -294,6 +296,12 @@ public: virtual void font_set_subpixel_positioning(RID p_font_rid, SubpixelPositioning p_subpixel) override; virtual SubpixelPositioning font_get_subpixel_positioning(RID p_font_rid) const override; + virtual void font_set_embolden(RID p_font_rid, float p_strength) override; + virtual float font_get_embolden(RID p_font_rid) const override; + + virtual void font_set_transform(RID p_font_rid, Transform2D p_transform) override; + virtual Transform2D font_get_transform(RID p_font_rid) const override; + virtual void font_set_variation_coordinates(RID p_font_rid, const Dictionary &p_variation_coordinates) override; virtual Dictionary font_get_variation_coordinates(RID p_font_rid) const override; diff --git a/modules/visual_script/editor/visual_script_editor.cpp b/modules/visual_script/editor/visual_script_editor.cpp index 813902b54e..a2e59c9cdf 100644 --- a/modules/visual_script/editor/visual_script_editor.cpp +++ b/modules/visual_script/editor/visual_script_editor.cpp @@ -1621,7 +1621,7 @@ void VisualScriptEditor::_remove_output_port(int p_id, int p_port) { conn_map.get_key_list(&keys); for (const int &E : keys) { for (const Set<int>::Element *F = conn_map[E].front(); F; F = F->next()) { - undo_redo->add_undo_method(script.ptr(), "data_connect", p_id, p_port, E, F); + undo_redo->add_undo_method(script.ptr(), "data_connect", p_id, p_port, E, F->get()); } } @@ -4725,8 +4725,6 @@ VisualScriptEditor::VisualScriptEditor() { undo_redo = EditorNode::get_singleton()->get_undo_redo(); - updating_members = false; - set_process_input(true); default_value_edit = memnew(CustomPropertyEditor); diff --git a/modules/visual_script/editor/visual_script_editor.h b/modules/visual_script/editor/visual_script_editor.h index e178f5cf72..5b355a71df 100644 --- a/modules/visual_script/editor/visual_script_editor.h +++ b/modules/visual_script/editor/visual_script_editor.h @@ -148,7 +148,7 @@ class VisualScriptEditor : public ScriptEditorBase { void _update_graph_connections(); void _update_graph(int p_only_id = -1); - bool updating_members; + bool updating_members = false; void _update_members(); String _sanitized_variant_text(const StringName &property_name); diff --git a/modules/visual_script/register_types.cpp b/modules/visual_script/register_types.cpp index e7b5f58174..d19870921d 100644 --- a/modules/visual_script/register_types.cpp +++ b/modules/visual_script/register_types.cpp @@ -53,10 +53,10 @@ void register_visual_script_types() { ScriptServer::register_language(visual_script_language); GDREGISTER_CLASS(VisualScript); - GDREGISTER_VIRTUAL_CLASS(VisualScriptNode); + GDREGISTER_ABSTRACT_CLASS(VisualScriptNode); GDREGISTER_CLASS(VisualScriptFunctionState); GDREGISTER_CLASS(VisualScriptFunction); - GDREGISTER_VIRTUAL_CLASS(VisualScriptLists); + GDREGISTER_ABSTRACT_CLASS(VisualScriptLists); GDREGISTER_CLASS(VisualScriptComposeArray); GDREGISTER_CLASS(VisualScriptOperator); GDREGISTER_CLASS(VisualScriptVariableSet); diff --git a/modules/visual_script/visual_script.cpp b/modules/visual_script/visual_script.cpp index 9549137aef..e8c44e2556 100644 --- a/modules/visual_script/visual_script.cpp +++ b/modules/visual_script/visual_script.cpp @@ -1705,7 +1705,7 @@ Variant VisualScriptInstance::_call_internal(const StringName &p_method, void *p return return_value; } -Variant VisualScriptInstance::call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) { +Variant VisualScriptInstance::callp(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) { r_error.error = Callable::CallError::CALL_OK; //ok by default Map<StringName, Function>::Element *F = functions.find(p_method); @@ -1798,13 +1798,13 @@ void VisualScriptInstance::notification(int p_notification) { Variant what = p_notification; const Variant *whatp = &what; Callable::CallError ce; - call(VisualScriptLanguage::singleton->notification, &whatp, 1, ce); // Do as call. + callp(VisualScriptLanguage::singleton->notification, &whatp, 1, ce); // Do as call. } String VisualScriptInstance::to_string(bool *r_valid) { if (has_method(CoreStringNames::get_singleton()->_to_string)) { Callable::CallError ce; - Variant ret = call(CoreStringNames::get_singleton()->_to_string, nullptr, 0, ce); + Variant ret = callp(CoreStringNames::get_singleton()->_to_string, nullptr, 0, ce); if (ce.error == Callable::CallError::CALL_OK) { if (ret.get_type() != Variant::STRING) { if (r_valid) { diff --git a/modules/visual_script/visual_script.h b/modules/visual_script/visual_script.h index e5c8ab48ee..d4dffdfc7a 100644 --- a/modules/visual_script/visual_script.h +++ b/modules/visual_script/visual_script.h @@ -410,7 +410,7 @@ public: virtual void get_method_list(List<MethodInfo> *p_list) const; virtual bool has_method(const StringName &p_method) const; - virtual Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error); + virtual Variant callp(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error); virtual void notification(int p_notification); String to_string(bool *r_valid); diff --git a/modules/visual_script/visual_script_expression.cpp b/modules/visual_script/visual_script_expression.cpp index e8942b9788..fef159bf87 100644 --- a/modules/visual_script/visual_script_expression.cpp +++ b/modules/visual_script/visual_script_expression.cpp @@ -176,7 +176,7 @@ PropertyInfo VisualScriptExpression::get_output_value_port_info(int p_idx) const } String VisualScriptExpression::get_caption() const { - return TTR("Expression"); + return RTR("Expression"); } String VisualScriptExpression::get_text() const { @@ -1500,7 +1500,7 @@ public: argp.write[i] = &arr[i]; } - base.call(call->method, (const Variant **)argp.ptr(), argp.size(), r_ret, ce); + base.callp(call->method, (const Variant **)argp.ptr(), argp.size(), r_ret, ce); if (ce.error != Callable::CallError::CALL_OK) { r_error_str = "On call to '" + String(call->method) + "':"; diff --git a/modules/visual_script/visual_script_flow_control.cpp b/modules/visual_script/visual_script_flow_control.cpp index fd1861abc4..d28744a09f 100644 --- a/modules/visual_script/visual_script_flow_control.cpp +++ b/modules/visual_script/visual_script_flow_control.cpp @@ -70,7 +70,7 @@ PropertyInfo VisualScriptReturn::get_output_value_port_info(int p_idx) const { } String VisualScriptReturn::get_caption() const { - return TTR("Return"); + return RTR("Return"); } String VisualScriptReturn::get_text() const { @@ -201,11 +201,11 @@ PropertyInfo VisualScriptCondition::get_output_value_port_info(int p_idx) const } String VisualScriptCondition::get_caption() const { - return TTR("Condition"); + return RTR("Condition"); } String VisualScriptCondition::get_text() const { - return TTR("if (cond) is:"); + return RTR("if (cond) is:"); } void VisualScriptCondition::_bind_methods() { @@ -281,11 +281,11 @@ PropertyInfo VisualScriptWhile::get_output_value_port_info(int p_idx) const { } String VisualScriptWhile::get_caption() const { - return TTR("While"); + return RTR("While"); } String VisualScriptWhile::get_text() const { - return TTR("while (cond):"); + return RTR("while (cond):"); } void VisualScriptWhile::_bind_methods() { @@ -364,11 +364,11 @@ PropertyInfo VisualScriptIterator::get_output_value_port_info(int p_idx) const { } String VisualScriptIterator::get_caption() const { - return TTR("Iterator"); + return RTR("Iterator"); } String VisualScriptIterator::get_text() const { - return TTR("for (elem) in (input):"); + return RTR("for (elem) in (input):"); } void VisualScriptIterator::_bind_methods() { @@ -478,11 +478,11 @@ PropertyInfo VisualScriptSequence::get_output_value_port_info(int p_idx) const { } String VisualScriptSequence::get_caption() const { - return TTR("Sequence"); + return RTR("Sequence"); } String VisualScriptSequence::get_text() const { - return TTR("in order:"); + return RTR("in order:"); } void VisualScriptSequence::set_steps(int p_steps) { @@ -587,11 +587,11 @@ PropertyInfo VisualScriptSwitch::get_output_value_port_info(int p_idx) const { } String VisualScriptSwitch::get_caption() const { - return TTR("Switch"); + return RTR("Switch"); } String VisualScriptSwitch::get_text() const { - return TTR("'input' is:"); + return RTR("'input' is:"); } class VisualScriptNodeInstanceSwitch : public VisualScriptNodeInstance { @@ -720,14 +720,14 @@ PropertyInfo VisualScriptTypeCast::get_output_value_port_info(int p_idx) const { } String VisualScriptTypeCast::get_caption() const { - return TTR("Type Cast"); + return RTR("Type Cast"); } String VisualScriptTypeCast::get_text() const { if (!script.is_empty()) { - return vformat(TTR("Is %s?"), script.get_file()); + return vformat(RTR("Is %s?"), script.get_file()); } else { - return vformat(TTR("Is %s?"), base_type); + return vformat(RTR("Is %s?"), base_type); } } diff --git a/modules/visual_script/visual_script_func_nodes.cpp b/modules/visual_script/visual_script_func_nodes.cpp index ef6c1ecdb9..2c9d23e457 100644 --- a/modules/visual_script/visual_script_func_nodes.cpp +++ b/modules/visual_script/visual_script_func_nodes.cpp @@ -33,6 +33,7 @@ #include "core/config/engine.h" #include "core/io/resource_loader.h" #include "core/os/os.h" +#include "core/templates/local_vector.h" #include "scene/main/node.h" #include "scene/main/scene_tree.h" #include "visual_script_nodes.h" @@ -261,13 +262,13 @@ String VisualScriptFunctionCall::get_text() const { String text; if (call_mode == CALL_MODE_BASIC_TYPE) { - text = vformat(TTR("On %s"), Variant::get_type_name(basic_type)); + text = vformat(RTR("On %s"), Variant::get_type_name(basic_type)); } else if (call_mode == CALL_MODE_INSTANCE) { - text = vformat(TTR("On %s"), base_type); + text = vformat(RTR("On %s"), base_type); } else if (call_mode == CALL_MODE_NODE_PATH) { text = "[" + String(base_path.simplified()) + "]"; } else if (call_mode == CALL_MODE_SELF) { - text = TTR("On Self"); + text = RTR("On Self"); } else if (call_mode == CALL_MODE_SINGLETON) { text = String(singleton) + ":" + String(function) + "()"; } @@ -772,9 +773,9 @@ public: if (rpc_mode) { call_rpc(object, p_inputs, input_args); } else if (returns) { - *p_outputs[0] = object->call(function, p_inputs, input_args, r_error); + *p_outputs[0] = object->callp(function, p_inputs, input_args, r_error); } else { - object->call(function, p_inputs, input_args, r_error); + object->callp(function, p_inputs, input_args, r_error); } } break; case VisualScriptFunctionCall::CALL_MODE_NODE_PATH: { @@ -795,9 +796,9 @@ public: if (rpc_mode) { call_rpc(node, p_inputs, input_args); } else if (returns) { - *p_outputs[0] = another->call(function, p_inputs, input_args, r_error); + *p_outputs[0] = another->callp(function, p_inputs, input_args, r_error); } else { - another->call(function, p_inputs, input_args, r_error); + another->callp(function, p_inputs, input_args, r_error); } } break; @@ -813,21 +814,21 @@ public: } else if (returns) { if (call_mode == VisualScriptFunctionCall::CALL_MODE_INSTANCE) { if (returns >= 2) { - v.call(function, p_inputs + 1, input_args, *p_outputs[1], r_error); + v.callp(function, p_inputs + 1, input_args, *p_outputs[1], r_error); } else if (returns == 1) { Variant ret; - v.call(function, p_inputs + 1, input_args, ret, r_error); + v.callp(function, p_inputs + 1, input_args, ret, r_error); } else { r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; r_error_str = "Invalid returns count for call_mode == CALL_MODE_INSTANCE"; return 0; } } else { - v.call(function, p_inputs + 1, input_args, *p_outputs[0], r_error); + v.callp(function, p_inputs + 1, input_args, *p_outputs[0], r_error); } } else { Variant ret; - v.call(function, p_inputs + 1, input_args, ret, r_error); + v.callp(function, p_inputs + 1, input_args, ret, r_error); } if (call_mode == VisualScriptFunctionCall::CALL_MODE_INSTANCE) { @@ -846,9 +847,9 @@ public: if (rpc_mode) { call_rpc(object, p_inputs, input_args); } else if (returns) { - *p_outputs[0] = object->call(function, p_inputs, input_args, r_error); + *p_outputs[0] = object->callp(function, p_inputs, input_args, r_error); } else { - object->call(function, p_inputs, input_args, r_error); + object->callp(function, p_inputs, input_args, r_error); } } break; } @@ -1032,18 +1033,18 @@ PropertyInfo VisualScriptPropertySet::get_output_value_port_info(int p_idx) cons } String VisualScriptPropertySet::get_caption() const { - static const char *opname[ASSIGN_OP_MAX] = { - TTRC("Set %s"), - TTRC("Add %s"), - TTRC("Subtract %s"), - TTRC("Multiply %s"), - TTRC("Divide %s"), - TTRC("Mod %s"), - TTRC("ShiftLeft %s"), - TTRC("ShiftRight %s"), - TTRC("BitAnd %s"), - TTRC("BitOr %s"), - TTRC("BitXor %s") + static const LocalVector<String> opname = { + RTR("Set %s"), + RTR("Add %s"), + RTR("Subtract %s"), + RTR("Multiply %s"), + RTR("Divide %s"), + RTR("Mod %s"), + RTR("ShiftLeft %s"), + RTR("ShiftRight %s"), + RTR("BitAnd %s"), + RTR("BitOr %s"), + RTR("BitXor %s"), }; String prop = property; @@ -1051,7 +1052,7 @@ String VisualScriptPropertySet::get_caption() const { prop += "." + String(index); } - return vformat(TTRGET(opname[assign_op]), prop); + return vformat(opname[assign_op], prop); } String VisualScriptPropertySet::get_text() const { @@ -1059,13 +1060,13 @@ String VisualScriptPropertySet::get_text() const { return ""; } if (call_mode == CALL_MODE_BASIC_TYPE) { - return vformat(TTR("On %s"), Variant::get_type_name(basic_type)); + return vformat(RTR("On %s"), Variant::get_type_name(basic_type)); } else if (call_mode == CALL_MODE_INSTANCE) { - return vformat(TTR("On %s"), base_type); + return vformat(RTR("On %s"), base_type); } else if (call_mode == CALL_MODE_NODE_PATH) { return " [" + String(base_path.simplified()) + "]"; } else { - return TTR("On Self"); + return RTR("On Self"); } } @@ -1776,18 +1777,18 @@ String VisualScriptPropertyGet::get_caption() const { prop += "." + String(index); } - return vformat(TTR("Get %s"), prop); + return vformat(RTR("Get %s"), prop); } String VisualScriptPropertyGet::get_text() const { if (call_mode == CALL_MODE_BASIC_TYPE) { - return vformat(TTR("On %s"), Variant::get_type_name(basic_type)); + return vformat(RTR("On %s"), Variant::get_type_name(basic_type)); } else if (call_mode == CALL_MODE_INSTANCE) { - return vformat(TTR("On %s"), base_type); + return vformat(RTR("On %s"), base_type); } else if (call_mode == CALL_MODE_NODE_PATH) { return " [" + String(base_path.simplified()) + "]"; } else { - return TTR("On Self"); + return RTR("On Self"); } } @@ -2303,7 +2304,7 @@ PropertyInfo VisualScriptEmitSignal::get_output_value_port_info(int p_idx) const } String VisualScriptEmitSignal::get_caption() const { - return vformat(TTR("Emit %s"), name); + return vformat(RTR("Emit %s"), name); } void VisualScriptEmitSignal::set_signal(const StringName &p_type) { @@ -2373,7 +2374,7 @@ public: virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) { Object *obj = instance->get_owner_ptr(); - obj->emit_signal(name, p_inputs, argcount); + obj->emit_signalp(name, p_inputs, argcount); return 0; } diff --git a/modules/visual_script/visual_script_nodes.cpp b/modules/visual_script/visual_script_nodes.cpp index e672267b00..b65b9f090a 100644 --- a/modules/visual_script/visual_script_nodes.cpp +++ b/modules/visual_script/visual_script_nodes.cpp @@ -204,7 +204,7 @@ PropertyInfo VisualScriptFunction::get_output_value_port_info(int p_idx) const { } String VisualScriptFunction::get_caption() const { - return TTR("Function"); + return RTR("Function"); } String VisualScriptFunction::get_text() const { @@ -767,7 +767,7 @@ PropertyInfo VisualScriptComposeArray::get_output_value_port_info(int p_idx) con } String VisualScriptComposeArray::get_caption() const { - return TTR("Compose Array"); + return RTR("Compose Array"); } String VisualScriptComposeArray::get_text() const { @@ -1186,11 +1186,11 @@ PropertyInfo VisualScriptSelect::get_output_value_port_info(int p_idx) const { } String VisualScriptSelect::get_caption() const { - return TTR("Select"); + return RTR("Select"); } String VisualScriptSelect::get_text() const { - return TTR("a if cond, else b"); + return RTR("a if cond, else b"); } void VisualScriptSelect::set_typed(Variant::Type p_op) { @@ -1284,7 +1284,7 @@ PropertyInfo VisualScriptVariableGet::get_output_value_port_info(int p_idx) cons } String VisualScriptVariableGet::get_caption() const { - return vformat(TTR("Get %s"), variable); + return vformat(RTR("Get %s"), variable); } void VisualScriptVariableGet::set_variable(StringName p_variable) { @@ -1394,7 +1394,7 @@ PropertyInfo VisualScriptVariableSet::get_output_value_port_info(int p_idx) cons } String VisualScriptVariableSet::get_caption() const { - return vformat(TTR("Set %s"), variable); + return vformat(RTR("Set %s"), variable); } void VisualScriptVariableSet::set_variable(StringName p_variable) { @@ -1501,7 +1501,7 @@ PropertyInfo VisualScriptConstant::get_output_value_port_info(int p_idx) const { } String VisualScriptConstant::get_caption() const { - return TTR("Constant"); + return RTR("Constant"); } void VisualScriptConstant::set_constant_type(Variant::Type p_type) { @@ -1628,7 +1628,7 @@ PropertyInfo VisualScriptPreload::get_output_value_port_info(int p_idx) const { } String VisualScriptPreload::get_caption() const { - return TTR("Preload"); + return RTR("Preload"); } void VisualScriptPreload::set_preload(const Ref<Resource> &p_preload) { @@ -1708,7 +1708,7 @@ PropertyInfo VisualScriptIndexGet::get_output_value_port_info(int p_idx) const { } String VisualScriptIndexGet::get_caption() const { - return TTR("Get Index"); + return RTR("Get Index"); } class VisualScriptNodeInstanceIndexGet : public VisualScriptNodeInstance { @@ -1775,7 +1775,7 @@ PropertyInfo VisualScriptIndexSet::get_output_value_port_info(int p_idx) const { } String VisualScriptIndexSet::get_caption() const { - return TTR("Set Index"); + return RTR("Set Index"); } class VisualScriptNodeInstanceIndexSet : public VisualScriptNodeInstance { @@ -1836,7 +1836,7 @@ PropertyInfo VisualScriptGlobalConstant::get_output_value_port_info(int p_idx) c } String VisualScriptGlobalConstant::get_caption() const { - return TTR("Global Constant"); + return RTR("Global Constant"); } void VisualScriptGlobalConstant::set_global_constant(int p_which) { @@ -1922,7 +1922,7 @@ PropertyInfo VisualScriptClassConstant::get_output_value_port_info(int p_idx) co } String VisualScriptClassConstant::get_caption() const { - return TTR("Class Constant"); + return RTR("Class Constant"); } void VisualScriptClassConstant::set_class_constant(const StringName &p_which) { @@ -2047,7 +2047,7 @@ PropertyInfo VisualScriptBasicTypeConstant::get_output_value_port_info(int p_idx } String VisualScriptBasicTypeConstant::get_caption() const { - return TTR("Basic Constant"); + return RTR("Basic Constant"); } String VisualScriptBasicTypeConstant::get_text() const { @@ -2212,7 +2212,7 @@ PropertyInfo VisualScriptMathConstant::get_output_value_port_info(int p_idx) con } String VisualScriptMathConstant::get_caption() const { - return TTR("Math Constant"); + return RTR("Math Constant"); } void VisualScriptMathConstant::set_math_constant(MathConstant p_which) { @@ -2304,7 +2304,7 @@ PropertyInfo VisualScriptEngineSingleton::get_output_value_port_info(int p_idx) } String VisualScriptEngineSingleton::get_caption() const { - return TTR("Get Engine Singleton"); + return RTR("Get Engine Singleton"); } void VisualScriptEngineSingleton::set_singleton(const String &p_string) { @@ -2414,7 +2414,7 @@ PropertyInfo VisualScriptSceneNode::get_output_value_port_info(int p_idx) const } String VisualScriptSceneNode::get_caption() const { - return TTR("Get Scene Node"); + return RTR("Get Scene Node"); } void VisualScriptSceneNode::set_node_path(const NodePath &p_path) { @@ -2605,7 +2605,7 @@ PropertyInfo VisualScriptSceneTree::get_output_value_port_info(int p_idx) const } String VisualScriptSceneTree::get_caption() const { - return TTR("Get Scene Tree"); + return RTR("Get Scene Tree"); } class VisualScriptNodeInstanceSceneTree : public VisualScriptNodeInstance { @@ -2692,7 +2692,7 @@ PropertyInfo VisualScriptResourcePath::get_output_value_port_info(int p_idx) con } String VisualScriptResourcePath::get_caption() const { - return TTR("Resource Path"); + return RTR("Resource Path"); } void VisualScriptResourcePath::set_resource_path(const String &p_path) { @@ -2774,7 +2774,7 @@ PropertyInfo VisualScriptSelf::get_output_value_port_info(int p_idx) const { } String VisualScriptSelf::get_caption() const { - return TTR("Get Self"); + return RTR("Get Self"); } class VisualScriptNodeInstanceSelf : public VisualScriptNodeInstance { @@ -2944,7 +2944,7 @@ String VisualScriptCustomNode::get_caption() const { if (GDVIRTUAL_CALL(_get_caption, ret)) { return ret; } - return TTR("CustomNode"); + return RTR("CustomNode"); } String VisualScriptCustomNode::get_text() const { @@ -3138,7 +3138,7 @@ PropertyInfo VisualScriptSubCall::get_output_value_port_info(int p_idx) const { } String VisualScriptSubCall::get_caption() const { - return TTR("SubCall"); + return RTR("SubCall"); } String VisualScriptSubCall::get_text() const { @@ -3174,7 +3174,7 @@ public: r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; return 0; } - *p_outputs[0] = subcall->call(VisualScriptLanguage::singleton->_subcall, p_inputs, input_args, r_error); + *p_outputs[0] = subcall->callp(VisualScriptLanguage::singleton->_subcall, p_inputs, input_args, r_error); return 0; } }; @@ -3349,7 +3349,7 @@ PropertyInfo VisualScriptConstructor::get_output_value_port_info(int p_idx) cons } String VisualScriptConstructor::get_caption() const { - return vformat(TTR("Construct %s"), Variant::get_type_name(type)); + return vformat(RTR("Construct %s"), Variant::get_type_name(type)); } String VisualScriptConstructor::get_category() const { @@ -3466,7 +3466,7 @@ PropertyInfo VisualScriptLocalVar::get_output_value_port_info(int p_idx) const { } String VisualScriptLocalVar::get_caption() const { - return TTR("Get Local Var"); + return RTR("Get Local Var"); } String VisualScriptLocalVar::get_category() const { @@ -3569,7 +3569,7 @@ PropertyInfo VisualScriptLocalVarSet::get_output_value_port_info(int p_idx) cons } String VisualScriptLocalVarSet::get_caption() const { - return TTR("Set Local Var"); + return RTR("Set Local Var"); } String VisualScriptLocalVarSet::get_text() const { @@ -3693,7 +3693,7 @@ PropertyInfo VisualScriptInputAction::get_output_value_port_info(int p_idx) cons } String VisualScriptInputAction::get_caption() const { - return vformat(TTR("Action %s"), name); + return vformat(RTR("Action %s"), name); } String VisualScriptInputAction::get_category() const { @@ -3847,7 +3847,7 @@ PropertyInfo VisualScriptDeconstruct::get_output_value_port_info(int p_idx) cons } String VisualScriptDeconstruct::get_caption() const { - return vformat(TTR("Deconstruct %s"), Variant::get_type_name(type)); + return vformat(RTR("Deconstruct %s"), Variant::get_type_name(type)); } String VisualScriptDeconstruct::get_category() const { diff --git a/modules/visual_script/visual_script_yield_nodes.cpp b/modules/visual_script/visual_script_yield_nodes.cpp index fbd5ad35ab..dcd8815394 100644 --- a/modules/visual_script/visual_script_yield_nodes.cpp +++ b/modules/visual_script/visual_script_yield_nodes.cpp @@ -68,7 +68,7 @@ PropertyInfo VisualScriptYield::get_output_value_port_info(int p_idx) const { } String VisualScriptYield::get_caption() const { - return yield_mode == YIELD_RETURN ? TTR("Yield") : TTR("Wait"); + return yield_mode == YIELD_RETURN ? RTR("Yield") : RTR("Wait"); } String VisualScriptYield::get_text() const { @@ -77,13 +77,13 @@ String VisualScriptYield::get_text() const { return ""; break; case YIELD_FRAME: - return TTR("Next Frame"); + return RTR("Next Frame"); break; case YIELD_PHYSICS_FRAME: - return TTR("Next Physics Frame"); + return RTR("Next Physics Frame"); break; case YIELD_WAIT: - return vformat(TTR("%s sec(s)"), rtos(wait_time)); + return vformat(RTR("%s sec(s)"), rtos(wait_time)); break; } @@ -335,13 +335,18 @@ PropertyInfo VisualScriptYieldSignal::get_output_value_port_info(int p_idx) cons } String VisualScriptYieldSignal::get_caption() const { - static const char *cname[3] = { - TTRC("WaitSignal"), - TTRC("WaitNodeSignal"), - TTRC("WaitInstanceSignal"), - }; - - return TTRGET(cname[call_mode]); + switch (call_mode) { + case CALL_MODE_SELF: { + return RTR("WaitSignal"); + } break; + case CALL_MODE_NODE_PATH: { + return RTR("WaitNodeSignal"); + } break; + case CALL_MODE_INSTANCE: { + return RTR("WaitInstanceSignal"); + } break; + } + return String(); } String VisualScriptYieldSignal::get_text() const { diff --git a/modules/vorbis/audio_stream_ogg_vorbis.cpp b/modules/vorbis/audio_stream_ogg_vorbis.cpp index 049d816a5a..5ff5b2339c 100644 --- a/modules/vorbis/audio_stream_ogg_vorbis.cpp +++ b/modules/vorbis/audio_stream_ogg_vorbis.cpp @@ -166,7 +166,7 @@ void AudioStreamPlaybackOGGVorbis::start(float p_from_pos) { active = true; seek(p_from_pos); loops = 0; - _begin_resample(); + begin_resample(); } void AudioStreamPlaybackOGGVorbis::stop() { diff --git a/modules/webrtc/register_types.cpp b/modules/webrtc/register_types.cpp index e6a8dcc31a..283e421e11 100644 --- a/modules/webrtc/register_types.cpp +++ b/modules/webrtc/register_types.cpp @@ -47,7 +47,7 @@ void register_webrtc_types() { ClassDB::register_custom_instance_class<WebRTCPeerConnection>(); GDREGISTER_CLASS(WebRTCPeerConnectionExtension); - GDREGISTER_VIRTUAL_CLASS(WebRTCDataChannel); + GDREGISTER_ABSTRACT_CLASS(WebRTCDataChannel); GDREGISTER_CLASS(WebRTCDataChannelExtension); GDREGISTER_CLASS(WebRTCMultiplayerPeer); diff --git a/modules/websocket/register_types.cpp b/modules/websocket/register_types.cpp index 1e9a4c0392..ff900f496f 100644 --- a/modules/websocket/register_types.cpp +++ b/modules/websocket/register_types.cpp @@ -63,7 +63,7 @@ void register_websocket_types() { WSLServer::make_default(); #endif - GDREGISTER_VIRTUAL_CLASS(WebSocketMultiplayerPeer); + GDREGISTER_ABSTRACT_CLASS(WebSocketMultiplayerPeer); ClassDB::register_custom_instance_class<WebSocketServer>(); ClassDB::register_custom_instance_class<WebSocketClient>(); ClassDB::register_custom_instance_class<WebSocketPeer>(); diff --git a/modules/webxr/register_types.cpp b/modules/webxr/register_types.cpp index 78fed3fbd6..a15dc93248 100644 --- a/modules/webxr/register_types.cpp +++ b/modules/webxr/register_types.cpp @@ -38,7 +38,7 @@ Ref<WebXRInterfaceJS> webxr; #endif void register_webxr_types() { - GDREGISTER_VIRTUAL_CLASS(WebXRInterface); + GDREGISTER_ABSTRACT_CLASS(WebXRInterface); #ifdef JAVASCRIPT_ENABLED webxr.instantiate(); |